{#-  Copyright 2026, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file -#}

static {{ target.getTypeDecl() }} COMPARE_{{op_code}}_{{target.getHelperCodeName()}}_{{left.getHelperCodeName()}}_{{right.getHelperCodeName()}}({{left.getVariableDecl("operand1")}}, {{right.getVariableDecl("operand2")}}) {
    {{left.getCheckValueCode("operand1")}}
    {{right.getCheckValueCode("operand2")}}

    {# TODO: Unify with tuple, seems the iteration part is only difference #}
    PyListObject *a = (PyListObject *)operand1;
    PyListObject *b = (PyListObject *)operand2;

{# Shortcut for equality, driven by length check. #}
{% if operator in ("==", "!=") %}
    if (Py_SIZE(a) != Py_SIZE(b)) {
{% if operator == "==" %}
        bool r = false;
{% else %}
        bool r = true;
{% endif %}

        // Convert to target type.
        {{ target.getTypeDecl() }} result = {{target.getToValueFromBoolExpression("r")}};
        {{ target.getTakeReferenceStatement("result", immortal=True) }}
        return result;
    }
{% endif %}

{# Find the first non-identical object. #}
{% if operator not in ("==", "!=") %}
    bool found = false;
{% endif %}
    nuitka_bool res = NUITKA_BOOL_TRUE;

    Py_ssize_t i;
    for (i = 0; i < Py_SIZE(a) && i < Py_SIZE(b); i++) {
        PyObject *aa = a->ob_item[i];
        PyObject *bb = b->ob_item[i];

        if (aa == bb) {
            continue;
        }

        Py_INCREF(aa);
        Py_INCREF(bb);
        res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(aa, bb);
        Py_DECREF(aa);
        Py_DECREF(bb);

        if (res == NUITKA_BOOL_EXCEPTION) {
            return {{target.getExceptionResultIndicatorValue()}};
        }

        if (res == NUITKA_BOOL_FALSE) {
{% if operator not in ("==", "!=") %}
            found = true;
{% endif %}
            break;
        }
    }

{# If size mismatches, but all is equal at the start, compare sizes to order lists. #}
{% if operator not in ("==", "!=") %}
    if (found == false) {
        bool r = Py_SIZE(a) {{operator}} Py_SIZE(b);

        // Convert to target type.
        {{ target.getTypeDecl() }} result = {{target.getToValueFromBoolExpression("r")}};
        {{ target.getTakeReferenceStatement("result", immortal=True) }}
        return result;
    }

    return RICH_COMPARE_{{op_code}}_{{target.getHelperCodeName()}}_OBJECT_OBJECT(a->ob_item[i], b->ob_item[i]);
{% else %}
{% if operator == "==" %}
    bool r;
    if (i >= Py_SIZE(a) || i >= Py_SIZE(b)) {
        r = Py_SIZE(a) {{operator}} Py_SIZE(b);
    } else {
        r = res == NUITKA_BOOL_TRUE;
    }
{% else %}
    bool r;

    if (i >= Py_SIZE(a) || i >= Py_SIZE(b)) {
        r = Py_SIZE(a) {{operator}} Py_SIZE(b);
    } else {
        r = res == NUITKA_BOOL_FALSE;
    }
{% endif %}

    // Convert to target type.
    {{ target.getTypeDecl() }} result = {{target.getToValueFromBoolExpression("r")}};
    {{ target.getTakeReferenceStatement("result", immortal=True) }}
    return result;

{% endif %}

}

{#-  Part of "Nuitka", an optimizing Python compiler that is compatible and           -#}
{#-  integrates with CPython, but also works on its own.                              -#}
{#-                                                                                   -#}
{#-  Licensed under the GNU Affero General Public License, Version 3 (the "License"); -#}
{#-  you may not use this file except in compliance with the License.                 -#}
{#-  You may obtain a copy of the License at                                          -#}
{#-                                                                                   -#}
{#-  https://www.gnu.org/licenses/agpl-3.0.txt                                        -#}
{#-                                                                                   -#}
{#-  See also: "Nuitka Runtime Library Exception, Version 1.0" in file                -#}
{#-  "LICENSE-RUNTIME.txt" for additional permissions granted under Section 7.        -#}
{#-                                                                                   -#}
{#-  Unless required by applicable law or agreed to in writing, software              -#}
{#-  distributed under the License is distributed on an "AS IS" BASIS,                -#}
{#-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.         -#}
{#-  See the License for the specific language governing permissions and              -#}
{#-  limitations under the License.                                                   -#}
