mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
interrogate: Support three-way comparison operator <=>
This commit is contained in:
parent
684992cf8f
commit
f6b1b6dbb0
@ -738,6 +738,11 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||||||
_void_return = true;
|
_void_return = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (fname == "operator <=>") {
|
||||||
|
// This returns an opaque object that we must leave unchanged.
|
||||||
|
_return_type = new ParameterRemapUnchanged(rtype);
|
||||||
|
_void_return = false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// The normal case.
|
// The normal case.
|
||||||
_return_type = interface_maker->remap_parameter(_cpptype, rtype);
|
_return_type = interface_maker->remap_parameter(_cpptype, rtype);
|
||||||
|
@ -70,6 +70,7 @@ RenameSet methodRenameDictionary[] = {
|
|||||||
{ "operator >" , "__gt__", 0 },
|
{ "operator >" , "__gt__", 0 },
|
||||||
{ "operator <=" , "__le__", 0 },
|
{ "operator <=" , "__le__", 0 },
|
||||||
{ "operator >=" , "__ge__", 0 },
|
{ "operator >=" , "__ge__", 0 },
|
||||||
|
{ "operator <=>" , "__cmp__", 0 },
|
||||||
{ "operator =" , "assign", 0 },
|
{ "operator =" , "assign", 0 },
|
||||||
{ "operator ()" , "__call__", 0 },
|
{ "operator ()" , "__call__", 0 },
|
||||||
{ "operator []" , "__getitem__", 0 },
|
{ "operator []" , "__getitem__", 0 },
|
||||||
@ -1753,7 +1754,8 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
fname == "operator ==" ||
|
fname == "operator ==" ||
|
||||||
fname == "operator !=" ||
|
fname == "operator !=" ||
|
||||||
fname == "operator >" ||
|
fname == "operator >" ||
|
||||||
fname == "operator >=") {
|
fname == "operator >=" ||
|
||||||
|
fname == "operator <=>") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2620,6 +2622,7 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
out << " return nullptr;\n";
|
out << " return nullptr;\n";
|
||||||
out << " }\n\n";
|
out << " }\n\n";
|
||||||
|
|
||||||
|
std::set<FunctionRemap *> threeway_remaps;
|
||||||
bool have_eq = false;
|
bool have_eq = false;
|
||||||
bool have_ne = false;
|
bool have_ne = false;
|
||||||
for (Function *func : obj->_methods) {
|
for (Function *func : obj->_methods) {
|
||||||
@ -2650,6 +2653,9 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
op_type = "Py_GT";
|
op_type = "Py_GT";
|
||||||
} else if (fname == "operator >=") {
|
} else if (fname == "operator >=") {
|
||||||
op_type = "Py_GE";
|
op_type = "Py_GE";
|
||||||
|
} else if (fname == "operator <=>") {
|
||||||
|
threeway_remaps = std::move(remaps);
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2670,7 +2676,15 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_local_richcompare) {
|
if (has_local_richcompare) {
|
||||||
if (have_eq && !have_ne) {
|
if (!threeway_remaps.empty()) {
|
||||||
|
out << " default:\n";
|
||||||
|
out << " {\n";
|
||||||
|
string expected_params;
|
||||||
|
write_function_forset(out, threeway_remaps, 1, 1, expected_params, 6, true, false,
|
||||||
|
AT_single_arg, RF_richcompare_zero | RF_err_null, false);
|
||||||
|
out << " }\n";
|
||||||
|
}
|
||||||
|
else if (have_eq && !have_ne) {
|
||||||
// Generate a not-equal function from the equal function.
|
// Generate a not-equal function from the equal function.
|
||||||
for (Function *func : obj->_methods) {
|
for (Function *func : obj->_methods) {
|
||||||
std::set<FunctionRemap*> remaps;
|
std::set<FunctionRemap*> remaps;
|
||||||
@ -2713,8 +2727,13 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
out << " PyErr_Clear();\n";
|
out << " PyErr_Clear();\n";
|
||||||
out << " }\n\n";
|
out << " }\n\n";
|
||||||
}
|
}
|
||||||
|
else if (!threeway_remaps.empty()) {
|
||||||
|
string expected_params;
|
||||||
|
write_function_forset(out, threeway_remaps, 1, 1, expected_params, 2, true, false,
|
||||||
|
AT_single_arg, RF_richcompare_zero | RF_err_null, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (slots.count("tp_compare")) {
|
if (slots.count("tp_compare") && threeway_remaps.empty()) {
|
||||||
// A lot of Panda code depends on comparisons being done via the
|
// A lot of Panda code depends on comparisons being done via the
|
||||||
// compare_to function, which is mapped to the tp_compare slot, which
|
// compare_to function, which is mapped to the tp_compare slot, which
|
||||||
// Python 3 no longer has. So, we'll write code to fall back to that if
|
// Python 3 no longer has. So, we'll write code to fall back to that if
|
||||||
@ -3536,7 +3555,8 @@ write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker
|
|||||||
fname == "operator ==" ||
|
fname == "operator ==" ||
|
||||||
fname == "operator !=" ||
|
fname == "operator !=" ||
|
||||||
fname == "operator >" ||
|
fname == "operator >" ||
|
||||||
fname == "operator >=") {
|
fname == "operator >=" ||
|
||||||
|
fname == "operator <=>") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6153,7 +6173,8 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||||||
// function call, so it should reduce the amount of code output while not
|
// function call, so it should reduce the amount of code output while not
|
||||||
// being any slower.
|
// being any slower.
|
||||||
bool return_null = (return_flags & RF_pyobject) != 0 &&
|
bool return_null = (return_flags & RF_pyobject) != 0 &&
|
||||||
(return_flags & RF_err_null) != 0;
|
(return_flags & RF_err_null) != 0 &&
|
||||||
|
(return_flags & RF_richcompare_zero) == 0;
|
||||||
if (return_null && return_expr.empty()) {
|
if (return_null && return_expr.empty()) {
|
||||||
indent(out, indent_level)
|
indent(out, indent_level)
|
||||||
<< "return Dtool_Return_None();\n";
|
<< "return Dtool_Return_None();\n";
|
||||||
@ -6306,6 +6327,10 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||||||
indent(out, indent_level) << "Py_INCREF(self);\n";
|
indent(out, indent_level) << "Py_INCREF(self);\n";
|
||||||
indent(out, indent_level) << "return self;\n";
|
indent(out, indent_level) << "return self;\n";
|
||||||
|
|
||||||
|
} else if (return_flags & RF_richcompare_zero) {
|
||||||
|
indent(out, indent_level)
|
||||||
|
<< "Py_RETURN_RICHCOMPARE(" << return_expr << ", 0, op);\n";
|
||||||
|
|
||||||
} else if (return_flags & RF_pyobject) {
|
} else if (return_flags & RF_pyobject) {
|
||||||
if (return_expr.empty()) {
|
if (return_expr.empty()) {
|
||||||
indent(out, indent_level) << "Py_INCREF(Py_None);\n";
|
indent(out, indent_level) << "Py_INCREF(Py_None);\n";
|
||||||
@ -7650,7 +7675,11 @@ is_remap_legal(FunctionRemap *remap) {
|
|||||||
if (!is_cpp_type_legal(remap->_return_type->get_orig_type())) {
|
if (!is_cpp_type_legal(remap->_return_type->get_orig_type())) {
|
||||||
// printf(" is_remap_legal Return Is Bad %s\n",remap->_return_type->get_orig_
|
// printf(" is_remap_legal Return Is Bad %s\n",remap->_return_type->get_orig_
|
||||||
// type()->get_fully_scoped_name().c_str());
|
// type()->get_fully_scoped_name().c_str());
|
||||||
return false;
|
// Except if this is a spaceship operator, since we have special handling
|
||||||
|
// for its return type.
|
||||||
|
if (remap->_cppfunc->get_simple_name() != "operator <=>") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't currently support returning pointers, but we accept them as
|
// We don't currently support returning pointers, but we accept them as
|
||||||
@ -8109,6 +8138,17 @@ NeedsARichCompareFunction(const InterrogateType &itype_class) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (itype_class._cpptype != nullptr) {
|
||||||
|
CPPStructType *struct_type = itype_class._cpptype->as_struct_type();
|
||||||
|
if (struct_type != nullptr) {
|
||||||
|
CPPScope *scope = struct_type->get_scope();
|
||||||
|
CPPScope::Functions::const_iterator it = scope->_functions.find("operator <=>");
|
||||||
|
if (it != scope->_functions.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +118,9 @@ private:
|
|||||||
|
|
||||||
// Invert boolean return value.
|
// Invert boolean return value.
|
||||||
RF_invert_bool = 0x8000,
|
RF_invert_bool = 0x8000,
|
||||||
|
|
||||||
|
// Used inside a rich comparison function.
|
||||||
|
RF_richcompare_zero = 0x10000,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SlottedFunctionDef {
|
class SlottedFunctionDef {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user