diff libinterp/octave-value/ov-classdef.cc @ 18314:06eb893b9db6

Implement subsref overloading in classdef. * ov-class.cc (sanitize, make_idx_args): Moved function to ov-base.cc. * ov-base.cc (sanitize, make_idx_args): Moved from ov-class.cc. * ov-base.h (make_udx_args): New API function declaration. * ov-classdef.cc (in_class_method): New utility static function. (octave_classdef::subsref): Use overloaded subsref method if present, only when not already in a class method.
author Michael Goffioul <michael.goffioul@gmail.com>
date Mon, 20 Jan 2014 14:10:42 -0500
parents 81c1edd70bfd
children ff311e5ff6d8
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc	Mon Jan 20 01:41:26 2014 -0500
+++ b/libinterp/octave-value/ov-classdef.cc	Mon Jan 20 14:10:42 2014 -0500
@@ -305,6 +305,14 @@
 }
 
 static bool
+in_class_method (const cdef_class& cls)
+{
+  cdef_class ctx = get_class_context ();
+
+  return (ctx.ok () && is_superclass (ctx, cls));
+}
+
+static bool
 check_access (const cdef_class& cls, const octave_value& acc,
               const std::string& meth_name = std::string (),
               const std::string& prop_name = std::string (),
@@ -885,14 +893,38 @@
   size_t skip = 0;
   octave_value_list retval;
 
-  // FIXME: should check "subsref" method first
+  cdef_class cls = object.get_class ();
+
+  if (! in_class_method (cls))
+    {
+      cdef_method meth = cls.find_method ("subsref");
+
+      if (meth.ok ())
+        {
+          octave_value_list args;
+
+          args(1) = make_idx_args (type, idx, "subsref");
+
+          if (! error_state)
+            {
+              count++;
+              args(0) = octave_value (this);
+
+              retval = meth.execute (args, nargout, true, "subsref");
+            }
+
+          return retval;
+        }
+    }
+
+  // At this point, the default subsref mechanism must be used.
 
   retval = object.subsref (type, idx, nargout, skip, cdef_class ());
 
   if (! error_state)
     {
       if (type.length () > skip && idx.size () > skip)
-	retval = retval(0).next_subsref (nargout, type, idx, skip);
+        retval = retval(0).next_subsref (nargout, type, idx, skip);
     }
 
   return retval;
@@ -906,8 +938,10 @@
   size_t skip = 0;
   octave_value_list retval;
 
-  // FIXME: should check "subsref" method first
-  // ? not sure this still applied with auto_add version of subsref
+  // This variant of subsref is used to create temporary values when doing
+  // assignment with multi-level indexing. AFAIK this is only used for internal
+  // purpose (not sure we should even implement this) and any overload subsref
+  // should not be called.
 
   retval = object.subsref (type, idx, 1, skip, cdef_class (), auto_add);