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