Browse Source

operator bool () -> __nonzero__()

David Rose 17 years ago
parent
commit
a6f4fb2377

+ 6 - 6
dtool/src/cppparser/cppBison.yxx

@@ -857,15 +857,15 @@ function_prototype:
   // As an added bonus, the type of the formal_parameter will be the
   // As an added bonus, the type of the formal_parameter will be the
   // typecast type, i.e. the return type of the typecast function.
   // typecast type, i.e. the return type of the typecast function.
 
 
-  // We give all typecast operators the name "operator typecast".
-  // Only their return type will differentiate them.  (Naturally, this
-  // violates actual C++ rules, but we're not an actual C++ compiler
-  // so we don't care.  And this is the easiest way to do it.)
+  // We give typecast operators the name "operator typecast <name>",
+  // where <name> is a simple name of the type to be typecast.  Use
+  // the method's return type to determine the full type description.
+  string name = "operator typecast " + $2->get_simple_name();
   CPPIdentifier *ident = $1;
   CPPIdentifier *ident = $1;
   if (ident == NULL) {
   if (ident == NULL) {
-    ident = new CPPIdentifier("operator typecast", @1.file);
+    ident = new CPPIdentifier(name, @1.file);
   } else {
   } else {
-    ident->add_name("operator typecast");
+    ident->add_name(name);
   }
   }
   $$ = CPPInstance::make_typecast_function
   $$ = CPPInstance::make_typecast_function
     (new CPPInstance($2, $3, 0, @3.file), ident, $6, $8);
     (new CPPInstance($2, $3, 0, @3.file), ident, $6, $8);

+ 38 - 4
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -98,6 +98,7 @@ RenameSet methodRenameDictionary[] = {
     { "operator ->"  , "dereference",          0 },
     { "operator ->"  , "dereference",          0 },
     { "operator <<=" , "__ilshift__",          1 },
     { "operator <<=" , "__ilshift__",          1 },
     { "operator >>=" , "__irshift__",          1 },
     { "operator >>=" , "__irshift__",          1 },
+    { "operator typecast bool" , "__nonzero__", 0 },
     { "print"       , "Cprint",               0 },
     { "print"       , "Cprint",               0 },
     { "CInterval.set_t" , "_priv__cSetT",      0 },
     { "CInterval.set_t" , "_priv__cSetT",      0 },
     { NULL, NULL, -1 }
     { NULL, NULL, -1 }
@@ -206,7 +207,7 @@ std::string  classNameFromCppName(const std::string &cppName)
     //# initialize to empty string
     //# initialize to empty string
     std::string className = "";
     std::string className = "";
     //# These are the characters we want to strip out of the name
     //# These are the characters we want to strip out of the name
-    const std::string  badChars("!@#$%^&*()<>,.-=+~{}? ");
+    const std::string  badChars("!@#$%^&*()<>,.-=+~{}?");
     int nextCap = 0;
     int nextCap = 0;
     int firstChar = 1;
     int firstChar = 1;
     for(std::string::const_iterator  chr = cppName.begin(); chr != cppName.end(); chr++)
     for(std::string::const_iterator  chr = cppName.begin(); chr != cppName.end(); chr++)
@@ -214,7 +215,7 @@ std::string  classNameFromCppName(const std::string &cppName)
         if (badChars.find(*chr) != std::string::npos)
         if (badChars.find(*chr) != std::string::npos)
         {
         {
         }
         }
-        else if (*chr == '_')
+        else if (*chr == '_' || *chr == ' ')
         {
         {
             nextCap = 1;
             nextCap = 1;
         }
         }
@@ -271,14 +272,14 @@ std::string nonClassNameFromCppName(const std::string &cppName_in)
 ///////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////
 std::string  methodNameFromCppName(const std::string &cppName, const std::string &className) {
 std::string  methodNameFromCppName(const std::string &cppName, const std::string &className) {
     std::string methodName;
     std::string methodName;
-    std::string badChars(" ");
+    const std::string  badChars("!@#$%^&*()<>,.-=+~{}?");
     int nextCap = 0;
     int nextCap = 0;
     for(std::string::const_iterator  chr = cppName.begin(); chr != cppName.end(); chr++)
     for(std::string::const_iterator  chr = cppName.begin(); chr != cppName.end(); chr++)
     {
     {
         if (badChars.find(*chr) != std::string::npos)
         if (badChars.find(*chr) != std::string::npos)
         {
         {
         }
         }
-        else if (*chr == '_')
+        else if (*chr == '_' || *chr == ' ')
         {
         {
             nextCap = 1;
             nextCap = 1;
         }
         }
@@ -559,6 +560,16 @@ get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) {
     return true;
     return true;
   }
   }
 
 
+  if (func->_ifunc.is_operator_typecast()) {
+    // A typecast operator.  If it's a bool type, then we wrap it with
+    // the __nonzero__ slot method.
+    if (!func->_remaps.empty() && TypeManager::is_bool(func->_remaps[0]->_return_type->get_orig_type())) {
+      def._answer_location = "tp_as_number->nb_nonzero";
+      def._wrapper_type = WT_inquiry;
+      return true;
+    }
+  }
+
   return false;
   return false;
 }
 }
 
 
@@ -1442,6 +1453,29 @@ write_module_class(ostream &out,  Object *obj) {
           out << "}\n\n";
           out << "}\n\n";
         }
         }
         break;
         break;
