changeset 15870:2b6fe094e615 classdef

Implement embryonic value-class semantic. * libinterp/octave-value/ov-classdef.h (cdef_object_rep::set_class): Delete method. (cdef_object_rep::get, cdef_object_rep::put): Copy implementation from handle_cdef_object. (cdef_object_rep::subsref, cdef_oject_rep::subsasgn): Move implementation to source file. (cdef_object_rep::map): Copy field from handle_cdef_object. (handle_cdef_rep::get, handle_cdef_rep::put): Move implementation to cdef_object_rep. (handle_cdef_rep::map): Move field to cdef_object_rep. (cdef_object_rep::cdef_object_rep, cdef_object_rep::operator=): Private declaration to disable copying. (handle_cdef_rep::handle_cdef_rep, handle_cdef_rep::operator=): Likewise. (class value_cdef_object): New class for value-class semantic. * libinterp/octave-value/ov-classdef.cc (cdef_object_rep::subsref, cdef_object_rep::subsasgn): Copy implementation from handle_cdef_object. (cdef_class_rep::run_constructor): Do not try to assign constructor result in case of error. (cdef_class_rep::construct): Create value_cdef_object object for value classes.
author Michael Goffioul <michael.goffioul@gmail.com>
date Tue, 01 Jan 2013 19:54:15 -0500
parents 5e5705b3e505
children 1ca9beb2a194
files libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-classdef.h
diffstat 2 files changed, 86 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc	Tue Jan 01 19:42:17 2013 -0500
+++ b/libinterp/octave-value/ov-classdef.cc	Tue Jan 01 19:54:15 2013 -0500
@@ -811,15 +811,10 @@
   return string_vector ();
 }
 
-handle_cdef_object::~handle_cdef_object (void)
-{
-  printf ("deleting %s object (handle)\n", cname.c_str ());
-}
-
 octave_value_list
-handle_cdef_object::subsref (const std::string& type,
-			     const std::list<octave_value_list>& idx,
-			     int nargout, int& skip)
+cdef_object_rep::subsref (const std::string& type,
+                          const std::list<octave_value_list>& idx,
+                          int nargout, int& skip)
 {
   skip = 0;
 
@@ -899,9 +894,9 @@
 }
 
 octave_value
-handle_cdef_object::subsasgn (const std::string& type,
-                              const std::list<octave_value_list>& idx,
-                              const octave_value& rhs)
+cdef_object_rep::subsasgn (const std::string& type,
+                           const std::list<octave_value_list>& idx,
+                           const octave_value& rhs)
 {
   octave_value retval;
 
@@ -957,6 +952,16 @@
   return retval;
 }
 
