mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
interrogate: simplify coercion code
This remove support for coercing non-ReferenceCounted types that are neither default-constructible nor move-assignable, but it turns out none of the classes we really need it for matches that. It further cuts down on the amount of code that is being generated to support coercion in cases where it makes absolutely no sense.
This commit is contained in:
parent
dd2806c8bd
commit
483a491ed7
@ -131,6 +131,14 @@ is_copy_constructible() const {
|
||||
return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-assignable.
|
||||
*/
|
||||
bool CPPExtensionType::
|
||||
is_copy_assignable() const {
|
||||
return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_copy_assignable() const;
|
||||
|
||||
virtual CPPDeclaration *substitute_decl(SubstDecl &subst,
|
||||
CPPScope *current_scope,
|
||||
|
@ -43,6 +43,8 @@ public:
|
||||
F_volatile_method = 0x4000,
|
||||
F_lvalue_method = 0x8000,
|
||||
F_rvalue_method = 0x10000,
|
||||
F_copy_assignment_operator = 0x20000,
|
||||
F_move_assignment_operator = 0x40000,
|
||||
};
|
||||
|
||||
CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
|
||||
|
@ -328,8 +328,8 @@ get_fully_scoped_name() const {
|
||||
|
||||
/**
|
||||
* If this is a function type instance, checks whether the function name
|
||||
* matches the class name (or ~name), and if so, flags it as a constructor (or
|
||||
* destructor).
|
||||
* matches the class name (or ~name), and if so, flags it as a constructor,
|
||||
* destructor or assignment operator
|
||||
*/
|
||||
void CPPInstance::
|
||||
check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
|
||||
@ -344,13 +344,16 @@ check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
|
||||
string class_name = scope->get_local_name();
|
||||
|
||||
if (!method_name.empty() && !class_name.empty()) {
|
||||
if (method_name == class_name) {
|
||||
// Check either a constructor or assignment operator.
|
||||
if (method_name == class_name || method_name == "operator =") {
|
||||
CPPType *void_type = CPPType::new_type
|
||||
(new CPPSimpleType(CPPSimpleType::T_void));
|
||||
|
||||
int flags = func->_flags | CPPFunctionType::F_constructor;
|
||||
int flags = func->_flags;
|
||||
if (method_name == class_name) {
|
||||
flags |= CPPFunctionType::F_constructor;
|
||||
}
|
||||
|
||||
// Check if it might be a copy or move constructor.
|
||||
CPPParameterList *params = func->_parameters;
|
||||
if (params->_parameters.size() == 1 && !params->_includes_ellipsis) {
|
||||
CPPType *param_type = params->_parameters[0]->_type;
|
||||
@ -360,10 +363,18 @@ check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
|
||||
param_type = ref_type->_pointing_at->remove_cv();
|
||||
|
||||
if (class_name == param_type->get_simple_name()) {
|
||||
if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
|
||||
flags |= CPPFunctionType::F_move_constructor;
|
||||
if (flags & CPPFunctionType::F_constructor) {
|
||||
if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
|
||||
flags |= CPPFunctionType::F_move_constructor;
|
||||
} else {
|
||||
flags |= CPPFunctionType::F_copy_constructor;
|
||||
}
|
||||
} else {
|
||||
flags |= CPPFunctionType::F_copy_constructor;
|
||||
if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
|
||||
flags |= CPPFunctionType::F_move_assignment_operator;
|
||||
} else {
|
||||
flags |= CPPFunctionType::F_copy_assignment_operator;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,6 +177,14 @@ is_copy_constructible() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-assignable.
|
||||
*/
|
||||
bool CPPPointerType::
|
||||
is_copy_assignable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a little more forgiving than is_equal(): it returns true if the
|
||||
* types appear to be referring to the same thing, even if they may have
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
virtual bool is_constructible(const CPPType *other) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_copy_assignable() const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
@ -103,6 +103,14 @@ is_copy_constructible() const {
|
||||
return (_type != T_void);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-assignable.
|
||||
*/
|
||||
bool CPPSimpleType::
|
||||
is_copy_assignable() const {
|
||||
return (_type != T_void);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_copy_assignable() const;
|
||||
virtual bool is_destructible() const;
|
||||
virtual bool is_parameter_expr() const;
|
||||
|
||||
|
@ -435,6 +435,17 @@ is_copy_constructible() const {
|
||||
return is_copy_constructible(V_public);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-assignable.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_copy_assignable() const {
|
||||
if (is_abstract()) {
|
||||
return false;
|
||||
}
|
||||
return is_copy_assignable(V_public);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
@ -606,6 +617,97 @@ is_move_constructible(CPPVisibility min_vis) const {
|
||||
return is_copy_constructible(min_vis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-assignable, without checking whether the
|
||||
* class is abstract.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_copy_assignable(CPPVisibility min_vis) const {
|
||||
CPPInstance *assignment_operator = get_copy_assignment_operator();
|
||||
if (assignment_operator != (CPPInstance *)NULL) {
|
||||
// It has a copy assignment operator.
|
||||
if (assignment_operator->_vis > min_vis) {
|
||||
// Inaccessible copy assignment operator.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (assignment_operator->_storage_class & CPPInstance::SC_deleted) {
|
||||
// Deleted copy assignment operator.
|
||||
return false;
|
||||
}
|
||||
|
||||
// NB: if it's defaulted, it may still be deleted.
|
||||
if ((assignment_operator->_storage_class & CPPInstance::SC_defaulted) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Implicit copy assignment operator. Check if the implicit or defaulted
|
||||
// copy assignment operator is deleted.
|
||||
if (!assignment_operator && (get_move_constructor() || get_move_assignment_operator())) {
|
||||
// It's not explicitly defaulted, and there is a move constructor or move
|
||||
// assignment operator, so the implicitly-declared one is deleted.
|
||||
return false;
|
||||
}
|
||||
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if (base != NULL) {
|
||||
if (!base->is_copy_assignable(V_protected)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure all members are assignable.
|
||||
CPPScope::Variables::const_iterator vi;
|
||||
for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
|
||||
CPPInstance *instance = (*vi).second;
|
||||
assert(instance != NULL);
|
||||
|
||||
if (instance->_storage_class & CPPInstance::SC_static) {
|
||||
// Static members don't count.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!instance->_type->is_copy_assignable()) {
|
||||
// Const or reference member, can't do it.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is move-assignable.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_move_assignable(CPPVisibility min_vis) const {
|
||||
CPPInstance *assignment_operator = get_move_assignment_operator();
|
||||
if (assignment_operator != (CPPInstance *)NULL) {
|
||||
// It has a user-declared move assignment_operator.
|
||||
if (assignment_operator->_vis > min_vis) {
|
||||
// Inaccessible move assignment_operator.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (assignment_operator->_storage_class & CPPInstance::SC_deleted) {
|
||||
// It is deleted.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_abstract()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return is_copy_assignable(min_vis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
@ -886,6 +988,80 @@ get_move_constructor() const {
|
||||
return (CPPInstance *)NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the assignment operator defined for the struct type, if any, or
|
||||
* NULL if no assignment operator is found.
|
||||
*/
|
||||
CPPFunctionGroup *CPPStructType::
|
||||
get_assignment_operator() const {
|
||||
// Just look for the function with the name "operator ="
|
||||
CPPScope::Functions::const_iterator fi;
|
||||
fi = _scope->_functions.find("operator =");
|
||||
if (fi != _scope->_functions.end()) {
|
||||
return fi->second;
|
||||
} else {
|
||||
return (CPPFunctionGroup *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the copy assignment operator defined for the struct type, or NULL
|
||||
* if no user-declared copy assignment operator exists.
|
||||
*/
|
||||
CPPInstance *CPPStructType::
|
||||
get_copy_assignment_operator() const {
|
||||
CPPFunctionGroup *fgroup = get_assignment_operator();
|
||||
if (fgroup == (CPPFunctionGroup *)NULL) {
|
||||
return (CPPInstance *)NULL;
|
||||
}
|
||||
|
||||
CPPFunctionGroup::Instances::const_iterator ii;
|
||||
for (ii = fgroup->_instances.begin();
|
||||
ii != fgroup->_instances.end();
|
||||
++ii) {
|
||||
CPPInstance *inst = (*ii);
|
||||
assert(inst->_type != (CPPType *)NULL);
|
||||
|
||||
CPPFunctionType *ftype = inst->_type->as_function_type();
|
||||
assert(ftype != (CPPFunctionType *)NULL);
|
||||
|
||||
if ((ftype->_flags & CPPFunctionType::F_copy_assignment_operator) != 0) {
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
|
||||
return (CPPInstance *)NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the move assignment operator defined for the struct type, or NULL
|
||||
* if no user-declared move assignment operator exists.
|
||||
*/
|
||||
CPPInstance *CPPStructType::
|
||||
get_move_assignment_operator() const {
|
||||
CPPFunctionGroup *fgroup = get_assignment_operator();
|
||||
if (fgroup == (CPPFunctionGroup *)NULL) {
|
||||
return (CPPInstance *)NULL;
|
||||
}
|
||||
|
||||
CPPFunctionGroup::Instances::const_iterator ii;
|
||||
for (ii = fgroup->_instances.begin();
|
||||
ii != fgroup->_instances.end();
|
||||
++ii) {
|
||||
CPPInstance *inst = (*ii);
|
||||
assert(inst->_type != (CPPType *)NULL);
|
||||
|
||||
CPPFunctionType *ftype = inst->_type->as_function_type();
|
||||
assert(ftype != (CPPFunctionType *)NULL);
|
||||
|
||||
if ((ftype->_flags & CPPFunctionType::F_move_assignment_operator) != 0) {
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
|
||||
return (CPPInstance *)NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the destructor defined for the struct type, if any, or NULL if no
|
||||
* user-declared destructor is found.
|
||||
|
@ -56,10 +56,13 @@ public:
|
||||
virtual bool is_constructible(const CPPType *arg_type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_copy_assignable() const;
|
||||
virtual bool is_destructible() const;
|
||||
bool is_default_constructible(CPPVisibility min_vis) const;
|
||||
bool is_copy_constructible(CPPVisibility min_vis) const;
|
||||
bool is_move_constructible(CPPVisibility min_vis) const;
|
||||
bool is_move_constructible(CPPVisibility min_vis = V_public) const;
|
||||
bool is_copy_assignable(CPPVisibility min_vis) const;
|
||||
bool is_move_assignable(CPPVisibility min_vis = V_public) const;
|
||||
bool is_destructible(CPPVisibility min_vis) const;
|
||||
virtual bool is_convertible_to(const CPPType *other) const;
|
||||
|
||||
@ -69,6 +72,9 @@ public:
|
||||
CPPInstance *get_default_constructor() const;
|
||||
CPPInstance *get_copy_constructor() const;
|
||||
CPPInstance *get_move_constructor() const;
|
||||
CPPFunctionGroup *get_assignment_operator() const;
|
||||
CPPInstance *get_copy_assignment_operator() const;
|
||||
CPPInstance *get_move_assignment_operator() const;
|
||||
CPPInstance *get_destructor() const;
|
||||
|
||||
virtual CPPDeclaration *
|
||||
|
@ -110,6 +110,14 @@ is_copy_constructible() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-assignable.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_copy_assignable() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_copy_assignable() const;
|
||||
virtual bool is_destructible() const;
|
||||
virtual bool is_parameter_expr() const;
|
||||
|
||||
|
@ -205,6 +205,14 @@ is_copy_constructible() const {
|
||||
return _type->is_copy_constructible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-assignable.
|
||||
*/
|
||||
bool CPPTypedefType::
|
||||
is_copy_assignable() const {
|
||||
return _type->is_copy_assignable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_copy_assignable() const;
|
||||
virtual bool is_destructible() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
|
@ -855,31 +855,13 @@ write_prototypes(ostream &out_code, ostream *out_h) {
|
||||
<< " return ((bool (*)(PyObject *, PT(" << class_name << ") &))Dtool_Ptr_" << safe_name << "->_Dtool_Coerce)(args, coerced);\n"
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
} else if (TypeManager::is_trivial(type)) {
|
||||
} else {
|
||||
out_code
|
||||
<< "inline static " << class_name << " *Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " &coerced) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, NULL);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_Coerce != NULL, NULL);\n"
|
||||
<< " return ((" << class_name << " *(*)(PyObject *, " << class_name << " &))Dtool_Ptr_" << safe_name << "->_Dtool_Coerce)(args, coerced);\n"
|
||||
<< "}\n";
|
||||
|
||||
} else {
|
||||
out_code
|
||||
<< "inline static bool Dtool_ConstCoerce_" << safe_name << "(PyObject *args, " << class_name << " const *&coerced, bool &manage) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, false);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_ConstCoerce != NULL, false);\n"
|
||||
<< " return ((bool (*)(PyObject *, " << class_name << " const *&, bool&))Dtool_Ptr_" << safe_name << "->_Dtool_ConstCoerce)(args, coerced, manage);\n"
|
||||
<< "}\n";
|
||||
|
||||
if (has_coerce > 1) {
|
||||
out_code
|
||||
<< "inline static bool Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " *&coerced, bool &manage) {\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << " != NULL, false);\n"
|
||||
<< " nassertr(Dtool_Ptr_" << safe_name << "->_Dtool_Coerce != NULL, false);\n"
|
||||
<< " return ((bool (*)(PyObject *, " << class_name << " *&, bool&))Dtool_Ptr_" << safe_name << "->_Dtool_Coerce)(args, coerced, manage);\n"
|
||||
<< "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
out_code << "#else\n";
|
||||
@ -888,20 +870,12 @@ write_prototypes(ostream &out_code, ostream *out_h) {
|
||||
|
||||
if (has_coerce > 0) {
|
||||
if (TypeManager::is_reference_count(type)) {
|
||||
assert(!type->is_trivial());
|
||||
out_code << "extern bool Dtool_ConstCoerce_" << safe_name << "(PyObject *args, CPT(" << class_name << ") &coerced);\n";
|
||||
if (has_coerce > 1) {
|
||||
out_code << "extern bool Dtool_Coerce_" << safe_name << "(PyObject *args, PT(" << class_name << ") &coerced);\n";
|
||||
}
|
||||
|
||||
} else if (TypeManager::is_trivial(type)) {
|
||||
out_code << "extern " << class_name << " *Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " &coerced);\n";
|
||||
|
||||
} else {
|
||||
out_code << "extern bool Dtool_ConstCoerce_" << safe_name << "(PyObject *args, " << class_name << " const *&coerced, bool &manage);\n";
|
||||
if (has_coerce > 1) {
|
||||
out_code << "extern bool Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " *&coerced, bool &manage);\n";
|
||||
}
|
||||
out_code << "extern " << class_name << " *Dtool_Coerce_" << safe_name << "(PyObject *args, " << class_name << " &coerced);\n";
|
||||
}
|
||||
}
|
||||
out_code << "#endif\n";
|
||||
@ -1062,7 +1036,7 @@ write_class_details(ostream &out, Object *obj) {
|
||||
int has_coerce = has_coerce_constructor(cpptype->as_struct_type());
|
||||
if (has_coerce > 0) {
|
||||
write_coerce_constructor(out, obj, true);
|
||||
if (has_coerce > 1 && !TypeManager::is_trivial(obj->_itype._cpptype)) {
|
||||
if (has_coerce > 1 && TypeManager::is_reference_count(obj->_itype._cpptype)) {
|
||||
write_coerce_constructor(out, obj, false);
|
||||
}
|
||||
}
|
||||
@ -1182,20 +1156,12 @@ write_class_declarations(ostream &out, ostream *out_h, Object *obj) {
|
||||
int has_coerce = has_coerce_constructor(type->as_struct_type());
|
||||
if (has_coerce > 0) {
|
||||
if (TypeManager::is_reference_count(type)) {
|
||||
assert(!type->is_trivial());
|
||||
out << "bool Dtool_ConstCoerce_" << class_name << "(PyObject *args, CPT(" << c_class_name << ") &coerced);\n";
|
||||
if (has_coerce > 1) {
|
||||
out << "bool Dtool_Coerce_" << class_name << "(PyObject *args, PT(" << c_class_name << ") &coerced);\n";
|
||||
}
|
||||
|
||||
} else if (TypeManager::is_trivial(type)) {
|
||||
out << "" << c_class_name << " *Dtool_Coerce_" << class_name << "(PyObject *args, " << c_class_name << " &coerced);\n";
|
||||
|
||||
} else {
|
||||
out << "bool Dtool_ConstCoerce_" << class_name << "(PyObject *args, " << c_class_name << " const *&coerced, bool &manage);\n";
|
||||
if (has_coerce > 1) {
|
||||
out << "bool Dtool_Coerce_" << class_name << "(PyObject *args, " << c_class_name << " *&coerced, bool &manage);\n";
|
||||
}
|
||||
out << "" << c_class_name << " *Dtool_Coerce_" << class_name << "(PyObject *args, " << c_class_name << " &coerced);\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -3046,8 +3012,7 @@ write_module_class(ostream &out, Object *obj) {
|
||||
|
||||
int has_coerce = has_coerce_constructor(obj->_itype._cpptype->as_struct_type());
|
||||
if (has_coerce > 0) {
|
||||
if (TypeManager::is_reference_count(obj->_itype._cpptype) ||
|
||||
!TypeManager::is_trivial(obj->_itype._cpptype)) {
|
||||
if (TypeManager::is_reference_count(obj->_itype._cpptype)) {
|
||||
out << " (CoerceFunction)Dtool_ConstCoerce_" << ClassName << ",\n";
|
||||
if (has_coerce > 1) {
|
||||
out << " (CoerceFunction)Dtool_Coerce_" << ClassName << ",\n";
|
||||
@ -3920,7 +3885,7 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
||||
}
|
||||
return_flags |= RF_err_false;
|
||||
|
||||
} else if (TypeManager::is_trivial(obj->_itype._cpptype)) {
|
||||
} else {
|
||||
out << cClassName << " *Dtool_Coerce_" << ClassName << "(PyObject *args, " << cClassName << " &coerced) {\n";
|
||||
|
||||
out << " " << cClassName << " *local_this;\n";
|
||||
@ -3934,26 +3899,6 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
|
||||
out << " return local_this;\n";
|
||||
|
||||
return_flags |= RF_err_null;
|
||||
|
||||
} else {
|
||||
if (is_const) {
|
||||
out << "bool Dtool_ConstCoerce_" << ClassName << "(PyObject *args, " << cClassName << " const *&coerced, bool &manage) {\n";
|
||||
} else {
|
||||
out << "bool Dtool_Coerce_" << ClassName << "(PyObject *args, " << cClassName << " *&coerced, bool &manage) {\n";
|
||||
}
|
||||
|
||||
out << " DTOOL_Call_ExtractThisPointerForType(args, &Dtool_" << ClassName << ", (void**)&coerced);\n";
|
||||
out << " if (coerced != NULL) {\n";
|
||||
if (!is_const) {
|
||||
out << " if (!((Dtool_PyInstDef *)args)->_is_const) {\n";
|
||||
out << " // A non-const instance is required, which this is.\n";
|
||||
out << " return true;\n";
|
||||
out << " }\n";
|
||||
} else {
|
||||
out << " return true;\n";
|
||||
}
|
||||
|
||||
return_flags |= RF_err_false;
|
||||
}
|
||||
|
||||
out << " }\n\n";
|
||||
@ -5498,8 +5443,8 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
// actual PointerTo. This eliminates an unref()ref() pair.
|
||||
pexpr_string = "MOVE(" + param_name + "_this)";
|
||||
|
||||
} else if (TypeManager::is_trivial(obj_type)) {
|
||||
// This is a trivial type, such as TypeHandle or LVecBase4.
|
||||
} else {
|
||||
// This is a move-assignable type, such as TypeHandle or LVecBase4.
|
||||
obj_type->output_instance(extra_convert, param_name + "_local", &parser);
|
||||
extra_convert << ";\n";
|
||||
|
||||
@ -5522,29 +5467,6 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
coerce_call = "(" + param_name + "_this != NULL)";
|
||||
|
||||
pexpr_string = param_name + "_this";
|
||||
|
||||
} else {
|
||||
// This is a bit less elegant: we use a bool to store whether we're
|
||||
// supposed to clean up the reference afterward.
|
||||
type->output_instance(extra_convert, param_name + "_this", &parser);
|
||||
extra_convert
|
||||
<< default_expr << ";\n"
|
||||
<< "bool " << param_name << "_manage = false;\n";
|
||||
|
||||
if (TypeManager::is_const_pointer_or_ref(orig_type)) {
|
||||
coerce_call = "Dtool_ConstCoerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this, " + param_name + "_manage)";
|
||||
} else {
|
||||
coerce_call = "Dtool_Coerce_" + make_safe_name(class_name) +
|
||||
"(" + param_name + ", " + param_name + "_this, " + param_name + "_manage)";
|
||||
}
|
||||
|
||||
extra_cleanup
|
||||
<< "if (" << param_name << "_manage) {\n"
|
||||
<< " delete " << param_name << "_this;\n"
|
||||
<< "}\n";
|
||||
|
||||
pexpr_string = param_name + "_this";
|
||||
}
|
||||
|
||||
if (report_errors) {
|
||||
@ -5848,7 +5770,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
manage_return = remap->_return_value_needs_management;
|
||||
return_expr = "return_value";
|
||||
|
||||
} else if ((return_flags & RF_coerced) != 0 && TypeManager::is_trivial(remap->_cpptype)) {
|
||||
} else if ((return_flags & RF_coerced) != 0 && !TypeManager::is_reference_count(remap->_cpptype)) {
|
||||
// Another special case is the coerce constructor for a trivial type. We
|
||||
// don't want to invoke "operator new" unnecessarily.
|
||||
if (is_constructor && remap->_extension) {
|
||||
@ -6152,13 +6074,8 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
indent(out, indent_level) << "coerced = MOVE(" << return_expr << ");\n";
|
||||
indent(out, indent_level) << "return true;\n";
|
||||
|
||||
} else if (TypeManager::is_trivial(remap->_cpptype)) {
|
||||
indent(out, indent_level) << "return &coerced;\n";
|
||||
|
||||
} else {
|
||||
indent(out, indent_level) << "coerced = " << return_expr << ";\n";
|
||||
indent(out, indent_level) << "manage = true;\n";
|
||||
indent(out, indent_level) << "return true;\n";
|
||||
indent(out, indent_level) << "return &coerced;\n";
|
||||
}
|
||||
|
||||
} else if (return_flags & RF_raise_keyerror) {
|
||||
@ -7357,6 +7274,14 @@ has_coerce_constructor(CPPStructType *type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// It is convenient to set default-constructability and move-assignability
|
||||
// as requirement for non-reference-counted objects, since it simplifies the
|
||||
// implementation and it holds for all classes we need it for.
|
||||
if (!TypeManager::is_reference_count(type) &&
|
||||
(!type->is_default_constructible() || !type->is_move_assignable())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPPScope *scope = type->get_scope();
|
||||
if (scope == NULL) {
|
||||
return 0;
|
||||
|
@ -2517,55 +2517,3 @@ is_local(CPPType *source_type) {
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is trivial (or trivial enough for our purposes).
|
||||
*/
|
||||
bool TypeManager::
|
||||
is_trivial(CPPType *source_type) {
|
||||
switch (source_type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_trivial(source_type->as_const_type()->_wrapped_around);
|
||||
|
||||
case CPPDeclaration::ST_reference:
|
||||
return false;
|
||||
|
||||
case CPPDeclaration::ST_pointer:
|
||||
return true;
|
||||
|
||||
case CPPDeclaration::ST_simple:
|
||||
return true;
|
||||
|
||||
case CPPDeclaration::ST_typedef:
|
||||
return is_trivial(source_type->as_typedef_type()->_type);
|
||||
|
||||
default:
|
||||
if (source_type->is_trivial() || is_handle(source_type)) {
|
||||
return true;
|
||||
} else {
|
||||
// This is a bit of a hack. is_trivial() returns false for types that
|
||||
// have an empty constructor (since we can't use =default yet). For the
|
||||
// other classes, it's just convenient to consider them trivial even if
|
||||
// they aren't, since they are simple enough.
|
||||
string name = source_type->get_simple_name();
|
||||
return (name == "ButtonHandle" || name == "DatagramIterator" ||
|
||||
name == "BitMask" || name == "Filename" || name == "pixel" ||
|
||||
name == "NodePath" || name == "LoaderOptions" ||
|
||||
name == "PointerToArray" || name == "ConstPointerToArray" ||
|
||||
name == "PStatThread" ||
|
||||
(name.size() >= 6 && name.substr(0, 6) == "LPlane") ||
|
||||
(name.size() > 6 && name.substr(0, 6) == "LPoint") ||
|
||||
(name.size() > 7 && name.substr(0, 7) == "LVector") ||
|
||||
(name.size() > 7 && name.substr(0, 7) == "LMatrix") ||
|
||||
(name.size() > 8 && name.substr(0, 8) == "LVecBase") ||
|
||||
(name.size() >= 9 && name.substr(0, 9) == "LParabola") ||
|
||||
(name.size() >= 9 && name.substr(0, 9) == "LRotation") ||
|
||||
(name.size() >= 11 && name.substr(0, 11) == "LQuaternion") ||
|
||||
(name.size() >= 12 && name.substr(0, 12) == "LOrientation") ||
|
||||
(name.size() > 16 && name.substr(0, 16) == "UnalignedLMatrix") ||
|
||||
(name.size() > 17 && name.substr(0, 17) == "UnalignedLVecBase"));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -149,7 +149,6 @@ public:
|
||||
|
||||
static bool is_exported(CPPType *type);
|
||||
static bool is_local(CPPType *type);
|
||||
static bool is_trivial(CPPType *type);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -88,6 +88,9 @@ __published:
|
||||
streampos tellp();
|
||||
void seekp(streampos pos);
|
||||
void seekp(streamoff off, ios_base::seekdir dir);
|
||||
|
||||
protected:
|
||||
ostream(ostream &&);
|
||||
};
|
||||
class istream : virtual public ios {
|
||||
__published:
|
||||
@ -97,12 +100,18 @@ __published:
|
||||
streampos tellg();
|
||||
void seekg(streampos pos);
|
||||
void seekg(streamoff off, ios_base::seekdir dir);
|
||||
|
||||
protected:
|
||||
istream(istream &&);
|
||||
};
|
||||
class iostream : public istream, public ostream {
|
||||
__published:
|
||||
iostream(const iostream&) = delete;
|
||||
|
||||
void flush();
|
||||
|
||||
protected:
|
||||
iostream(iostream &&);
|
||||
};
|
||||
|
||||
class ofstream : public ostream {
|
||||
|
@ -247,6 +247,8 @@ private:
|
||||
template <class Element>
|
||||
class ConstPointerToArray : public PointerToArrayBase<Element> {
|
||||
public:
|
||||
INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
|
||||
|
||||
// By hiding this template from interrogate, we would improve compile-time
|
||||
// speed and memory utilization. However, we do want to export a minimal
|
||||
// subset of this class. So we define just the exportable interface here.
|
||||
@ -287,7 +289,6 @@ PUBLISHED:
|
||||
typedef TYPENAME pvector<Element>::difference_type difference_type;
|
||||
typedef TYPENAME pvector<Element>::size_type size_type;
|
||||
|
||||
INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
|
||||
INLINE ConstPointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element));
|
||||
INLINE ConstPointerToArray(const PointerToArray<Element> ©);
|
||||
INLINE ConstPointerToArray(const ConstPointerToArray<Element> ©);
|
||||
|
@ -11,13 +11,6 @@
|
||||
* @date 2002-03-06
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE NodePathCollection::
|
||||
~NodePathCollection() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the other list onto the end of this one.
|
||||
*/
|
||||
|
@ -19,30 +19,6 @@
|
||||
#include "colorAttrib.h"
|
||||
#include "indent.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
NodePathCollection::
|
||||
NodePathCollection() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
NodePathCollection::
|
||||
NodePathCollection(const NodePathCollection ©) :
|
||||
_node_paths(copy._node_paths)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void NodePathCollection::
|
||||
operator = (const NodePathCollection ©) {
|
||||
_node_paths = copy._node_paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new NodePath to the collection.
|
||||
*/
|
||||
|
@ -25,10 +25,7 @@
|
||||
*/
|
||||
class EXPCL_PANDA_PGRAPH NodePathCollection {
|
||||
PUBLISHED:
|
||||
NodePathCollection();
|
||||
NodePathCollection(const NodePathCollection ©);
|
||||
void operator = (const NodePathCollection ©);
|
||||
INLINE ~NodePathCollection();
|
||||
NodePathCollection() DEFAULT_CTOR;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
EXTENSION(NodePathCollection(PyObject *self, PyObject *sequence));
|
||||
|
Loading…
x
Reference in New Issue
Block a user