changeset 22897:4090c32fccf8

store set of dispatch classes in built-in function objects * ov-fcn.h (octave_function::push_dispatch_class, octave_function::handles_dispatch_class): New virtual functions. * ov-builtin.h, ov-builtin.cc (octave_builtin::push_dispatch_class, octave_builtin::handles_dispatch_class): New functions. * symtab.h, symtab.cc (symbol_table::fcn_info::fcn_info_rep::install_built_in_dispatch): Define in .cc file. Store class names in built-in function object instead of class_methods. (symbol_table::fcn_info::fcn_info_rep::load_class_method): Also search for built-in functions that are declared to handle specific types.
author John W. Eaton <jwe@octave.org>
date Thu, 15 Dec 2016 22:04:11 -0500
parents 8fb46f48c548
children 9baa19102908
files libinterp/corefcn/symtab.cc libinterp/corefcn/symtab.h libinterp/octave-value/ov-builtin.cc libinterp/octave-value/ov-builtin.h libinterp/octave-value/ov-fcn.h
diffstat 5 files changed, 69 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/symtab.cc	Thu Dec 15 21:53:28 2016 -0500
+++ b/libinterp/corefcn/symtab.cc	Thu Dec 15 22:04:11 2016 -0500
@@ -529,6 +529,24 @@
                   it++;
                 }
             }
+
+          if (retval.is_undefined ())
+            {
+              // Search for built-in functions that are declared to
+              // handle specific types.
+
+              if (built_in_function.is_defined ())
+                {
+                  octave_function *fcn = built_in_function.function_value ();
+
+                  if (fcn && fcn->handles_dispatch_class (dispatch_type))
+                    {
+                      retval = built_in_function;
+
+                      class_methods[dispatch_type] = retval;
+                    }
+                }
+            }
         }
     }
 
@@ -1111,6 +1129,27 @@
 }
 
 void
+symbol_table::fcn_info::fcn_info_rep::install_built_in_dispatch (const std::string& klass)
+{
+  if (built_in_function.is_defined ())
+    {
+      octave_function *fcn = built_in_function.function_value ();
+
+      if (fcn)
+        {
+          if (fcn->handles_dispatch_class (klass))
+            warning ("install_built_in_dispatch: '%s' already defined for class '%s'",
+                     name.c_str (), klass.c_str ());
+          else
+            fcn->push_dispatch_class (klass);
+        }
+    }
+  else
+    error ("install_built_in_dispatch: '%s' is not a built-in function",
+           name.c_str ());
+}
+
+void
 symbol_table::fcn_info::fcn_info_rep::dump (std::ostream& os,
                                             const std::string& prefix) const
 {
--- a/libinterp/corefcn/symtab.h	Thu Dec 15 21:53:28 2016 -0500
+++ b/libinterp/corefcn/symtab.h	Thu Dec 15 22:04:11 2016 -0500
@@ -853,20 +853,7 @@
         built_in_function = f;
       }
 
-      void install_built_in_dispatch (const std::string& klass)
-      {
-        if (built_in_function.is_defined ())
-          {
-            if (class_methods.find (klass) != class_methods.end ())
-              warning ("install_built_in_dispatch: '%s' already defined for class '%s'",
-                       name.c_str (), klass.c_str ());
-            else
-              class_methods[klass] = built_in_function;
-          }
-        else
-          error ("install_built_in_dispatch: '%s' is not a built-in function",
-                 name.c_str ());
-      }
+      void install_built_in_dispatch (const std::string& klass);
 
       template <typename T>
       void
--- a/libinterp/octave-value/ov-builtin.cc	Thu Dec 15 21:53:28 2016 -0500
+++ b/libinterp/octave-value/ov-builtin.cc	Thu Dec 15 22:04:11 2016 -0500
@@ -159,5 +159,17 @@
   return f;
 }
 
+void
+octave_builtin::push_dispatch_class (const std::string& dispatch_type)
+{
+  dispatch_classes.insert (dispatch_type);
+}
+
+bool
+octave_builtin::handles_dispatch_class (const std::string& dispatch_type) const
+{
+  return dispatch_classes.find (dispatch_type) != dispatch_classes.end ();
+}
+
 const std::list<octave_lvalue> *octave_builtin::curr_lvalue_list = 0;
 
--- a/libinterp/octave-value/ov-builtin.h	Thu Dec 15 21:53:28 2016 -0500
+++ b/libinterp/octave-value/ov-builtin.h	Thu Dec 15 22:04:11 2016 -0500
@@ -25,6 +25,8 @@
 
 #include "octave-config.h"
 
+#include <list>
+#include <set>
 #include <string>
 
 #include "ov-fcn.h"
@@ -97,6 +99,10 @@
 
   fcn function (void) const;
 
+  void push_dispatch_class (const std::string& dispatch_type);
+
+  bool handles_dispatch_class (const std::string& dispatch_type) const;
+
   static const std::list<octave_lvalue> *curr_lvalue_list;
 
 protected:
@@ -107,6 +113,9 @@
   // The name of the file where this function was defined.
   std::string file;
 
+  // The types this function has been declared to handle (if any).
+  std::set<std::string> dispatch_classes;
+
   // A pointer to the jit type that represents the function.
   jit_type *jtype;
 
--- a/libinterp/octave-value/ov-fcn.h	Thu Dec 15 21:53:28 2016 -0500
+++ b/libinterp/octave-value/ov-fcn.h	Thu Dec 15 22:04:11 2016 -0500
@@ -104,6 +104,14 @@
 
   virtual bool takes_var_return (void) const { return false; }
 
+  // The next two functions are for dispatching to built-in
+  // functions given built-in classes.
+
+  virtual void push_dispatch_class (const std::string&) { }
+
+  virtual bool handles_dispatch_class (const std::string&) const
+  { return false; }
+
   void stash_dispatch_class (const std::string& nm) { xdispatch_class = nm; }
 
   std::string dispatch_class (void) const { return xdispatch_class; }