+handle_cdef_object::~handle_cdef_object (void)
+{
+  printf ("deleting %s object (handle)\n", cname.c_str ());
+}
+
+value_cdef_object::~value_cdef_object (void)
+{
+  printf ("deleting %s object (value)\n", cname.c_str ());
+}
+
 cdef_method
 cdef_class::cdef_class_rep::find_method (const std::string& nm, bool local)
 {
@@ -1377,19 +1382,28 @@
       ctor_args.prepend (to_ov (obj));
       ctor_retval = ctor.execute (ctor_args, 1);
 
-      if (ctor_retval.length () == 1)
-        obj = to_cdef (ctor_retval(0));
-      else
-        ::error ("%s: invalid number of output arguments for classdef constructor",
-                 ctor_name.c_str ());
+      if (! error_state)
+        {
+          if (ctor_retval.length () == 1)
+            obj = to_cdef (ctor_retval(0));
+          else
+            ::error ("%s: invalid number of output arguments for classdef constructor",
+                     ctor_name.c_str ());
+        }
     }
 }
 
 octave_value
 cdef_class::cdef_class_rep::construct (const octave_value_list& args)
 {
-  // FIXME: determine whether to use value or handle rep object
-  cdef_object obj (new handle_cdef_object (get ("Name").string_value ()));
+  cdef_object_rep *r;
+
+  if (is_handle_class ())
+    r = new handle_cdef_object (get_name ());
+  else
+    r = new value_cdef_object (get_name ());
+
+  cdef_object obj (r);
 
   initialize_object (obj);
 
@@ -1491,14 +1505,6 @@
   if (error_state)
     return cdef_class ();
 
-  // FIXME: remove this...
-  if (! retval.is_handle_class ())
-    {
-      ::error ("%s: value classes not supported yet",
-               class_name.c_str ());
-      return cdef_class ();
-    }
-
   // Class attributes
 
   if (t->attribute_list ())
--- a/libinterp/octave-value/ov-classdef.h	Tue Jan 01 19:42:17 2013 -0500
+++ b/libinterp/octave-value/ov-classdef.h	Tue Jan 01 19:54:15 2013 -0500
@@ -55,39 +55,35 @@
 
   virtual cdef_class get_class (void) const;
 
-  virtual void set_class (const cdef_object&)
-    { error ("set_class: invalid object"); }
-
   virtual cdef_object_rep* clone (void) const
     {
       error ("clone: invalid object");
       return new cdef_object_rep ();
     }
 
-  virtual void put (const std::string&, const octave_value&)
-    { error ("put: invalid object"); }
+  virtual void put (const std::string& pname, const octave_value& val)
+    { map.assign (pname, val); }
+
+  virtual octave_value get (const std::string& pname) const
+    {
+      Cell val = map.contents (pname);
 
-  virtual octave_value get (const std::string&) const
-    {
-      error ("get: invalid object");
-      return octave_value ();
+      if (val.numel () > 0)
+	return val(0, 0);
+      else
+	{
+	  error ("get: unknown slot: %s", pname.c_str ());
+	  return octave_value ();
+	}
     }
 
-  virtual octave_value_list subsref (const std::string&,
-				     const std::list<octave_value_list>&,
-				     int, int&)
-    {
-      error ("subsref: invalid object");
-      return octave_value_list ();
-    }
+  virtual octave_value_list subsref (const std::string& type,
+                                     const std::list<octave_value_list>& idx,
+                                     int nargout, int& skip);
 
-  virtual octave_value subsasgn (const std::string&,
-                                 const std::list<octave_value_list>&,
-                                 const octave_value&)
-    {
-      error ("subsasgn: invalid object");
-      return octave_value ();
-    }
+  virtual octave_value subsasgn (const std::string& type,
+                                 const std::list<octave_value_list>& idx,
+                                 const octave_value& rhs);
 
   virtual string_vector map_keys(void) const;
 
@@ -104,6 +100,14 @@
 
   /* class name */
   std::string cname;
+
+  /* object property values */
+  Octave_map map;
+
+private:
+  // No copying
+  cdef_object_rep (const cdef_object_rep&);
+  cdef_object_rep& operator = (const cdef_object_rep& );
 };
 
 class
@@ -202,34 +206,39 @@
       return obj;
     }
 
-  void put (const std::string& pname, const octave_value& val)
-    { map.assign (pname, val); }
+  bool is_valid (void) const { return true; }
 
-  octave_value get (const std::string& pname) const
-    {
-      Cell val = map.contents (pname);
+private:
+  // No copying
+  handle_cdef_object (const handle_cdef_object&);
+  handle_cdef_object& operator = (const handle_cdef_object&);
+};
 
-      if (val.numel () > 0)
-	return val(0, 0);
-      else
-	{
-	  error ("get: unknown slot: %s", pname.c_str ());
-	  return octave_value ();
-	}
+class
+value_cdef_object : public cdef_object_rep
+{
+public:
+  value_cdef_object (void)
+      : cdef_object_rep () { }
+
+  value_cdef_object (const std::string& nm)
+      : cdef_object_rep (nm) { }
+
+  ~value_cdef_object (void);
+
+  cdef_object_rep* clone (void) const
+    {
+      value_cdef_object* obj = new value_cdef_object (cname);
+      obj->map = map;
+      return obj;
     }
 
-  octave_value_list subsref (const std::string& type,
-			     const std::list<octave_value_list>& idx,
-			     int nargout, int& skip);
-
-  octave_value subsasgn (const std::string& type,
-                         const std::list<octave_value_list>& idx,
-                         const octave_value& rhs);
-
   bool is_valid (void) const { return true; }
 
-protected:
-  Octave_map map;
+private:
+  // No copying
+  value_cdef_object (const value_cdef_object&);
+  value_cdef_object& operator = (const value_cdef_object&);
 };
 
 class