static bool write_structs()

in cppwinrt/code_writers.h [2669:2786]


    static bool write_structs(writer& w, std::vector<TypeDef> const& types)
    {
        auto format = R"(    struct %
    {
%    };
    inline bool operator==(% const& left, % const& right)%
    {
        return%;
    }
    inline bool operator!=(% const& left, % const& right)%
    {
        return !(left == right);
    }
)";

        if (types.empty())
        {
            return false;
        }

        struct complex_struct
        {
            complex_struct(writer& w, TypeDef const& type) :
                type(type),
                is_noexcept(!has_reference(type))
            {
                for (auto&& field : type.FieldList())
                {
                    fields.emplace_back(field.Name(), w.write_temp("%", field.Signature().Type()));
                }
            }

            static bool has_reference(TypeDef const&)
            {
                return false;
            };

            TypeDef type;
            std::vector<std::pair<std::string_view, std::string>> fields;
            bool is_noexcept{ false };
        };

        std::vector<complex_struct> structs;
        structs.reserve(types.size());

        for (auto&& type : types)
        {
            structs.emplace_back(w, type);
        }

        auto depends = [](writer& w, complex_struct const& left, complex_struct const& right)
        {
            auto right_type = w.write_temp("%", right.type);
            std::string right_as_ref = std::string("winrt::Windows::Foundation::IReference<") + right_type + ">";
            for (auto&& field : left.fields)
            {
                if (right_type == field.second || right_as_ref == field.second)
                {
                    return true;
                }
            }

            return false;
        };

        for (size_t left = 0; left < structs.size(); ++left)
        {
            for (size_t right = left + 1; right < structs.size(); ++right)
            {
                if (depends(w, structs[left], structs[right]))
                {
                    // Left depends on right, therefore move right in front of left.
                    complex_struct temp = std::move(structs[right]);
                    structs.erase(structs.begin() + right);
                    structs.insert(structs.begin() + left, std::move(temp));

                    // Start over from the newly inserted struct.
                    right = structs.size();
                    --left;
                }
            }
        }

        bool promote = false;
        auto cpp_namespace = w.write_temp("@", w.type_namespace);

        for (auto&& type : structs)
        {
            auto name = type.type.TypeName();
            std::string_view is_noexcept = type.is_noexcept ? " noexcept" : "";

            w.write(format,
                name,
                bind_each<write_struct_field>(type.fields),
                name,
                name,
                is_noexcept,
                bind<write_struct_equality>(type.fields),
                name,
                name,
                is_noexcept);

            for (auto&& field : type.fields)
            {
                if (field.second.find(':') == std::string::npos)
                {
                    continue;
                }

                if (!starts_with(field.second, cpp_namespace))
                {
                    promote = true;
                }
            }
        }

        return promote;
    }