changeset 18382:6e3344111522

Implement subsasgn overloading in classdef * ov-classdef.cc (octave_classdef::subsasgn): Look for overloaded method "subsasgn" when not in a class method or a builtin call. * ov-classdef.h (to_cdef, to_cdef_ref): Turn warning into error when the casted object is not of type "object".
author Michael Goffioul <michael.goffioul@gmail.com>
date Fri, 24 Jan 2014 22:17:29 -0500
parents b48391da83fc
children 5b7b12e16523
files libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-classdef.h
diffstat 2 files changed, 41 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc	Fri Jan 24 17:12:39 2014 -0800
+++ b/libinterp/octave-value/ov-classdef.cc	Fri Jan 24 22:17:29 2014 -0500
@@ -959,9 +959,45 @@
                            const std::list<octave_value_list>& idx,
                            const octave_value& rhs)
 {
-  // FIXME: should check "subsasgn" method first
-
-  return object.subsasgn (type, idx, rhs);
+  octave_value retval;
+
+  cdef_class cls = object.get_class ();
+
+  if (! in_class_method (cls) && ! called_from_builtin ())
+    {
+      cdef_method meth = cls.find_method ("subsasgn");
+
+      if (meth.ok ())
+        {
+          octave_value_list args;
+
+          args(1) = make_idx_args (type, idx, "subsasgn");
+
+          if (! error_state)
+            {
+              count++;
+              args(0) = octave_value (this);
+              args(2) = rhs;
+
+              octave_value_list retlist;
+
+              retlist = meth.execute (args, 1, true, "subsasgn");
+
+              if (! error_state)
+                {
+                  if (retlist.length () > 0)
+                    retval = retlist(0);
+                  else
+                    ::error ("overloaded method `subsasgn' did not return any value");
+                }
+            }
+        }
+    }
+
+  if (! error_state && ! retval.is_defined ())
+    retval = object.subsasgn (type, idx, rhs);
+
+  return retval;
 }
 
 octave_value
--- a/libinterp/octave-value/ov-classdef.h	Fri Jan 24 17:12:39 2014 -0800
+++ b/libinterp/octave-value/ov-classdef.h	Fri Jan 24 22:17:29 2014 -0500
@@ -1500,7 +1500,7 @@
     return dynamic_cast<octave_classdef *> (val.internal_rep ())->get_object ();
   else
     {
-      warning ("trying to cast non-object into object");
+      error ("cannot convert `%s' into `object'", val.type_name().c_str ());
       return cdef_object ();
     }
 }
@@ -1514,7 +1514,7 @@
     return dynamic_cast<octave_classdef *> (val.internal_rep ())->get_object_ref ();
   else
     {
-      warning ("trying to cast non-object into object");
+      error ("cannot convert `%s' into `object'", val.type_name().c_str ());
       return empty;
     }
 }