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

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

#include <gtest/gtest.h>

#include <algorithm>

TEST(normalization, nfkc_001_000)
{
    // 0145;0145;004E 0327;0145;004E 0327;
    // (Ņ; Ņ; N◌̧; Ņ; N◌̧; ) LATIN CAPITAL LETTER N WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0145 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0145 }};
        std::array<uint32_t, 2> const c3 = {{ 0x004E, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0145 }};
        std::array<uint32_t, 2> const c5 = {{ 0x004E, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_001)
{
    // 0146;0146;006E 0327;0146;006E 0327;
    // (ņ; ņ; n◌̧; ņ; n◌̧; ) LATIN SMALL LETTER N WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0146 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0146 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006E, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0146 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006E, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_002)
{
    // 0147;0147;004E 030C;0147;004E 030C;
    // (Ň; Ň; N◌̌; Ň; N◌̌; ) LATIN CAPITAL LETTER N WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0147 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0147 }};
        std::array<uint32_t, 2> const c3 = {{ 0x004E, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0147 }};
        std::array<uint32_t, 2> const c5 = {{ 0x004E, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_003)
{
    // 0148;0148;006E 030C;0148;006E 030C;
    // (ň; ň; n◌̌; ň; n◌̌; ) LATIN SMALL LETTER N WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0148 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0148 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006E, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0148 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006E, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_004)
{
    // 0149;0149;0149;02BC 006E;02BC 006E;
    // (ŉ; ŉ; ŉ; ʼn; ʼn; ) LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0149 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0149 }};
        std::array<uint32_t, 1> const c3 = {{ 0x0149 }};
        std::array<uint32_t, 2> const c4 = {{ 0x02BC, 0x006E }};
        std::array<uint32_t, 2> const c5 = {{ 0x02BC, 0x006E }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_005)
{
    // 014C;014C;004F 0304;014C;004F 0304;
    // (Ō; Ō; O◌̄; Ō; O◌̄; ) LATIN CAPITAL LETTER O WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x014C }};
        std::array<uint32_t, 1> const c2 = {{ 0x014C }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x014C }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_006)
{
    // 014D;014D;006F 0304;014D;006F 0304;
    // (ō; ō; o◌̄; ō; o◌̄; ) LATIN SMALL LETTER O WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x014D }};
        std::array<uint32_t, 1> const c2 = {{ 0x014D }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x014D }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_007)
{
    // 014E;014E;004F 0306;014E;004F 0306;
    // (Ŏ; Ŏ; O◌̆; Ŏ; O◌̆; ) LATIN CAPITAL LETTER O WITH BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x014E }};
        std::array<uint32_t, 1> const c2 = {{ 0x014E }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x0306 }};
        std::array<uint32_t, 1> const c4 = {{ 0x014E }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x0306 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_008)
{
    // 014F;014F;006F 0306;014F;006F 0306;
    // (ŏ; ŏ; o◌̆; ŏ; o◌̆; ) LATIN SMALL LETTER O WITH BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x014F }};
        std::array<uint32_t, 1> const c2 = {{ 0x014F }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x0306 }};
        std::array<uint32_t, 1> const c4 = {{ 0x014F }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x0306 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_009)
{
    // 0150;0150;004F 030B;0150;004F 030B;
    // (Ő; Ő; O◌̋; Ő; O◌̋; ) LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0150 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0150 }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x030B }};
        std::array<uint32_t, 1> const c4 = {{ 0x0150 }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x030B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_010)
{
    // 0151;0151;006F 030B;0151;006F 030B;
    // (ő; ő; o◌̋; ő; o◌̋; ) LATIN SMALL LETTER O WITH DOUBLE ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0151 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0151 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x030B }};
        std::array<uint32_t, 1> const c4 = {{ 0x0151 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x030B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_011)
{
    // 0154;0154;0052 0301;0154;0052 0301;
    // (Ŕ; Ŕ; R◌́; Ŕ; R◌́; ) LATIN CAPITAL LETTER R WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0154 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0154 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0052, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0154 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0052, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_012)
{
    // 0155;0155;0072 0301;0155;0072 0301;
    // (ŕ; ŕ; r◌́; ŕ; r◌́; ) LATIN SMALL LETTER R WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0155 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0155 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0072, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0155 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0072, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_013)
{
    // 0156;0156;0052 0327;0156;0052 0327;
    // (Ŗ; Ŗ; R◌̧; Ŗ; R◌̧; ) LATIN CAPITAL LETTER R WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0156 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0156 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0052, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0156 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0052, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_014)
{
    // 0157;0157;0072 0327;0157;0072 0327;
    // (ŗ; ŗ; r◌̧; ŗ; r◌̧; ) LATIN SMALL LETTER R WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0157 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0157 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0072, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0157 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0072, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_015)
{
    // 0158;0158;0052 030C;0158;0052 030C;
    // (Ř; Ř; R◌̌; Ř; R◌̌; ) LATIN CAPITAL LETTER R WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0158 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0158 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0052, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0158 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0052, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_016)
{
    // 0159;0159;0072 030C;0159;0072 030C;
    // (ř; ř; r◌̌; ř; r◌̌; ) LATIN SMALL LETTER R WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0159 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0159 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0072, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0159 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0072, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_017)
{
    // 015A;015A;0053 0301;015A;0053 0301;
    // (Ś; Ś; S◌́; Ś; S◌́; ) LATIN CAPITAL LETTER S WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x015A }};
        std::array<uint32_t, 1> const c2 = {{ 0x015A }};
        std::array<uint32_t, 2> const c3 = {{ 0x0053, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x015A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0053, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_018)
{
    // 015B;015B;0073 0301;015B;0073 0301;
    // (ś; ś; s◌́; ś; s◌́; ) LATIN SMALL LETTER S WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x015B }};
        std::array<uint32_t, 1> const c2 = {{ 0x015B }};
        std::array<uint32_t, 2> const c3 = {{ 0x0073, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x015B }};
        std::array<uint32_t, 2> const c5 = {{ 0x0073, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_019)
{
    // 015C;015C;0053 0302;015C;0053 0302;
    // (Ŝ; Ŝ; S◌̂; Ŝ; S◌̂; ) LATIN CAPITAL LETTER S WITH CIRCUMFLEX
    {
        std::array<uint32_t, 1> const c1 = {{ 0x015C }};
        std::array<uint32_t, 1> const c2 = {{ 0x015C }};
        std::array<uint32_t, 2> const c3 = {{ 0x0053, 0x0302 }};
        std::array<uint32_t, 1> const c4 = {{ 0x015C }};
        std::array<uint32_t, 2> const c5 = {{ 0x0053, 0x0302 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_020)
{
    // 015D;015D;0073 0302;015D;0073 0302;
    // (ŝ; ŝ; s◌̂; ŝ; s◌̂; ) LATIN SMALL LETTER S WITH CIRCUMFLEX
    {
        std::array<uint32_t, 1> const c1 = {{ 0x015D }};
        std::array<uint32_t, 1> const c2 = {{ 0x015D }};
        std::array<uint32_t, 2> const c3 = {{ 0x0073, 0x0302 }};
        std::array<uint32_t, 1> const c4 = {{ 0x015D }};
        std::array<uint32_t, 2> const c5 = {{ 0x0073, 0x0302 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_021)
{
    // 015E;015E;0053 0327;015E;0053 0327;
    // (Ş; Ş; S◌̧; Ş; S◌̧; ) LATIN CAPITAL LETTER S WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x015E }};
        std::array<uint32_t, 1> const c2 = {{ 0x015E }};
        std::array<uint32_t, 2> const c3 = {{ 0x0053, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x015E }};
        std::array<uint32_t, 2> const c5 = {{ 0x0053, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_022)
{
    // 015F;015F;0073 0327;015F;0073 0327;
    // (ş; ş; s◌̧; ş; s◌̧; ) LATIN SMALL LETTER S WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x015F }};
        std::array<uint32_t, 1> const c2 = {{ 0x015F }};
        std::array<uint32_t, 2> const c3 = {{ 0x0073, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x015F }};
        std::array<uint32_t, 2> const c5 = {{ 0x0073, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_023)
{
    // 0160;0160;0053 030C;0160;0053 030C;
    // (Š; Š; S◌̌; Š; S◌̌; ) LATIN CAPITAL LETTER S WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0160 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0160 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0053, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0160 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0053, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_024)
{
    // 0161;0161;0073 030C;0161;0073 030C;
    // (š; š; s◌̌; š; s◌̌; ) LATIN SMALL LETTER S WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0161 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0161 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0073, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0161 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0073, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_025)
{
    // 0162;0162;0054 0327;0162;0054 0327;
    // (Ţ; Ţ; T◌̧; Ţ; T◌̧; ) LATIN CAPITAL LETTER T WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0162 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0162 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0054, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0162 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0054, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_026)
{
    // 0163;0163;0074 0327;0163;0074 0327;
    // (ţ; ţ; t◌̧; ţ; t◌̧; ) LATIN SMALL LETTER T WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0163 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0163 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0074, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0163 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0074, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_027)
{
    // 0164;0164;0054 030C;0164;0054 030C;
    // (Ť; Ť; T◌̌; Ť; T◌̌; ) LATIN CAPITAL LETTER T WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0164 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0164 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0054, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0164 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0054, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_028)
{
    // 0165;0165;0074 030C;0165;0074 030C;
    // (ť; ť; t◌̌; ť; t◌̌; ) LATIN SMALL LETTER T WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0165 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0165 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0074, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x0165 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0074, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_029)
{
    // 0168;0168;0055 0303;0168;0055 0303;
    // (Ũ; Ũ; U◌̃; Ũ; U◌̃; ) LATIN CAPITAL LETTER U WITH TILDE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0168 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0168 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x0303 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0168 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x0303 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_030)
{
    // 0169;0169;0075 0303;0169;0075 0303;
    // (ũ; ũ; u◌̃; ũ; u◌̃; ) LATIN SMALL LETTER U WITH TILDE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0169 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0169 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x0303 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0169 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x0303 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_031)
{
    // 016A;016A;0055 0304;016A;0055 0304;
    // (Ū; Ū; U◌̄; Ū; U◌̄; ) LATIN CAPITAL LETTER U WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x016A }};
        std::array<uint32_t, 1> const c2 = {{ 0x016A }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x016A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_032)
{
    // 016B;016B;0075 0304;016B;0075 0304;
    // (ū; ū; u◌̄; ū; u◌̄; ) LATIN SMALL LETTER U WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x016B }};
        std::array<uint32_t, 1> const c2 = {{ 0x016B }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x016B }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_033)
{
    // 016C;016C;0055 0306;016C;0055 0306;
    // (Ŭ; Ŭ; U◌̆; Ŭ; U◌̆; ) LATIN CAPITAL LETTER U WITH BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x016C }};
        std::array<uint32_t, 1> const c2 = {{ 0x016C }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x0306 }};
        std::array<uint32_t, 1> const c4 = {{ 0x016C }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x0306 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_034)
{
    // 016D;016D;0075 0306;016D;0075 0306;
    // (ŭ; ŭ; u◌̆; ŭ; u◌̆; ) LATIN SMALL LETTER U WITH BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x016D }};
        std::array<uint32_t, 1> const c2 = {{ 0x016D }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x0306 }};
        std::array<uint32_t, 1> const c4 = {{ 0x016D }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x0306 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_035)
{
    // 016E;016E;0055 030A;016E;0055 030A;
    // (Ů; Ů; U◌̊; Ů; U◌̊; ) LATIN CAPITAL LETTER U WITH RING ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x016E }};
        std::array<uint32_t, 1> const c2 = {{ 0x016E }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x030A }};
        std::array<uint32_t, 1> const c4 = {{ 0x016E }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x030A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_036)
{
    // 016F;016F;0075 030A;016F;0075 030A;
    // (ů; ů; u◌̊; ů; u◌̊; ) LATIN SMALL LETTER U WITH RING ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x016F }};
        std::array<uint32_t, 1> const c2 = {{ 0x016F }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x030A }};
        std::array<uint32_t, 1> const c4 = {{ 0x016F }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x030A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_037)
{
    // 0170;0170;0055 030B;0170;0055 030B;
    // (Ű; Ű; U◌̋; Ű; U◌̋; ) LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0170 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0170 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x030B }};
        std::array<uint32_t, 1> const c4 = {{ 0x0170 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x030B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_038)
{
    // 0171;0171;0075 030B;0171;0075 030B;
    // (ű; ű; u◌̋; ű; u◌̋; ) LATIN SMALL LETTER U WITH DOUBLE ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0171 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0171 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x030B }};
        std::array<uint32_t, 1> const c4 = {{ 0x0171 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x030B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_039)
{
    // 0172;0172;0055 0328;0172;0055 0328;
    // (Ų; Ų; U◌̨; Ų; U◌̨; ) LATIN CAPITAL LETTER U WITH OGONEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0172 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0172 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x0328 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0172 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x0328 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_040)
{
    // 0173;0173;0075 0328;0173;0075 0328;
    // (ų; ų; u◌̨; ų; u◌̨; ) LATIN SMALL LETTER U WITH OGONEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0173 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0173 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x0328 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0173 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x0328 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_041)
{
    // 0174;0174;0057 0302;0174;0057 0302;
    // (Ŵ; Ŵ; W◌̂; Ŵ; W◌̂; ) LATIN CAPITAL LETTER W WITH CIRCUMFLEX
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0174 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0174 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0057, 0x0302 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0174 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0057, 0x0302 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_042)
{
    // 0175;0175;0077 0302;0175;0077 0302;
    // (ŵ; ŵ; w◌̂; ŵ; w◌̂; ) LATIN SMALL LETTER W WITH CIRCUMFLEX
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0175 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0175 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0077, 0x0302 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0175 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0077, 0x0302 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_043)
{
    // 0176;0176;0059 0302;0176;0059 0302;
    // (Ŷ; Ŷ; Y◌̂; Ŷ; Y◌̂; ) LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0176 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0176 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0059, 0x0302 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0176 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0059, 0x0302 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_044)
{
    // 0177;0177;0079 0302;0177;0079 0302;
    // (ŷ; ŷ; y◌̂; ŷ; y◌̂; ) LATIN SMALL LETTER Y WITH CIRCUMFLEX
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0177 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0177 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0079, 0x0302 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0177 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0079, 0x0302 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_045)
{
    // 0178;0178;0059 0308;0178;0059 0308;
    // (Ÿ; Ÿ; Y◌̈; Ÿ; Y◌̈; ) LATIN CAPITAL LETTER Y WITH DIAERESIS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0178 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0178 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0059, 0x0308 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0178 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0059, 0x0308 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_046)
{
    // 0179;0179;005A 0301;0179;005A 0301;
    // (Ź; Ź; Z◌́; Ź; Z◌́; ) LATIN CAPITAL LETTER Z WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0179 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0179 }};
        std::array<uint32_t, 2> const c3 = {{ 0x005A, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0179 }};
        std::array<uint32_t, 2> const c5 = {{ 0x005A, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_047)
{
    // 017A;017A;007A 0301;017A;007A 0301;
    // (ź; ź; z◌́; ź; z◌́; ) LATIN SMALL LETTER Z WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x017A }};
        std::array<uint32_t, 1> const c2 = {{ 0x017A }};
        std::array<uint32_t, 2> const c3 = {{ 0x007A, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x017A }};
        std::array<uint32_t, 2> const c5 = {{ 0x007A, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_048)
{
    // 017B;017B;005A 0307;017B;005A 0307;
    // (Ż; Ż; Z◌̇; Ż; Z◌̇; ) LATIN CAPITAL LETTER Z WITH DOT ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x017B }};
        std::array<uint32_t, 1> const c2 = {{ 0x017B }};
        std::array<uint32_t, 2> const c3 = {{ 0x005A, 0x0307 }};
        std::array<uint32_t, 1> const c4 = {{ 0x017B }};
        std::array<uint32_t, 2> const c5 = {{ 0x005A, 0x0307 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_049)
{
    // 017C;017C;007A 0307;017C;007A 0307;
    // (ż; ż; z◌̇; ż; z◌̇; ) LATIN SMALL LETTER Z WITH DOT ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x017C }};
        std::array<uint32_t, 1> const c2 = {{ 0x017C }};
        std::array<uint32_t, 2> const c3 = {{ 0x007A, 0x0307 }};
        std::array<uint32_t, 1> const c4 = {{ 0x017C }};
        std::array<uint32_t, 2> const c5 = {{ 0x007A, 0x0307 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_050)
{
    // 017D;017D;005A 030C;017D;005A 030C;
    // (Ž; Ž; Z◌̌; Ž; Z◌̌; ) LATIN CAPITAL LETTER Z WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x017D }};
        std::array<uint32_t, 1> const c2 = {{ 0x017D }};
        std::array<uint32_t, 2> const c3 = {{ 0x005A, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x017D }};
        std::array<uint32_t, 2> const c5 = {{ 0x005A, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_051)
{
    // 017E;017E;007A 030C;017E;007A 030C;
    // (ž; ž; z◌̌; ž; z◌̌; ) LATIN SMALL LETTER Z WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x017E }};
        std::array<uint32_t, 1> const c2 = {{ 0x017E }};
        std::array<uint32_t, 2> const c3 = {{ 0x007A, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x017E }};
        std::array<uint32_t, 2> const c5 = {{ 0x007A, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_052)
{
    // 017F;017F;017F;0073;0073;
    // (ſ; ſ; ſ; s; s; ) LATIN SMALL LETTER LONG S
    {
        std::array<uint32_t, 1> const c1 = {{ 0x017F }};
        std::array<uint32_t, 1> const c2 = {{ 0x017F }};
        std::array<uint32_t, 1> const c3 = {{ 0x017F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0073 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0073 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_053)
{
    // 01A0;01A0;004F 031B;01A0;004F 031B;
    // (Ơ; Ơ; O◌̛; Ơ; O◌̛; ) LATIN CAPITAL LETTER O WITH HORN
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01A0 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01A0 }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x031B }};
        std::array<uint32_t, 1> const c4 = {{ 0x01A0 }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x031B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_054)
{
    // 01A1;01A1;006F 031B;01A1;006F 031B;
    // (ơ; ơ; o◌̛; ơ; o◌̛; ) LATIN SMALL LETTER O WITH HORN
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01A1 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01A1 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x031B }};
        std::array<uint32_t, 1> const c4 = {{ 0x01A1 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x031B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_055)
{
    // 01AF;01AF;0055 031B;01AF;0055 031B;
    // (Ư; Ư; U◌̛; Ư; U◌̛; ) LATIN CAPITAL LETTER U WITH HORN
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01AF }};
        std::array<uint32_t, 1> const c2 = {{ 0x01AF }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x031B }};
        std::array<uint32_t, 1> const c4 = {{ 0x01AF }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x031B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_056)
{
    // 01B0;01B0;0075 031B;01B0;0075 031B;
    // (ư; ư; u◌̛; ư; u◌̛; ) LATIN SMALL LETTER U WITH HORN
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01B0 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01B0 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x031B }};
        std::array<uint32_t, 1> const c4 = {{ 0x01B0 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x031B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_057)
{
    // 01C4;01C4;01C4;0044 017D;0044 005A 030C;
    // (Ǆ; Ǆ; Ǆ; DŽ; DZ◌̌; ) LATIN CAPITAL LETTER DZ WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01C4 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01C4 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01C4 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0044, 0x017D }};
        std::array<uint32_t, 3> const c5 = {{ 0x0044, 0x005A, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_058)
{
    // 01C5;01C5;01C5;0044 017E;0044 007A 030C;
    // (ǅ; ǅ; ǅ; Dž; Dz◌̌; ) LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01C5 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01C5 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01C5 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0044, 0x017E }};
        std::array<uint32_t, 3> const c5 = {{ 0x0044, 0x007A, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_059)
{
    // 01C6;01C6;01C6;0064 017E;0064 007A 030C;
    // (ǆ; ǆ; ǆ; dž; dz◌̌; ) LATIN SMALL LETTER DZ WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01C6 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01C6 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01C6 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0064, 0x017E }};
        std::array<uint32_t, 3> const c5 = {{ 0x0064, 0x007A, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_060)
{
    // 01C7;01C7;01C7;004C 004A;004C 004A;
    // (Ǉ; Ǉ; Ǉ; LJ; LJ; ) LATIN CAPITAL LETTER LJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01C7 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01C7 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01C7 }};
        std::array<uint32_t, 2> const c4 = {{ 0x004C, 0x004A }};
        std::array<uint32_t, 2> const c5 = {{ 0x004C, 0x004A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_061)
{
    // 01C8;01C8;01C8;004C 006A;004C 006A;
    // (ǈ; ǈ; ǈ; Lj; Lj; ) LATIN CAPITAL LETTER L WITH SMALL LETTER J
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01C8 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01C8 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01C8 }};
        std::array<uint32_t, 2> const c4 = {{ 0x004C, 0x006A }};
        std::array<uint32_t, 2> const c5 = {{ 0x004C, 0x006A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_062)
{
    // 01C9;01C9;01C9;006C 006A;006C 006A;
    // (ǉ; ǉ; ǉ; lj; lj; ) LATIN SMALL LETTER LJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01C9 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01C9 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01C9 }};
        std::array<uint32_t, 2> const c4 = {{ 0x006C, 0x006A }};
        std::array<uint32_t, 2> const c5 = {{ 0x006C, 0x006A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_063)
{
    // 01CA;01CA;01CA;004E 004A;004E 004A;
    // (Ǌ; Ǌ; Ǌ; NJ; NJ; ) LATIN CAPITAL LETTER NJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01CA }};
        std::array<uint32_t, 1> const c2 = {{ 0x01CA }};
        std::array<uint32_t, 1> const c3 = {{ 0x01CA }};
        std::array<uint32_t, 2> const c4 = {{ 0x004E, 0x004A }};
        std::array<uint32_t, 2> const c5 = {{ 0x004E, 0x004A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_064)
{
    // 01CB;01CB;01CB;004E 006A;004E 006A;
    // (ǋ; ǋ; ǋ; Nj; Nj; ) LATIN CAPITAL LETTER N WITH SMALL LETTER J
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01CB }};
        std::array<uint32_t, 1> const c2 = {{ 0x01CB }};
        std::array<uint32_t, 1> const c3 = {{ 0x01CB }};
        std::array<uint32_t, 2> const c4 = {{ 0x004E, 0x006A }};
        std::array<uint32_t, 2> const c5 = {{ 0x004E, 0x006A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_065)
{
    // 01CC;01CC;01CC;006E 006A;006E 006A;
    // (ǌ; ǌ; ǌ; nj; nj; ) LATIN SMALL LETTER NJ
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01CC }};
        std::array<uint32_t, 1> const c2 = {{ 0x01CC }};
        std::array<uint32_t, 1> const c3 = {{ 0x01CC }};
        std::array<uint32_t, 2> const c4 = {{ 0x006E, 0x006A }};
        std::array<uint32_t, 2> const c5 = {{ 0x006E, 0x006A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_066)
{
    // 01CD;01CD;0041 030C;01CD;0041 030C;
    // (Ǎ; Ǎ; A◌̌; Ǎ; A◌̌; ) LATIN CAPITAL LETTER A WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01CD }};
        std::array<uint32_t, 1> const c2 = {{ 0x01CD }};
        std::array<uint32_t, 2> const c3 = {{ 0x0041, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01CD }};
        std::array<uint32_t, 2> const c5 = {{ 0x0041, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_067)
{
    // 01CE;01CE;0061 030C;01CE;0061 030C;
    // (ǎ; ǎ; a◌̌; ǎ; a◌̌; ) LATIN SMALL LETTER A WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01CE }};
        std::array<uint32_t, 1> const c2 = {{ 0x01CE }};
        std::array<uint32_t, 2> const c3 = {{ 0x0061, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01CE }};
        std::array<uint32_t, 2> const c5 = {{ 0x0061, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_068)
{
    // 01CF;01CF;0049 030C;01CF;0049 030C;
    // (Ǐ; Ǐ; I◌̌; Ǐ; I◌̌; ) LATIN CAPITAL LETTER I WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01CF }};
        std::array<uint32_t, 1> const c2 = {{ 0x01CF }};
        std::array<uint32_t, 2> const c3 = {{ 0x0049, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01CF }};
        std::array<uint32_t, 2> const c5 = {{ 0x0049, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_069)
{
    // 01D0;01D0;0069 030C;01D0;0069 030C;
    // (ǐ; ǐ; i◌̌; ǐ; i◌̌; ) LATIN SMALL LETTER I WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D0 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D0 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0069, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D0 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0069, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_070)
{
    // 01D1;01D1;004F 030C;01D1;004F 030C;
    // (Ǒ; Ǒ; O◌̌; Ǒ; O◌̌; ) LATIN CAPITAL LETTER O WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D1 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D1 }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D1 }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_071)
{
    // 01D2;01D2;006F 030C;01D2;006F 030C;
    // (ǒ; ǒ; o◌̌; ǒ; o◌̌; ) LATIN SMALL LETTER O WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D2 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D2 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D2 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_072)
{
    // 01D3;01D3;0055 030C;01D3;0055 030C;
    // (Ǔ; Ǔ; U◌̌; Ǔ; U◌̌; ) LATIN CAPITAL LETTER U WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D3 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D3 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D3 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_073)
{
    // 01D4;01D4;0075 030C;01D4;0075 030C;
    // (ǔ; ǔ; u◌̌; ǔ; u◌̌; ) LATIN SMALL LETTER U WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D4 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D4 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D4 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_074)
{
    // 01D5;01D5;0055 0308 0304;01D5;0055 0308 0304;
    // (Ǖ; Ǖ; U◌̈◌̄; Ǖ; U◌̈◌̄; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D5 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D5 }};
        std::array<uint32_t, 3> const c3 = {{ 0x0055, 0x0308, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D5 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0055, 0x0308, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_075)
{
    // 01D6;01D6;0075 0308 0304;01D6;0075 0308 0304;
    // (ǖ; ǖ; u◌̈◌̄; ǖ; u◌̈◌̄; ) LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D6 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D6 }};
        std::array<uint32_t, 3> const c3 = {{ 0x0075, 0x0308, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D6 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0075, 0x0308, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_076)
{
    // 01D7;01D7;0055 0308 0301;01D7;0055 0308 0301;
    // (Ǘ; Ǘ; U◌̈◌́; Ǘ; U◌̈◌́; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D7 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D7 }};
        std::array<uint32_t, 3> const c3 = {{ 0x0055, 0x0308, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D7 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0055, 0x0308, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_077)
{
    // 01D8;01D8;0075 0308 0301;01D8;0075 0308 0301;
    // (ǘ; ǘ; u◌̈◌́; ǘ; u◌̈◌́; ) LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D8 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D8 }};
        std::array<uint32_t, 3> const c3 = {{ 0x0075, 0x0308, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D8 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0075, 0x0308, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_078)
{
    // 01D9;01D9;0055 0308 030C;01D9;0055 0308 030C;
    // (Ǚ; Ǚ; U◌̈◌̌; Ǚ; U◌̈◌̌; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01D9 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01D9 }};
        std::array<uint32_t, 3> const c3 = {{ 0x0055, 0x0308, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01D9 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0055, 0x0308, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_079)
{
    // 01DA;01DA;0075 0308 030C;01DA;0075 0308 030C;
    // (ǚ; ǚ; u◌̈◌̌; ǚ; u◌̈◌̌; ) LATIN SMALL LETTER U WITH DIAERESIS AND CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01DA }};
        std::array<uint32_t, 1> const c2 = {{ 0x01DA }};
        std::array<uint32_t, 3> const c3 = {{ 0x0075, 0x0308, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01DA }};
        std::array<uint32_t, 3> const c5 = {{ 0x0075, 0x0308, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_080)
{
    // 01DB;01DB;0055 0308 0300;01DB;0055 0308 0300;
    // (Ǜ; Ǜ; U◌̈◌̀; Ǜ; U◌̈◌̀; ) LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01DB }};
        std::array<uint32_t, 1> const c2 = {{ 0x01DB }};
        std::array<uint32_t, 3> const c3 = {{ 0x0055, 0x0308, 0x0300 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01DB }};
        std::array<uint32_t, 3> const c5 = {{ 0x0055, 0x0308, 0x0300 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_081)
{
    // 01DC;01DC;0075 0308 0300;01DC;0075 0308 0300;
    // (ǜ; ǜ; u◌̈◌̀; ǜ; u◌̈◌̀; ) LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01DC }};
        std::array<uint32_t, 1> const c2 = {{ 0x01DC }};
        std::array<uint32_t, 3> const c3 = {{ 0x0075, 0x0308, 0x0300 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01DC }};
        std::array<uint32_t, 3> const c5 = {{ 0x0075, 0x0308, 0x0300 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_082)
{
    // 01DE;01DE;0041 0308 0304;01DE;0041 0308 0304;
    // (Ǟ; Ǟ; A◌̈◌̄; Ǟ; A◌̈◌̄; ) LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01DE }};
        std::array<uint32_t, 1> const c2 = {{ 0x01DE }};
        std::array<uint32_t, 3> const c3 = {{ 0x0041, 0x0308, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01DE }};
        std::array<uint32_t, 3> const c5 = {{ 0x0041, 0x0308, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_083)
{
    // 01DF;01DF;0061 0308 0304;01DF;0061 0308 0304;
    // (ǟ; ǟ; a◌̈◌̄; ǟ; a◌̈◌̄; ) LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01DF }};
        std::array<uint32_t, 1> const c2 = {{ 0x01DF }};
        std::array<uint32_t, 3> const c3 = {{ 0x0061, 0x0308, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01DF }};
        std::array<uint32_t, 3> const c5 = {{ 0x0061, 0x0308, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_084)
{
    // 01E0;01E0;0041 0307 0304;01E0;0041 0307 0304;
    // (Ǡ; Ǡ; A◌̇◌̄; Ǡ; A◌̇◌̄; ) LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E0 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E0 }};
        std::array<uint32_t, 3> const c3 = {{ 0x0041, 0x0307, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E0 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0041, 0x0307, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_085)
{
    // 01E1;01E1;0061 0307 0304;01E1;0061 0307 0304;
    // (ǡ; ǡ; a◌̇◌̄; ǡ; a◌̇◌̄; ) LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E1 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E1 }};
        std::array<uint32_t, 3> const c3 = {{ 0x0061, 0x0307, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E1 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0061, 0x0307, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_086)
{
    // 01E2;01E2;00C6 0304;01E2;00C6 0304;
    // (Ǣ; Ǣ; Æ◌̄; Ǣ; Æ◌̄; ) LATIN CAPITAL LETTER AE WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E2 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E2 }};
        std::array<uint32_t, 2> const c3 = {{ 0x00C6, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E2 }};
        std::array<uint32_t, 2> const c5 = {{ 0x00C6, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_087)
{
    // 01E3;01E3;00E6 0304;01E3;00E6 0304;
    // (ǣ; ǣ; æ◌̄; ǣ; æ◌̄; ) LATIN SMALL LETTER AE WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E3 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E3 }};
        std::array<uint32_t, 2> const c3 = {{ 0x00E6, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E3 }};
        std::array<uint32_t, 2> const c5 = {{ 0x00E6, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_088)
{
    // 01E6;01E6;0047 030C;01E6;0047 030C;
    // (Ǧ; Ǧ; G◌̌; Ǧ; G◌̌; ) LATIN CAPITAL LETTER G WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E6 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E6 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0047, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E6 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0047, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_089)
{
    // 01E7;01E7;0067 030C;01E7;0067 030C;
    // (ǧ; ǧ; g◌̌; ǧ; g◌̌; ) LATIN SMALL LETTER G WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E7 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E7 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0067, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E7 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0067, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_090)
{
    // 01E8;01E8;004B 030C;01E8;004B 030C;
    // (Ǩ; Ǩ; K◌̌; Ǩ; K◌̌; ) LATIN CAPITAL LETTER K WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E8 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E8 }};
        std::array<uint32_t, 2> const c3 = {{ 0x004B, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E8 }};
        std::array<uint32_t, 2> const c5 = {{ 0x004B, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_091)
{
    // 01E9;01E9;006B 030C;01E9;006B 030C;
    // (ǩ; ǩ; k◌̌; ǩ; k◌̌; ) LATIN SMALL LETTER K WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01E9 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01E9 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006B, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01E9 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006B, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_092)
{
    // 01EA;01EA;004F 0328;01EA;004F 0328;
    // (Ǫ; Ǫ; O◌̨; Ǫ; O◌̨; ) LATIN CAPITAL LETTER O WITH OGONEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01EA }};
        std::array<uint32_t, 1> const c2 = {{ 0x01EA }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x0328 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01EA }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x0328 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_093)
{
    // 01EB;01EB;006F 0328;01EB;006F 0328;
    // (ǫ; ǫ; o◌̨; ǫ; o◌̨; ) LATIN SMALL LETTER O WITH OGONEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01EB }};
        std::array<uint32_t, 1> const c2 = {{ 0x01EB }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x0328 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01EB }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x0328 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_094)
{
    // 01EC;01EC;004F 0328 0304;01EC;004F 0328 0304;
    // (Ǭ; Ǭ; O◌̨◌̄; Ǭ; O◌̨◌̄; ) LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01EC }};
        std::array<uint32_t, 1> const c2 = {{ 0x01EC }};
        std::array<uint32_t, 3> const c3 = {{ 0x004F, 0x0328, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01EC }};
        std::array<uint32_t, 3> const c5 = {{ 0x004F, 0x0328, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_095)
{
    // 01ED;01ED;006F 0328 0304;01ED;006F 0328 0304;
    // (ǭ; ǭ; o◌̨◌̄; ǭ; o◌̨◌̄; ) LATIN SMALL LETTER O WITH OGONEK AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01ED }};
        std::array<uint32_t, 1> const c2 = {{ 0x01ED }};
        std::array<uint32_t, 3> const c3 = {{ 0x006F, 0x0328, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01ED }};
        std::array<uint32_t, 3> const c5 = {{ 0x006F, 0x0328, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_096)
{
    // 01EE;01EE;01B7 030C;01EE;01B7 030C;
    // (Ǯ; Ǯ; Ʒ◌̌; Ǯ; Ʒ◌̌; ) LATIN CAPITAL LETTER EZH WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01EE }};
        std::array<uint32_t, 1> const c2 = {{ 0x01EE }};
        std::array<uint32_t, 2> const c3 = {{ 0x01B7, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01EE }};
        std::array<uint32_t, 2> const c5 = {{ 0x01B7, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_097)
{
    // 01EF;01EF;0292 030C;01EF;0292 030C;
    // (ǯ; ǯ; ʒ◌̌; ǯ; ʒ◌̌; ) LATIN SMALL LETTER EZH WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01EF }};
        std::array<uint32_t, 1> const c2 = {{ 0x01EF }};
        std::array<uint32_t, 2> const c3 = {{ 0x0292, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01EF }};
        std::array<uint32_t, 2> const c5 = {{ 0x0292, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_098)
{
    // 01F0;01F0;006A 030C;01F0;006A 030C;
    // (ǰ; ǰ; j◌̌; ǰ; j◌̌; ) LATIN SMALL LETTER J WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F0 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F0 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006A, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x01F0 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006A, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_099)
{
    // 01F1;01F1;01F1;0044 005A;0044 005A;
    // (Ǳ; Ǳ; Ǳ; DZ; DZ; ) LATIN CAPITAL LETTER DZ
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F1 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F1 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01F1 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0044, 0x005A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0044, 0x005A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_100)
{
    // 01F2;01F2;01F2;0044 007A;0044 007A;
    // (ǲ; ǲ; ǲ; Dz; Dz; ) LATIN CAPITAL LETTER D WITH SMALL LETTER Z
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F2 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F2 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01F2 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0044, 0x007A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0044, 0x007A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_101)
{
    // 01F3;01F3;01F3;0064 007A;0064 007A;
    // (ǳ; ǳ; ǳ; dz; dz; ) LATIN SMALL LETTER DZ
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F3 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F3 }};
        std::array<uint32_t, 1> const c3 = {{ 0x01F3 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0064, 0x007A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0064, 0x007A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_102)
{
    // 01F4;01F4;0047 0301;01F4;0047 0301;
    // (Ǵ; Ǵ; G◌́; Ǵ; G◌́; ) LATIN CAPITAL LETTER G WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F4 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F4 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0047, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01F4 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0047, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_103)
{
    // 01F5;01F5;0067 0301;01F5;0067 0301;
    // (ǵ; ǵ; g◌́; ǵ; g◌́; ) LATIN SMALL LETTER G WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F5 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F5 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0067, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01F5 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0067, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_104)
{
    // 01F8;01F8;004E 0300;01F8;004E 0300;
    // (Ǹ; Ǹ; N◌̀; Ǹ; N◌̀; ) LATIN CAPITAL LETTER N WITH GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F8 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F8 }};
        std::array<uint32_t, 2> const c3 = {{ 0x004E, 0x0300 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01F8 }};
        std::array<uint32_t, 2> const c5 = {{ 0x004E, 0x0300 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_105)
{
    // 01F9;01F9;006E 0300;01F9;006E 0300;
    // (ǹ; ǹ; n◌̀; ǹ; n◌̀; ) LATIN SMALL LETTER N WITH GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01F9 }};
        std::array<uint32_t, 1> const c2 = {{ 0x01F9 }};
        std::array<uint32_t, 2> const c3 = {{ 0x006E, 0x0300 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01F9 }};
        std::array<uint32_t, 2> const c5 = {{ 0x006E, 0x0300 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_106)
{
    // 01FA;01FA;0041 030A 0301;01FA;0041 030A 0301;
    // (Ǻ; Ǻ; A◌̊◌́; Ǻ; A◌̊◌́; ) LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01FA }};
        std::array<uint32_t, 1> const c2 = {{ 0x01FA }};
        std::array<uint32_t, 3> const c3 = {{ 0x0041, 0x030A, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01FA }};
        std::array<uint32_t, 3> const c5 = {{ 0x0041, 0x030A, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_107)
{
    // 01FB;01FB;0061 030A 0301;01FB;0061 030A 0301;
    // (ǻ; ǻ; a◌̊◌́; ǻ; a◌̊◌́; ) LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01FB }};
        std::array<uint32_t, 1> const c2 = {{ 0x01FB }};
        std::array<uint32_t, 3> const c3 = {{ 0x0061, 0x030A, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01FB }};
        std::array<uint32_t, 3> const c5 = {{ 0x0061, 0x030A, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_108)
{
    // 01FC;01FC;00C6 0301;01FC;00C6 0301;
    // (Ǽ; Ǽ; Æ◌́; Ǽ; Æ◌́; ) LATIN CAPITAL LETTER AE WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01FC }};
        std::array<uint32_t, 1> const c2 = {{ 0x01FC }};
        std::array<uint32_t, 2> const c3 = {{ 0x00C6, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01FC }};
        std::array<uint32_t, 2> const c5 = {{ 0x00C6, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_109)
{
    // 01FD;01FD;00E6 0301;01FD;00E6 0301;
    // (ǽ; ǽ; æ◌́; ǽ; æ◌́; ) LATIN SMALL LETTER AE WITH ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01FD }};
        std::array<uint32_t, 1> const c2 = {{ 0x01FD }};
        std::array<uint32_t, 2> const c3 = {{ 0x00E6, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01FD }};
        std::array<uint32_t, 2> const c5 = {{ 0x00E6, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_110)
{
    // 01FE;01FE;00D8 0301;01FE;00D8 0301;
    // (Ǿ; Ǿ; Ø◌́; Ǿ; Ø◌́; ) LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01FE }};
        std::array<uint32_t, 1> const c2 = {{ 0x01FE }};
        std::array<uint32_t, 2> const c3 = {{ 0x00D8, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01FE }};
        std::array<uint32_t, 2> const c5 = {{ 0x00D8, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_111)
{
    // 01FF;01FF;00F8 0301;01FF;00F8 0301;
    // (ǿ; ǿ; ø◌́; ǿ; ø◌́; ) LATIN SMALL LETTER O WITH STROKE AND ACUTE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x01FF }};
        std::array<uint32_t, 1> const c2 = {{ 0x01FF }};
        std::array<uint32_t, 2> const c3 = {{ 0x00F8, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x01FF }};
        std::array<uint32_t, 2> const c5 = {{ 0x00F8, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_112)
{
    // 0200;0200;0041 030F;0200;0041 030F;
    // (Ȁ; Ȁ; A◌̏; Ȁ; A◌̏; ) LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0200 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0200 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0041, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0200 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0041, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_113)
{
    // 0201;0201;0061 030F;0201;0061 030F;
    // (ȁ; ȁ; a◌̏; ȁ; a◌̏; ) LATIN SMALL LETTER A WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0201 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0201 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0061, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0201 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0061, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_114)
{
    // 0202;0202;0041 0311;0202;0041 0311;
    // (Ȃ; Ȃ; A◌̑; Ȃ; A◌̑; ) LATIN CAPITAL LETTER A WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0202 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0202 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0041, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0202 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0041, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_115)
{
    // 0203;0203;0061 0311;0203;0061 0311;
    // (ȃ; ȃ; a◌̑; ȃ; a◌̑; ) LATIN SMALL LETTER A WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0203 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0203 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0061, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0203 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0061, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_116)
{
    // 0204;0204;0045 030F;0204;0045 030F;
    // (Ȅ; Ȅ; E◌̏; Ȅ; E◌̏; ) LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0204 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0204 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0045, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0204 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0045, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_117)
{
    // 0205;0205;0065 030F;0205;0065 030F;
    // (ȅ; ȅ; e◌̏; ȅ; e◌̏; ) LATIN SMALL LETTER E WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0205 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0205 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0065, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0205 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0065, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_118)
{
    // 0206;0206;0045 0311;0206;0045 0311;
    // (Ȇ; Ȇ; E◌̑; Ȇ; E◌̑; ) LATIN CAPITAL LETTER E WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0206 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0206 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0045, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0206 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0045, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_119)
{
    // 0207;0207;0065 0311;0207;0065 0311;
    // (ȇ; ȇ; e◌̑; ȇ; e◌̑; ) LATIN SMALL LETTER E WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0207 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0207 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0065, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0207 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0065, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_120)
{
    // 0208;0208;0049 030F;0208;0049 030F;
    // (Ȉ; Ȉ; I◌̏; Ȉ; I◌̏; ) LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0208 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0208 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0049, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0208 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0049, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_121)
{
    // 0209;0209;0069 030F;0209;0069 030F;
    // (ȉ; ȉ; i◌̏; ȉ; i◌̏; ) LATIN SMALL LETTER I WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0209 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0209 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0069, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0209 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0069, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_122)
{
    // 020A;020A;0049 0311;020A;0049 0311;
    // (Ȋ; Ȋ; I◌̑; Ȋ; I◌̑; ) LATIN CAPITAL LETTER I WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x020A }};
        std::array<uint32_t, 1> const c2 = {{ 0x020A }};
        std::array<uint32_t, 2> const c3 = {{ 0x0049, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x020A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0049, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_123)
{
    // 020B;020B;0069 0311;020B;0069 0311;
    // (ȋ; ȋ; i◌̑; ȋ; i◌̑; ) LATIN SMALL LETTER I WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x020B }};
        std::array<uint32_t, 1> const c2 = {{ 0x020B }};
        std::array<uint32_t, 2> const c3 = {{ 0x0069, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x020B }};
        std::array<uint32_t, 2> const c5 = {{ 0x0069, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_124)
{
    // 020C;020C;004F 030F;020C;004F 030F;
    // (Ȍ; Ȍ; O◌̏; Ȍ; O◌̏; ) LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x020C }};
        std::array<uint32_t, 1> const c2 = {{ 0x020C }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x020C }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_125)
{
    // 020D;020D;006F 030F;020D;006F 030F;
    // (ȍ; ȍ; o◌̏; ȍ; o◌̏; ) LATIN SMALL LETTER O WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x020D }};
        std::array<uint32_t, 1> const c2 = {{ 0x020D }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x020D }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_126)
{
    // 020E;020E;004F 0311;020E;004F 0311;
    // (Ȏ; Ȏ; O◌̑; Ȏ; O◌̑; ) LATIN CAPITAL LETTER O WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x020E }};
        std::array<uint32_t, 1> const c2 = {{ 0x020E }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x020E }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_127)
{
    // 020F;020F;006F 0311;020F;006F 0311;
    // (ȏ; ȏ; o◌̑; ȏ; o◌̑; ) LATIN SMALL LETTER O WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x020F }};
        std::array<uint32_t, 1> const c2 = {{ 0x020F }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x020F }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_128)
{
    // 0210;0210;0052 030F;0210;0052 030F;
    // (Ȑ; Ȑ; R◌̏; Ȑ; R◌̏; ) LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0210 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0210 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0052, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0210 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0052, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_129)
{
    // 0211;0211;0072 030F;0211;0072 030F;
    // (ȑ; ȑ; r◌̏; ȑ; r◌̏; ) LATIN SMALL LETTER R WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0211 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0211 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0072, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0211 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0072, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_130)
{
    // 0212;0212;0052 0311;0212;0052 0311;
    // (Ȓ; Ȓ; R◌̑; Ȓ; R◌̑; ) LATIN CAPITAL LETTER R WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0212 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0212 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0052, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0212 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0052, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_131)
{
    // 0213;0213;0072 0311;0213;0072 0311;
    // (ȓ; ȓ; r◌̑; ȓ; r◌̑; ) LATIN SMALL LETTER R WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0213 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0213 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0072, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0213 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0072, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_132)
{
    // 0214;0214;0055 030F;0214;0055 030F;
    // (Ȕ; Ȕ; U◌̏; Ȕ; U◌̏; ) LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0214 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0214 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0214 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_133)
{
    // 0215;0215;0075 030F;0215;0075 030F;
    // (ȕ; ȕ; u◌̏; ȕ; u◌̏; ) LATIN SMALL LETTER U WITH DOUBLE GRAVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0215 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0215 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x030F }};
        std::array<uint32_t, 1> const c4 = {{ 0x0215 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x030F }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_134)
{
    // 0216;0216;0055 0311;0216;0055 0311;
    // (Ȗ; Ȗ; U◌̑; Ȗ; U◌̑; ) LATIN CAPITAL LETTER U WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0216 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0216 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0055, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0216 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0055, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_135)
{
    // 0217;0217;0075 0311;0217;0075 0311;
    // (ȗ; ȗ; u◌̑; ȗ; u◌̑; ) LATIN SMALL LETTER U WITH INVERTED BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0217 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0217 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0075, 0x0311 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0217 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0075, 0x0311 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_136)
{
    // 0218;0218;0053 0326;0218;0053 0326;
    // (Ș; Ș; S◌̦; Ș; S◌̦; ) LATIN CAPITAL LETTER S WITH COMMA BELOW
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0218 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0218 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0053, 0x0326 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0218 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0053, 0x0326 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_137)
{
    // 0219;0219;0073 0326;0219;0073 0326;
    // (ș; ș; s◌̦; ș; s◌̦; ) LATIN SMALL LETTER S WITH COMMA BELOW
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0219 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0219 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0073, 0x0326 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0219 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0073, 0x0326 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_138)
{
    // 021A;021A;0054 0326;021A;0054 0326;
    // (Ț; Ț; T◌̦; Ț; T◌̦; ) LATIN CAPITAL LETTER T WITH COMMA BELOW
    {
        std::array<uint32_t, 1> const c1 = {{ 0x021A }};
        std::array<uint32_t, 1> const c2 = {{ 0x021A }};
        std::array<uint32_t, 2> const c3 = {{ 0x0054, 0x0326 }};
        std::array<uint32_t, 1> const c4 = {{ 0x021A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0054, 0x0326 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_139)
{
    // 021B;021B;0074 0326;021B;0074 0326;
    // (ț; ț; t◌̦; ț; t◌̦; ) LATIN SMALL LETTER T WITH COMMA BELOW
    {
        std::array<uint32_t, 1> const c1 = {{ 0x021B }};
        std::array<uint32_t, 1> const c2 = {{ 0x021B }};
        std::array<uint32_t, 2> const c3 = {{ 0x0074, 0x0326 }};
        std::array<uint32_t, 1> const c4 = {{ 0x021B }};
        std::array<uint32_t, 2> const c5 = {{ 0x0074, 0x0326 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_140)
{
    // 021E;021E;0048 030C;021E;0048 030C;
    // (Ȟ; Ȟ; H◌̌; Ȟ; H◌̌; ) LATIN CAPITAL LETTER H WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x021E }};
        std::array<uint32_t, 1> const c2 = {{ 0x021E }};
        std::array<uint32_t, 2> const c3 = {{ 0x0048, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x021E }};
        std::array<uint32_t, 2> const c5 = {{ 0x0048, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_141)
{
    // 021F;021F;0068 030C;021F;0068 030C;
    // (ȟ; ȟ; h◌̌; ȟ; h◌̌; ) LATIN SMALL LETTER H WITH CARON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x021F }};
        std::array<uint32_t, 1> const c2 = {{ 0x021F }};
        std::array<uint32_t, 2> const c3 = {{ 0x0068, 0x030C }};
        std::array<uint32_t, 1> const c4 = {{ 0x021F }};
        std::array<uint32_t, 2> const c5 = {{ 0x0068, 0x030C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_142)
{
    // 0226;0226;0041 0307;0226;0041 0307;
    // (Ȧ; Ȧ; A◌̇; Ȧ; A◌̇; ) LATIN CAPITAL LETTER A WITH DOT ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0226 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0226 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0041, 0x0307 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0226 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0041, 0x0307 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_143)
{
    // 0227;0227;0061 0307;0227;0061 0307;
    // (ȧ; ȧ; a◌̇; ȧ; a◌̇; ) LATIN SMALL LETTER A WITH DOT ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0227 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0227 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0061, 0x0307 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0227 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0061, 0x0307 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_144)
{
    // 0228;0228;0045 0327;0228;0045 0327;
    // (Ȩ; Ȩ; E◌̧; Ȩ; E◌̧; ) LATIN CAPITAL LETTER E WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0228 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0228 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0045, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0228 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0045, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_145)
{
    // 0229;0229;0065 0327;0229;0065 0327;
    // (ȩ; ȩ; e◌̧; ȩ; e◌̧; ) LATIN SMALL LETTER E WITH CEDILLA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0229 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0229 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0065, 0x0327 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0229 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0065, 0x0327 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_146)
{
    // 022A;022A;004F 0308 0304;022A;004F 0308 0304;
    // (Ȫ; Ȫ; O◌̈◌̄; Ȫ; O◌̈◌̄; ) LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x022A }};
        std::array<uint32_t, 1> const c2 = {{ 0x022A }};
        std::array<uint32_t, 3> const c3 = {{ 0x004F, 0x0308, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x022A }};
        std::array<uint32_t, 3> const c5 = {{ 0x004F, 0x0308, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_147)
{
    // 022B;022B;006F 0308 0304;022B;006F 0308 0304;
    // (ȫ; ȫ; o◌̈◌̄; ȫ; o◌̈◌̄; ) LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x022B }};
        std::array<uint32_t, 1> const c2 = {{ 0x022B }};
        std::array<uint32_t, 3> const c3 = {{ 0x006F, 0x0308, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x022B }};
        std::array<uint32_t, 3> const c5 = {{ 0x006F, 0x0308, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_148)
{
    // 022C;022C;004F 0303 0304;022C;004F 0303 0304;
    // (Ȭ; Ȭ; O◌̃◌̄; Ȭ; O◌̃◌̄; ) LATIN CAPITAL LETTER O WITH TILDE AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x022C }};
        std::array<uint32_t, 1> const c2 = {{ 0x022C }};
        std::array<uint32_t, 3> const c3 = {{ 0x004F, 0x0303, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x022C }};
        std::array<uint32_t, 3> const c5 = {{ 0x004F, 0x0303, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_149)
{
    // 022D;022D;006F 0303 0304;022D;006F 0303 0304;
    // (ȭ; ȭ; o◌̃◌̄; ȭ; o◌̃◌̄; ) LATIN SMALL LETTER O WITH TILDE AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x022D }};
        std::array<uint32_t, 1> const c2 = {{ 0x022D }};
        std::array<uint32_t, 3> const c3 = {{ 0x006F, 0x0303, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x022D }};
        std::array<uint32_t, 3> const c5 = {{ 0x006F, 0x0303, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_150)
{
    // 022E;022E;004F 0307;022E;004F 0307;
    // (Ȯ; Ȯ; O◌̇; Ȯ; O◌̇; ) LATIN CAPITAL LETTER O WITH DOT ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x022E }};
        std::array<uint32_t, 1> const c2 = {{ 0x022E }};
        std::array<uint32_t, 2> const c3 = {{ 0x004F, 0x0307 }};
        std::array<uint32_t, 1> const c4 = {{ 0x022E }};
        std::array<uint32_t, 2> const c5 = {{ 0x004F, 0x0307 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_151)
{
    // 022F;022F;006F 0307;022F;006F 0307;
    // (ȯ; ȯ; o◌̇; ȯ; o◌̇; ) LATIN SMALL LETTER O WITH DOT ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x022F }};
        std::array<uint32_t, 1> const c2 = {{ 0x022F }};
        std::array<uint32_t, 2> const c3 = {{ 0x006F, 0x0307 }};
        std::array<uint32_t, 1> const c4 = {{ 0x022F }};
        std::array<uint32_t, 2> const c5 = {{ 0x006F, 0x0307 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_152)
{
    // 0230;0230;004F 0307 0304;0230;004F 0307 0304;
    // (Ȱ; Ȱ; O◌̇◌̄; Ȱ; O◌̇◌̄; ) LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0230 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0230 }};
        std::array<uint32_t, 3> const c3 = {{ 0x004F, 0x0307, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0230 }};
        std::array<uint32_t, 3> const c5 = {{ 0x004F, 0x0307, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_153)
{
    // 0231;0231;006F 0307 0304;0231;006F 0307 0304;
    // (ȱ; ȱ; o◌̇◌̄; ȱ; o◌̇◌̄; ) LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0231 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0231 }};
        std::array<uint32_t, 3> const c3 = {{ 0x006F, 0x0307, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0231 }};
        std::array<uint32_t, 3> const c5 = {{ 0x006F, 0x0307, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_154)
{
    // 0232;0232;0059 0304;0232;0059 0304;
    // (Ȳ; Ȳ; Y◌̄; Ȳ; Y◌̄; ) LATIN CAPITAL LETTER Y WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0232 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0232 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0059, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0232 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0059, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_155)
{
    // 0233;0233;0079 0304;0233;0079 0304;
    // (ȳ; ȳ; y◌̄; ȳ; y◌̄; ) LATIN SMALL LETTER Y WITH MACRON
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0233 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0233 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0079, 0x0304 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0233 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0079, 0x0304 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_156)
{
    // 02B0;02B0;02B0;0068;0068;
    // (ʰ; ʰ; ʰ; h; h; ) MODIFIER LETTER SMALL H
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B0 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B0 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B0 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0068 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0068 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_157)
{
    // 02B1;02B1;02B1;0266;0266;
    // (ʱ; ʱ; ʱ; ɦ; ɦ; ) MODIFIER LETTER SMALL H WITH HOOK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B1 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B1 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B1 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0266 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0266 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_158)
{
    // 02B2;02B2;02B2;006A;006A;
    // (ʲ; ʲ; ʲ; j; j; ) MODIFIER LETTER SMALL J
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B2 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B2 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B2 }};
        std::array<uint32_t, 1> const c4 = {{ 0x006A }};
        std::array<uint32_t, 1> const c5 = {{ 0x006A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

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

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

    }
}

TEST(normalization, nfkc_001_159)
{
    // 02B3;02B3;02B3;0072;0072;
    // (ʳ; ʳ; ʳ; r; r; ) MODIFIER LETTER SMALL R
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B3 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B3 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B3 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0072 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0072 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

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

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

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

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_160)
{
    // 02B4;02B4;02B4;0279;0279;
    // (ʴ; ʴ; ʴ; ɹ; ɹ; ) MODIFIER LETTER SMALL TURNED R
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B4 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B4 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B4 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0279 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0279 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_161)
{
    // 02B5;02B5;02B5;027B;027B;
    // (ʵ; ʵ; ʵ; ɻ; ɻ; ) MODIFIER LETTER SMALL TURNED R WITH HOOK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B5 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B5 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B5 }};
        std::array<uint32_t, 1> const c4 = {{ 0x027B }};
        std::array<uint32_t, 1> const c5 = {{ 0x027B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_162)
{
    // 02B6;02B6;02B6;0281;0281;
    // (ʶ; ʶ; ʶ; ʁ; ʁ; ) MODIFIER LETTER SMALL CAPITAL INVERTED R
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B6 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B6 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B6 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0281 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0281 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_163)
{
    // 02B7;02B7;02B7;0077;0077;
    // (ʷ; ʷ; ʷ; w; w; ) MODIFIER LETTER SMALL W
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B7 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B7 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0077 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0077 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_164)
{
    // 02B8;02B8;02B8;0079;0079;
    // (ʸ; ʸ; ʸ; y; y; ) MODIFIER LETTER SMALL Y
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02B8 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B8 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B8 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0079 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0079 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_165)
{
    // 02D8;02D8;02D8;0020 0306;0020 0306;
    // (˘; ˘; ˘;  ◌̆;  ◌̆; ) BREVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02D8 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02D8 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02D8 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x0306 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x0306 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_166)
{
    // 02D9;02D9;02D9;0020 0307;0020 0307;
    // (˙; ˙; ˙;  ◌̇;  ◌̇; ) DOT ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02D9 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02D9 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02D9 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x0307 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x0307 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_167)
{
    // 02DA;02DA;02DA;0020 030A;0020 030A;
    // (˚; ˚; ˚;  ◌̊;  ◌̊; ) RING ABOVE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02DA }};
        std::array<uint32_t, 1> const c2 = {{ 0x02DA }};
        std::array<uint32_t, 1> const c3 = {{ 0x02DA }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x030A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x030A }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_168)
{
    // 02DB;02DB;02DB;0020 0328;0020 0328;
    // (˛; ˛; ˛;  ◌̨;  ◌̨; ) OGONEK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02DB }};
        std::array<uint32_t, 1> const c2 = {{ 0x02DB }};
        std::array<uint32_t, 1> const c3 = {{ 0x02DB }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x0328 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x0328 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_169)
{
    // 02DC;02DC;02DC;0020 0303;0020 0303;
    // (˜; ˜; ˜;  ◌̃;  ◌̃; ) SMALL TILDE
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02DC }};
        std::array<uint32_t, 1> const c2 = {{ 0x02DC }};
        std::array<uint32_t, 1> const c3 = {{ 0x02DC }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x0303 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x0303 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_170)
{
    // 02DD;02DD;02DD;0020 030B;0020 030B;
    // (˝; ˝; ˝;  ◌̋;  ◌̋; ) DOUBLE ACUTE ACCENT
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02DD }};
        std::array<uint32_t, 1> const c2 = {{ 0x02DD }};
        std::array<uint32_t, 1> const c3 = {{ 0x02DD }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x030B }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x030B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_171)
{
    // 02E0;02E0;02E0;0263;0263;
    // (ˠ; ˠ; ˠ; ɣ; ɣ; ) MODIFIER LETTER SMALL GAMMA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02E0 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02E0 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02E0 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0263 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0263 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_172)
{
    // 02E1;02E1;02E1;006C;006C;
    // (ˡ; ˡ; ˡ; l; l; ) MODIFIER LETTER SMALL L
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02E1 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02E1 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02E1 }};
        std::array<uint32_t, 1> const c4 = {{ 0x006C }};
        std::array<uint32_t, 1> const c5 = {{ 0x006C }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_173)
{
    // 02E2;02E2;02E2;0073;0073;
    // (ˢ; ˢ; ˢ; s; s; ) MODIFIER LETTER SMALL S
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02E2 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02E2 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02E2 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0073 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0073 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_174)
{
    // 02E3;02E3;02E3;0078;0078;
    // (ˣ; ˣ; ˣ; x; x; ) MODIFIER LETTER SMALL X
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02E3 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02E3 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02E3 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0078 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0078 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_175)
{
    // 02E4;02E4;02E4;0295;0295;
    // (ˤ; ˤ; ˤ; ʕ; ʕ; ) MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
    {
        std::array<uint32_t, 1> const c1 = {{ 0x02E4 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02E4 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02E4 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0295 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0295 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_176)
{
    // 0340;0300;0300;0300;0300;
    // (◌̀; ◌̀; ◌̀; ◌̀; ◌̀; ) COMBINING GRAVE TONE MARK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0340 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0300 }};
        std::array<uint32_t, 1> const c3 = {{ 0x0300 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0300 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0300 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_177)
{
    // 0341;0301;0301;0301;0301;
    // (◌́; ◌́; ◌́; ◌́; ◌́; ) COMBINING ACUTE TONE MARK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0341 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0301 }};
        std::array<uint32_t, 1> const c3 = {{ 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0301 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_178)
{
    // 0343;0313;0313;0313;0313;
    // (◌̓; ◌̓; ◌̓; ◌̓; ◌̓; ) COMBINING GREEK KORONIS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0343 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0313 }};
        std::array<uint32_t, 1> const c3 = {{ 0x0313 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0313 }};
        std::array<uint32_t, 1> const c5 = {{ 0x0313 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_179)
{
    // 0344;0308 0301;0308 0301;0308 0301;0308 0301;
    // (◌̈́; ◌̈◌́; ◌̈◌́; ◌̈◌́; ◌̈◌́; ) COMBINING GREEK DIALYTIKA TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0344 }};
        std::array<uint32_t, 2> const c2 = {{ 0x0308, 0x0301 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0308, 0x0301 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0308, 0x0301 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0308, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_180)
{
    // 0374;02B9;02B9;02B9;02B9;
    // (ʹ; ʹ; ʹ; ʹ; ʹ; ) GREEK NUMERAL SIGN
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0374 }};
        std::array<uint32_t, 1> const c2 = {{ 0x02B9 }};
        std::array<uint32_t, 1> const c3 = {{ 0x02B9 }};
        std::array<uint32_t, 1> const c4 = {{ 0x02B9 }};
        std::array<uint32_t, 1> const c5 = {{ 0x02B9 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_181)
{
    // 037A;037A;037A;0020 0345;0020 0345;
    // (ͺ; ͺ; ͺ;  ◌ͅ;  ◌ͅ; ) GREEK YPOGEGRAMMENI
    {
        std::array<uint32_t, 1> const c1 = {{ 0x037A }};
        std::array<uint32_t, 1> const c2 = {{ 0x037A }};
        std::array<uint32_t, 1> const c3 = {{ 0x037A }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x0345 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x0345 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_182)
{
    // 037E;003B;003B;003B;003B;
    // (;; ;; ;; ;; ;; ) GREEK QUESTION MARK
    {
        std::array<uint32_t, 1> const c1 = {{ 0x037E }};
        std::array<uint32_t, 1> const c2 = {{ 0x003B }};
        std::array<uint32_t, 1> const c3 = {{ 0x003B }};
        std::array<uint32_t, 1> const c4 = {{ 0x003B }};
        std::array<uint32_t, 1> const c5 = {{ 0x003B }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_183)
{
    // 0384;0384;0384;0020 0301;0020 0301;
    // (΄; ΄; ΄;  ◌́;  ◌́; ) GREEK TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0384 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0384 }};
        std::array<uint32_t, 1> const c3 = {{ 0x0384 }};
        std::array<uint32_t, 2> const c4 = {{ 0x0020, 0x0301 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0020, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_184)
{
    // 0385;0385;00A8 0301;0020 0308 0301;0020 0308 0301;
    // (΅; ΅; ¨◌́;  ◌̈◌́;  ◌̈◌́; ) GREEK DIALYTIKA TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0385 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0385 }};
        std::array<uint32_t, 2> const c3 = {{ 0x00A8, 0x0301 }};
        std::array<uint32_t, 3> const c4 = {{ 0x0020, 0x0308, 0x0301 }};
        std::array<uint32_t, 3> const c5 = {{ 0x0020, 0x0308, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_185)
{
    // 0386;0386;0391 0301;0386;0391 0301;
    // (Ά; Ά; Α◌́; Ά; Α◌́; ) GREEK CAPITAL LETTER ALPHA WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0386 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0386 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0391, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0386 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0391, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_186)
{
    // 0387;00B7;00B7;00B7;00B7;
    // (·; ·; ·; ·; ·; ) GREEK ANO TELEIA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0387 }};
        std::array<uint32_t, 1> const c2 = {{ 0x00B7 }};
        std::array<uint32_t, 1> const c3 = {{ 0x00B7 }};
        std::array<uint32_t, 1> const c4 = {{ 0x00B7 }};
        std::array<uint32_t, 1> const c5 = {{ 0x00B7 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_187)
{
    // 0388;0388;0395 0301;0388;0395 0301;
    // (Έ; Έ; Ε◌́; Έ; Ε◌́; ) GREEK CAPITAL LETTER EPSILON WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0388 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0388 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0395, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0388 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0395, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_188)
{
    // 0389;0389;0397 0301;0389;0397 0301;
    // (Ή; Ή; Η◌́; Ή; Η◌́; ) GREEK CAPITAL LETTER ETA WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0389 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0389 }};
        std::array<uint32_t, 2> const c3 = {{ 0x0397, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0389 }};
        std::array<uint32_t, 2> const c5 = {{ 0x0397, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_189)
{
    // 038A;038A;0399 0301;038A;0399 0301;
    // (Ί; Ί; Ι◌́; Ί; Ι◌́; ) GREEK CAPITAL LETTER IOTA WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x038A }};
        std::array<uint32_t, 1> const c2 = {{ 0x038A }};
        std::array<uint32_t, 2> const c3 = {{ 0x0399, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x038A }};
        std::array<uint32_t, 2> const c5 = {{ 0x0399, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_190)
{
    // 038C;038C;039F 0301;038C;039F 0301;
    // (Ό; Ό; Ο◌́; Ό; Ο◌́; ) GREEK CAPITAL LETTER OMICRON WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x038C }};
        std::array<uint32_t, 1> const c2 = {{ 0x038C }};
        std::array<uint32_t, 2> const c3 = {{ 0x039F, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x038C }};
        std::array<uint32_t, 2> const c5 = {{ 0x039F, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_191)
{
    // 038E;038E;03A5 0301;038E;03A5 0301;
    // (Ύ; Ύ; Υ◌́; Ύ; Υ◌́; ) GREEK CAPITAL LETTER UPSILON WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x038E }};
        std::array<uint32_t, 1> const c2 = {{ 0x038E }};
        std::array<uint32_t, 2> const c3 = {{ 0x03A5, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x038E }};
        std::array<uint32_t, 2> const c5 = {{ 0x03A5, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_192)
{
    // 038F;038F;03A9 0301;038F;03A9 0301;
    // (Ώ; Ώ; Ω◌́; Ώ; Ω◌́; ) GREEK CAPITAL LETTER OMEGA WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x038F }};
        std::array<uint32_t, 1> const c2 = {{ 0x038F }};
        std::array<uint32_t, 2> const c3 = {{ 0x03A9, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x038F }};
        std::array<uint32_t, 2> const c5 = {{ 0x03A9, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_193)
{
    // 0390;0390;03B9 0308 0301;0390;03B9 0308 0301;
    // (ΐ; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x0390 }};
        std::array<uint32_t, 1> const c2 = {{ 0x0390 }};
        std::array<uint32_t, 3> const c3 = {{ 0x03B9, 0x0308, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x0390 }};
        std::array<uint32_t, 3> const c5 = {{ 0x03B9, 0x0308, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_194)
{
    // 03AA;03AA;0399 0308;03AA;0399 0308;
    // (Ϊ; Ϊ; Ι◌̈; Ϊ; Ι◌̈; ) GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x03AA }};
        std::array<uint32_t, 1> const c2 = {{ 0x03AA }};
        std::array<uint32_t, 2> const c3 = {{ 0x0399, 0x0308 }};
        std::array<uint32_t, 1> const c4 = {{ 0x03AA }};
        std::array<uint32_t, 2> const c5 = {{ 0x0399, 0x0308 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_195)
{
    // 03AB;03AB;03A5 0308;03AB;03A5 0308;
    // (Ϋ; Ϋ; Υ◌̈; Ϋ; Υ◌̈; ) GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
    {
        std::array<uint32_t, 1> const c1 = {{ 0x03AB }};
        std::array<uint32_t, 1> const c2 = {{ 0x03AB }};
        std::array<uint32_t, 2> const c3 = {{ 0x03A5, 0x0308 }};
        std::array<uint32_t, 1> const c4 = {{ 0x03AB }};
        std::array<uint32_t, 2> const c5 = {{ 0x03A5, 0x0308 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_196)
{
    // 03AC;03AC;03B1 0301;03AC;03B1 0301;
    // (ά; ά; α◌́; ά; α◌́; ) GREEK SMALL LETTER ALPHA WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x03AC }};
        std::array<uint32_t, 1> const c2 = {{ 0x03AC }};
        std::array<uint32_t, 2> const c3 = {{ 0x03B1, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x03AC }};
        std::array<uint32_t, 2> const c5 = {{ 0x03B1, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_197)
{
    // 03AD;03AD;03B5 0301;03AD;03B5 0301;
    // (έ; έ; ε◌́; έ; ε◌́; ) GREEK SMALL LETTER EPSILON WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x03AD }};
        std::array<uint32_t, 1> const c2 = {{ 0x03AD }};
        std::array<uint32_t, 2> const c3 = {{ 0x03B5, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x03AD }};
        std::array<uint32_t, 2> const c5 = {{ 0x03B5, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_198)
{
    // 03AE;03AE;03B7 0301;03AE;03B7 0301;
    // (ή; ή; η◌́; ή; η◌́; ) GREEK SMALL LETTER ETA WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x03AE }};
        std::array<uint32_t, 1> const c2 = {{ 0x03AE }};
        std::array<uint32_t, 2> const c3 = {{ 0x03B7, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x03AE }};
        std::array<uint32_t, 2> const c5 = {{ 0x03B7, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

TEST(normalization, nfkc_001_199)
{
    // 03AF;03AF;03B9 0301;03AF;03B9 0301;
    // (ί; ί; ι◌́; ί; ι◌́; ) GREEK SMALL LETTER IOTA WITH TONOS
    {
        std::array<uint32_t, 1> const c1 = {{ 0x03AF }};
        std::array<uint32_t, 1> const c2 = {{ 0x03AF }};
        std::array<uint32_t, 2> const c3 = {{ 0x03B9, 0x0301 }};
        std::array<uint32_t, 1> const c4 = {{ 0x03AF }};
        std::array<uint32_t, 2> const c5 = {{ 0x03B9, 0x0301 }};

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c2.begin(), c2.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c2.begin(), c2.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c3.begin(), c3.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c3.begin(), c3.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::c>(c4.begin(), c4.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kc>(c4.begin(), c4.end()));

        EXPECT_TRUE(boost::text::normalized<boost::text::nf::d>(c5.begin(), c5.end()));
        EXPECT_TRUE(boost::text::normalized<boost::text::nf::kd>(c5.begin(), c5.end()));

        {
            std::string str = boost::text::to_string(c1.begin(), c1.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c2.begin(), c2.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c3.begin(), c3.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c4.begin(), c4.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

        {
            std::string str = boost::text::to_string(c5.begin(), c5.end());
            boost::text::normalize<boost::text::nf::kc>(str);
            auto const r = boost::text::as_utf32(str);
            EXPECT_EQ(std::distance(r.begin(), r.end()), (std::ptrdiff_t)c4.size());
            auto c4_it = c4.begin();
            int i = 0;
            for (auto x : r) {
                EXPECT_EQ(x, *c4_it) << "iteration " << i;
                ++c4_it;
                ++i;
            }
        }

    }
}

max_stars_repo_name: Ryan-rsm-McKenzie/text

max_issues_repo_name: Ryan-rsm-McKenzie/text

max_forks_repo_name: Ryan-rsm-McKenzie/text