17db96d56Sopenharmony_ci/* Boolean type, a subtype of int */
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci#include "Python.h"
47db96d56Sopenharmony_ci#include "pycore_object.h"      // _Py_FatalRefcountError()
57db96d56Sopenharmony_ci#include "pycore_runtime.h"       // _Py_ID()
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci/* We define bool_repr to return "False" or "True" */
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_cistatic PyObject *
107db96d56Sopenharmony_cibool_repr(PyObject *self)
117db96d56Sopenharmony_ci{
127db96d56Sopenharmony_ci    PyObject *res = self == Py_True ? &_Py_ID(True) : &_Py_ID(False);
137db96d56Sopenharmony_ci    return Py_NewRef(res);
147db96d56Sopenharmony_ci}
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci/* Function to return a bool from a C long */
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ciPyObject *PyBool_FromLong(long ok)
197db96d56Sopenharmony_ci{
207db96d56Sopenharmony_ci    PyObject *result;
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ci    if (ok)
237db96d56Sopenharmony_ci        result = Py_True;
247db96d56Sopenharmony_ci    else
257db96d56Sopenharmony_ci        result = Py_False;
267db96d56Sopenharmony_ci    Py_INCREF(result);
277db96d56Sopenharmony_ci    return result;
287db96d56Sopenharmony_ci}
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci/* We define bool_new to always return either Py_True or Py_False */
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_cistatic PyObject *
337db96d56Sopenharmony_cibool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
347db96d56Sopenharmony_ci{
357db96d56Sopenharmony_ci    PyObject *x = Py_False;
367db96d56Sopenharmony_ci    long ok;
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_ci    if (!_PyArg_NoKeywords("bool", kwds))
397db96d56Sopenharmony_ci        return NULL;
407db96d56Sopenharmony_ci    if (!PyArg_UnpackTuple(args, "bool", 0, 1, &x))
417db96d56Sopenharmony_ci        return NULL;
427db96d56Sopenharmony_ci    ok = PyObject_IsTrue(x);
437db96d56Sopenharmony_ci    if (ok < 0)
447db96d56Sopenharmony_ci        return NULL;
457db96d56Sopenharmony_ci    return PyBool_FromLong(ok);
467db96d56Sopenharmony_ci}
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_cistatic PyObject *
497db96d56Sopenharmony_cibool_vectorcall(PyObject *type, PyObject * const*args,
507db96d56Sopenharmony_ci                size_t nargsf, PyObject *kwnames)
517db96d56Sopenharmony_ci{
527db96d56Sopenharmony_ci    long ok = 0;
537db96d56Sopenharmony_ci    if (!_PyArg_NoKwnames("bool", kwnames)) {
547db96d56Sopenharmony_ci        return NULL;
557db96d56Sopenharmony_ci    }
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
587db96d56Sopenharmony_ci    if (!_PyArg_CheckPositional("bool", nargs, 0, 1)) {
597db96d56Sopenharmony_ci        return NULL;
607db96d56Sopenharmony_ci    }
617db96d56Sopenharmony_ci
627db96d56Sopenharmony_ci    assert(PyType_Check(type));
637db96d56Sopenharmony_ci    if (nargs) {
647db96d56Sopenharmony_ci        ok = PyObject_IsTrue(args[0]);
657db96d56Sopenharmony_ci        if (ok < 0) {
667db96d56Sopenharmony_ci            return NULL;
677db96d56Sopenharmony_ci        }
687db96d56Sopenharmony_ci    }
697db96d56Sopenharmony_ci    return PyBool_FromLong(ok);
707db96d56Sopenharmony_ci}
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci/* Arithmetic operations redefined to return bool if both args are bool. */
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_cistatic PyObject *
757db96d56Sopenharmony_cibool_and(PyObject *a, PyObject *b)
767db96d56Sopenharmony_ci{
777db96d56Sopenharmony_ci    if (!PyBool_Check(a) || !PyBool_Check(b))
787db96d56Sopenharmony_ci        return PyLong_Type.tp_as_number->nb_and(a, b);
797db96d56Sopenharmony_ci    return PyBool_FromLong((a == Py_True) & (b == Py_True));
807db96d56Sopenharmony_ci}
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_cistatic PyObject *
837db96d56Sopenharmony_cibool_or(PyObject *a, PyObject *b)
847db96d56Sopenharmony_ci{
857db96d56Sopenharmony_ci    if (!PyBool_Check(a) || !PyBool_Check(b))
867db96d56Sopenharmony_ci        return PyLong_Type.tp_as_number->nb_or(a, b);
877db96d56Sopenharmony_ci    return PyBool_FromLong((a == Py_True) | (b == Py_True));
887db96d56Sopenharmony_ci}
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_cistatic PyObject *
917db96d56Sopenharmony_cibool_xor(PyObject *a, PyObject *b)
927db96d56Sopenharmony_ci{
937db96d56Sopenharmony_ci    if (!PyBool_Check(a) || !PyBool_Check(b))
947db96d56Sopenharmony_ci        return PyLong_Type.tp_as_number->nb_xor(a, b);
957db96d56Sopenharmony_ci    return PyBool_FromLong((a == Py_True) ^ (b == Py_True));
967db96d56Sopenharmony_ci}
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci/* Doc string */
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ciPyDoc_STRVAR(bool_doc,
1017db96d56Sopenharmony_ci"bool(x) -> bool\n\
1027db96d56Sopenharmony_ci\n\
1037db96d56Sopenharmony_ciReturns True when the argument x is true, False otherwise.\n\
1047db96d56Sopenharmony_ciThe builtins True and False are the only two instances of the class bool.\n\
1057db96d56Sopenharmony_ciThe class bool is a subclass of the class int, and cannot be subclassed.");
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci/* Arithmetic methods -- only so we can override &, |, ^. */
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_cistatic PyNumberMethods bool_as_number = {
1107db96d56Sopenharmony_ci    0,                          /* nb_add */
1117db96d56Sopenharmony_ci    0,                          /* nb_subtract */
1127db96d56Sopenharmony_ci    0,                          /* nb_multiply */
1137db96d56Sopenharmony_ci    0,                          /* nb_remainder */
1147db96d56Sopenharmony_ci    0,                          /* nb_divmod */
1157db96d56Sopenharmony_ci    0,                          /* nb_power */
1167db96d56Sopenharmony_ci    0,                          /* nb_negative */
1177db96d56Sopenharmony_ci    0,                          /* nb_positive */
1187db96d56Sopenharmony_ci    0,                          /* nb_absolute */
1197db96d56Sopenharmony_ci    0,                          /* nb_bool */
1207db96d56Sopenharmony_ci    0,                          /* nb_invert */
1217db96d56Sopenharmony_ci    0,                          /* nb_lshift */
1227db96d56Sopenharmony_ci    0,                          /* nb_rshift */
1237db96d56Sopenharmony_ci    bool_and,                   /* nb_and */
1247db96d56Sopenharmony_ci    bool_xor,                   /* nb_xor */
1257db96d56Sopenharmony_ci    bool_or,                    /* nb_or */
1267db96d56Sopenharmony_ci    0,                          /* nb_int */
1277db96d56Sopenharmony_ci    0,                          /* nb_reserved */
1287db96d56Sopenharmony_ci    0,                          /* nb_float */
1297db96d56Sopenharmony_ci    0,                          /* nb_inplace_add */
1307db96d56Sopenharmony_ci    0,                          /* nb_inplace_subtract */
1317db96d56Sopenharmony_ci    0,                          /* nb_inplace_multiply */
1327db96d56Sopenharmony_ci    0,                          /* nb_inplace_remainder */
1337db96d56Sopenharmony_ci    0,                          /* nb_inplace_power */
1347db96d56Sopenharmony_ci    0,                          /* nb_inplace_lshift */
1357db96d56Sopenharmony_ci    0,                          /* nb_inplace_rshift */
1367db96d56Sopenharmony_ci    0,                          /* nb_inplace_and */
1377db96d56Sopenharmony_ci    0,                          /* nb_inplace_xor */
1387db96d56Sopenharmony_ci    0,                          /* nb_inplace_or */
1397db96d56Sopenharmony_ci    0,                          /* nb_floor_divide */
1407db96d56Sopenharmony_ci    0,                          /* nb_true_divide */
1417db96d56Sopenharmony_ci    0,                          /* nb_inplace_floor_divide */
1427db96d56Sopenharmony_ci    0,                          /* nb_inplace_true_divide */
1437db96d56Sopenharmony_ci    0,                          /* nb_index */
1447db96d56Sopenharmony_ci};
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_cistatic void _Py_NO_RETURN
1477db96d56Sopenharmony_cibool_dealloc(PyObject* Py_UNUSED(ignore))
1487db96d56Sopenharmony_ci{
1497db96d56Sopenharmony_ci    _Py_FatalRefcountError("deallocating True or False");
1507db96d56Sopenharmony_ci}
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci/* The type object for bool.  Note that this cannot be subclassed! */
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ciPyTypeObject PyBool_Type = {
1557db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyType_Type, 0)
1567db96d56Sopenharmony_ci    "bool",
1577db96d56Sopenharmony_ci    sizeof(struct _longobject),
1587db96d56Sopenharmony_ci    0,
1597db96d56Sopenharmony_ci    bool_dealloc,                               /* tp_dealloc */
1607db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
1617db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
1627db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
1637db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
1647db96d56Sopenharmony_ci    bool_repr,                                  /* tp_repr */
1657db96d56Sopenharmony_ci    &bool_as_number,                            /* tp_as_number */
1667db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
1677db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
1687db96d56Sopenharmony_ci    0,                                          /* tp_hash */
1697db96d56Sopenharmony_ci    0,                                          /* tp_call */
1707db96d56Sopenharmony_ci    0,                                          /* tp_str */
1717db96d56Sopenharmony_ci    0,                                          /* tp_getattro */
1727db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
1737db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
1747db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
1757db96d56Sopenharmony_ci    bool_doc,                                   /* tp_doc */
1767db96d56Sopenharmony_ci    0,                                          /* tp_traverse */
1777db96d56Sopenharmony_ci    0,                                          /* tp_clear */
1787db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
1797db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
1807db96d56Sopenharmony_ci    0,                                          /* tp_iter */
1817db96d56Sopenharmony_ci    0,                                          /* tp_iternext */
1827db96d56Sopenharmony_ci    0,                                          /* tp_methods */
1837db96d56Sopenharmony_ci    0,                                          /* tp_members */
1847db96d56Sopenharmony_ci    0,                                          /* tp_getset */
1857db96d56Sopenharmony_ci    &PyLong_Type,                               /* tp_base */
1867db96d56Sopenharmony_ci    0,                                          /* tp_dict */
1877db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
1887db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
1897db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
1907db96d56Sopenharmony_ci    0,                                          /* tp_init */
1917db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
1927db96d56Sopenharmony_ci    bool_new,                                   /* tp_new */
1937db96d56Sopenharmony_ci    .tp_vectorcall = bool_vectorcall,
1947db96d56Sopenharmony_ci};
1957db96d56Sopenharmony_ci
1967db96d56Sopenharmony_ci/* The objects representing bool values False and True */
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_cistruct _longobject _Py_FalseStruct = {
1997db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyBool_Type, 0)
2007db96d56Sopenharmony_ci    { 0 }
2017db96d56Sopenharmony_ci};
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_cistruct _longobject _Py_TrueStruct = {
2047db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(&PyBool_Type, 1)
2057db96d56Sopenharmony_ci    { 1 }
2067db96d56Sopenharmony_ci};
207