+        
+      case WT_inquiry:
+        // int func(PyObject *self)
+        {
+          Function *func = rfi->first;
+          out << "//////////////////\n";
+          out << "//  A wrapper function to satisfy Python's internal calling conventions. \n";
+          out << "//     " <<ClassName<< " ..." << rfi->second._answer_location <<" = "<< methodNameFromCppName(func,export_calss_name) <<"\n";
+          out << "//////////////////\n";
+          out << "static int " << func->_name << methodNameFromCppName(func,export_calss_name) << "(PyObject *self)\n";
+          out << "{\n";
+          out << "    PyObject *args = Py_BuildValue(\"()\");\n";
+          out << "    PyObject *result = " << func->_name <<"(self, args, NULL);\n";
+          out << "    Py_DECREF(args);\n";
+          out << "    if (result == NULL) {\n";
+          out << "      return -1;\n";
+          out << "    }\n";
+          out << "    int iresult = PyInt_AsLong(result);\n";
+          out << "    Py_DECREF(result);\n";
+          out << "    return iresult;\n";
+          out << "}\n\n";
+        }
+        break;
 
 
       case WT_none:
       case WT_none:
         break;
         break;

+ 1 - 0
dtool/src/interrogate/interfaceMakerPythonNative.h

@@ -73,6 +73,7 @@ private:
     WT_sequence_setitem,
     WT_sequence_setitem,
     WT_sequence_size,
     WT_sequence_size,
     WT_mapping_setitem,
     WT_mapping_setitem,
+    WT_inquiry,
   };
   };
 
 
   class SlottedFunctionDef {
   class SlottedFunctionDef {

+ 5 - 0
dtool/src/interrogate/interrogateBuilder.cxx

@@ -1685,6 +1685,11 @@ get_function(CPPInstance *function, string description,
     ifunction->_flags |= InterrogateFunction::F_unary_op;
     ifunction->_flags |= InterrogateFunction::F_unary_op;
   }
   }
 
 
+  if (ftype->_flags & CPPFunctionType::F_operator_typecast) {
+    // This is a special typecast operator.
+    ifunction->_flags |= InterrogateFunction::F_operator_typecast;
+  }
+
   ifunction->_flags |= flags;
   ifunction->_flags |= flags;
   ifunction->_instances->insert(InterrogateFunction::Instances::value_type(function_signature, function));
   ifunction->_instances->insert(InterrogateFunction::Instances::value_type(function_signature, function));
   ifunction->_expression = expression;
   ifunction->_expression = expression;

+ 11 - 0
dtool/src/interrogatedb/interrogateFunction.I

@@ -57,6 +57,17 @@ is_unary_op() const {
   return (_flags & F_unary_op) != 0;
   return (_flags & F_unary_op) != 0;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: InterrogateFunction::is_operator_typecast
+//       Access: Public
+//  Description: Returns true if the function is a special typecast
+//               operator, like operator bool().
+////////////////////////////////////////////////////////////////////
+INLINE bool InterrogateFunction::
+is_operator_typecast() const {
+  return (_flags & F_operator_typecast) != 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: InterrogateFunction::get_class
 //     Function: InterrogateFunction::get_class
 //       Access: Public
 //       Access: Public

+ 2 - 0
dtool/src/interrogatedb/interrogateFunction.h

@@ -39,6 +39,7 @@ public:
   INLINE bool is_virtual() const;
   INLINE bool is_virtual() const;
   INLINE bool is_method() const;
   INLINE bool is_method() const;
   INLINE bool is_unary_op() const;
   INLINE bool is_unary_op() const;
+  INLINE bool is_operator_typecast() const;
   INLINE TypeIndex get_class() const;
   INLINE TypeIndex get_class() const;
 
 
   INLINE bool has_scoped_name() const;
   INLINE bool has_scoped_name() const;
@@ -70,6 +71,7 @@ private:
     F_getter          = 0x0010,
     F_getter          = 0x0010,
     F_setter          = 0x0020,
     F_setter          = 0x0020,
     F_unary_op        = 0x0040,
     F_unary_op        = 0x0040,
+    F_operator_typecast = 0x0080,
   };
   };
 
 
   int _flags;
   int _flags;