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

{% set props = {"exits": {}} %}
{% from 'HelperSlotsInt.c.j2' import int_core with context %}
{% set bool_mode = target and target.type_name in ("nuitka_bool", "nbool") %}
bool BINARY_OPERATION_{{op_code}}_{{target.getHelperCodeName()}}_{{left.getHelperCodeName()}}_{{right.getHelperCodeName()}}({{ target.getVariableDecl("result") }}, {{left.getVariableDecl("operand1")}}, {{right.getVariableDecl("operand2")}}) {
    {{ left.getCheckValueCode("operand1") }}
    {{ right.getCheckValueCode("operand2") }}

    bool left_c_usable = {{left.getDualValidityCheckCode("C", "operand1")}};
    bool right_c_usable = {{right.getDualValidityCheckCode("C", "operand2")}};

    if (left_c_usable && right_c_usable) {
{% if target.isSimilarOrSameTypesAsOneOf(n_ilong_desc) %}
    // Not every code path will make use of all possible results.
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4101)
#endif
        NUITKA_MAY_BE_UNUSED bool cbool_result;
        NUITKA_MAY_BE_UNUSED PyObject *obj_result;
        NUITKA_MAY_BE_UNUSED long clong_result;
        NUITKA_MAY_BE_UNUSED double cfloat_result;
#if defined(_MSC_VER)
#pragma warning(pop)
#endif

        {{int_core(props, operator, nb_slot, bool_mode, left, right, result, "operand1", "operand2", "exit_result_ok", "exit_result_exception", "exit_result_ok_cbool", "exit_result_ok_clong", "exit_result_ok_cfloat", "exit_result_object", "exit_result_ok_left", "exit_result_ok_const_int_0", "exit_result_ok_const_int_neg_1", "exit_result_ok_const_float_0_0", "exit_result_ok_const_float_minus_0_0")}}

{% if props["fall_through_needed"] %}
{% if left.isDualType() %}
        {{left.getDualTypeEnsurePythonObjectCode("operand1")}}
        obj_result = BINARY_OPERATION_{{op_code}}_OBJECT_{{left.getDualType("Python").getHelperCodeName()}}_{{right.getDualType("C").getHelperCodeName()}}({{left.getDualTypeAccessCode("Python", "operand1")}}, {{right.getDualTypeAccessCode("C", "operand2")}});
{% else %}
        {{right.getDualTypeEnsurePythonObjectCode("operand2")}}
        obj_result = BINARY_OPERATION_{{op_code}}_OBJECT_{{left.getDualType("C").getHelperCodeName()}}_{{right.getDualType("Python").getHelperCodeName()}}({{left.getDualTypeAccessCode("C", "operand1")}}, {{right.getDualTypeAccessCode("Python", "operand2")}});
{% endif %}

        if (unlikely(result == NULL)) {
            return false;
        }

        {{ target.getAssignFromObjectExpressionCode("result", "obj_result") }}
        return true;

{% else %}
        {{ 0/0 }}
{% endif %}
{% endif %}

{% if "exit_result_ok_clong" in props["exits"] %}
exit_result_ok_clong:
        {{target.getAssignFromLongExpressionCode("result", "clong_result")}}
        return true;
{% endif %}

{% if left.isDualType() %}
    } else if (left_c_usable == false && right_c_usable) {
        PyObject *python_result = BINARY_OPERATION_{{op_code}}_OBJECT_{{left.getDualType("Python").getHelperCodeName()}}_{{right.getDualType("C").getHelperCodeName()}}({{left.getDualTypeAccessCode("Python", "operand1")}}, {{right.getDualTypeAccessCode("C", "operand2")}});

        if (unlikely(python_result == NULL)) {
            return false;
        }

        {{ target.getSetDualValueCode("Python", "result", "python_result") }}
        return true;
{% endif %}
{% if right.isDualType() %}
    } else if (left_c_usable && right_c_usable == false) {
{% if left.isCommutativeType() and right.isCommutativeType() and isCommutativeOperation(op_code) %}
        PyObject *python_result = BINARY_OPERATION_{{op_code}}_OBJECT_{{right.getDualType("Python").getHelperCodeName()}}_{{left.getDualType("C").getHelperCodeName()}}({{right.getDualTypeAccessCode("Python", "operand2")}}, {{left.getDualTypeAccessCode("C", "operand1")}});
{% else %}
        PyObject *python_result = BINARY_OPERATION_{{op_code}}_OBJECT_{{left.getDualType("C").getHelperCodeName()}}_{{right.getDualType("Python").getHelperCodeName()}}({{left.getDualTypeAccessCode("C", "operand1")}}, {{right.getDualTypeAccessCode("Python", "operand2")}});
{% endif %}

        if (unlikely(python_result == NULL)) {
            return false;
        }

        {{ target.getSetDualValueCode("Python", "result", "python_result") }}

        return true;
{% endif %}
    } else {
{% if left.isDualType() and right.isDualType() %}
        PyObject *python_result = BINARY_OPERATION_{{op_code}}_OBJECT_{{left.getDualType("Python").getHelperCodeName()}}_{{right.getDualType("Python").getHelperCodeName()}}({{left.getDualTypeAccessCode("Python", "operand1")}}, {{right.getDualTypeAccessCode("Python", "operand1")}});

        if (unlikely(python_result == NULL)) {
            return false;
        }

        {{ target.getSetDualValueCode("Python", "result", "python_result") }}

        return true;
{% else %}
        NUITKA_CANNOT_GET_HERE("cannot happen with types {{left.getHelperCodeName()}} {{right.getHelperCodeName()}}");
        return false;
{% 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.                                                   -#}
