diff libinterp/octave-value/ov-classdef.h @ 15913:8521321604df classdef

Initial support for object array semantic. * libinterp/octave-value/ov-classdef.h (class cdef_object_array): New class. (cdef_object_rep::empty_clone, cdef_object_rep::copy, cdef_object_rep::make_array, cdef_object_rep::is_array, cdef_object_rep::array_value): New methods. (cdef_object::empty_clone, cdef_object::make_array, cdef_object::copy, cdef_object::is_array, cdef_object::array_value): Likewise. (cdef_object_base::empty_clone, cdef_object_base::make_array): Likewise. (handle_cdef_object::copy): Likewise. (value_cdef_object::copy): Likewise. (cdef_class::cdef_class_rep::copy, cdef_property::cdef_property_rep::copy, cdef_method::cdef_method_rep::copy, cdef_package::cdef_package_rep::copy): Likewise. (handle_cdef_object::handle_cdef_object): New copy constructor. (cdef_object::make_unique): New method. (cdef_object::subsasgn): Use it. (cdef_class::cdef_class_rep::meta): New member. (cdef_class::cdef_class_rep::cdef_class_rep): Initialize it. (cdef_class::cdef_class_rep::mark_as_meta_class, cdef_class::cdef_class_rep::is_meta): Use and manipulate it. (cdef_class::mark_as_meta_class, cdef_class::is_meta): Likewise. (cdef_class::cdef_class_rep::construct_object, cdef_class::cdef_class_rep::is_abstract, cdef_class::cdef_class_rep::is_sealed): New methods. (cdef_class::construct_object, cdef_class::is_abstract, cdef_class::is_sealed): Likewise. (cdef_class::cdef_class_rep::cdef_class_rep): New copy constructor. (cdef_property::cdef_property_rep::default_value): Remove member. (cdef_property::cdef_property_rep::get_value ()): Use "DefaultValue" slot. (cdef_property::cdef_property_rep::set_value (octave_value)): Remove method. (cdef_property::set_value (octave_value)): Likewise. (cdef_property::cdef_property_rep::cdef_property_rep): New copy constructor. (cdef_method::cdef_method_rep::cdef_method_rep): Likewise. (cdef_package::cdef_package_rep::cdef_package_rep): Likewise. (octave_classdef::empty_clone): Call cdef_object::empty_clone. (octave_classdef::undef_subsasgn): New method. (class cdef_property, class cdef_method, class cdef_package): Mark cdef_class as friend. * libinterp/octave-value/ov-classdef.cc: Include Array.cc. (make_class): Initialize "Abstract" property. Do not register classes with empty name. (make_meta_class): New static function. (make_method): Check whether function object is valid. (make_package): Do not register packages with empty name. (octave_classdef::undef_subsasgn): New method. (class cdef_object_array): New class. (cdef_class::cdef_class_rep::cdef_class_rep): Initialize meta. (cdef_class::cdef_class_rep::find_methods, cdef_class::cdef_class_rep::find_names): Use cdef_method::is_constructor instead of relying on the method name. (cdef_class::cdef_class_rep::construct_object): New method. (cdef_class::cdef_class_rep::construct): Use it. (install_classdef): Use make_meta_class. Create "Abstract" property for class meta.class.
author Michael Goffioul <michael.goffioul@gmail.com>
date Tue, 08 Jan 2013 12:34:30 -0500
parents b18b7e560236
children f97a746e4544
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.h
+++ b/libinterp/octave-value/ov-classdef.h
@@ -63,6 +63,26 @@
       return new cdef_object_rep ();
     }
 
+  virtual cdef_object_rep* empty_clone (void) const
+    {
+      gripe_invalid_object ("empty_clone");
+      return new cdef_object_rep ();
+    }
+
+  virtual cdef_object_rep* copy (void) const
+    {
+      gripe_invalid_object ("copy");
+      return new cdef_object_rep ();
+    }
+
+  virtual cdef_object_rep* make_array (void) const
+    {
+      gripe_invalid_object ("make_array");
+      return new cdef_object_rep ();
+    }
+
+  virtual bool is_array (void) const { return false; }
+
   virtual bool is_class (void) const { return false; }
 
   virtual bool is_property (void) const { return false; }
@@ -71,6 +91,12 @@
 
   virtual bool is_package (void) const { return false; }
 
+  virtual Array<cdef_object> array_value (void) const
+    {
+      gripe_invalid_object ("array_value");
+      return Array<cdef_object> ();
+    }
+
   virtual void put (const std::string&, const octave_value&)
     { gripe_invalid_object ("put"); }
 
@@ -199,6 +225,17 @@
   cdef_object clone (void) const
     { return cdef_object (rep->clone ()); }
 
+  cdef_object empty_clone (void) const
+    { return cdef_object (rep->empty_clone ()); }
+
+  cdef_object make_array (void) const
+    { return cdef_object (rep->make_array ()); }
+
+  cdef_object copy (void) const
+    { return cdef_object (rep->copy ()); }
+
+  bool is_array (void) const { return rep->is_array (); }
+
   bool is_class (void) const { return rep->is_class (); }
 
   bool is_property (void) const { return rep->is_property (); }
@@ -207,6 +244,8 @@
 
   bool is_package (void) const { return rep->is_package (); }
 
+  Array<cdef_object> array_value (void) const { return rep->array_value (); }
+
   void put (const std::string& pname, const octave_value& val)
     { rep->put (pname, val); }
 
@@ -221,7 +260,10 @@
   octave_value
   subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
             const octave_value& rhs)
-    { return rep->subsasgn (type, idx, rhs); }
+    {
+      make_unique ();
+      return rep->subsasgn (type, idx, rhs);
+    }
 
   string_vector map_keys (void) const { return rep->map_keys (); }
 
@@ -248,6 +290,12 @@
 protected:
   cdef_object_rep* get_rep (void) { return rep; }
 
+  void make_unique (void)
+    {
+      if (rep->refcount > 1)
+        *this = clone ();
+    }
+
 private:
   cdef_object_rep *rep;
 };
@@ -268,6 +316,11 @@
 
   void set_class (const cdef_class& cls);
 
+  cdef_object_rep* empty_clone (void) const
+    { return new cdef_object_base (*this); }
+
+  cdef_object_rep* make_array (void) const;
+
 protected:
   // Restricted copying!
   cdef_object_base (const cdef_object_base& obj)
@@ -291,6 +344,46 @@
 };
 
 class
+cdef_object_array : public cdef_object_base
+{
+public:
+  cdef_object_array (void) : cdef_object_base () { }
+
+  cdef_object_array (const Array<cdef_object>& a)
+    : cdef_object_base (), array (a) { }
+
+  cdef_object_rep* clone (void) const
+    { return new cdef_object_array (*this); }
+
+  bool is_valid (void) const { return true; }
+
+  bool is_array (void) const { return true; }
+
+  Array<cdef_object> array_value (void) const { return array; }
+
+  octave_value_list
+  subsref (const std::string& type, const std::list<octave_value_list>& idx,
+           int nargout, size_t& skip, const cdef_class& context);
+
+  octave_value
+  subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
+            const octave_value& rhs);
+
+private:
+  Array<cdef_object> array;
+
+private:
+  void fill_empty_values (void);
+
+  // Private copying!
+  cdef_object_array (const cdef_object_array& obj)
+    : cdef_object_base (obj), array (obj.array) { }
+
+  // No assignment!
+  cdef_object_array& operator = (const cdef_object_array&);
+};
+
+class
 cdef_object_scalar : public cdef_object_base
 {
 public:
@@ -367,11 +460,18 @@
       return obj;
     }
 
+  cdef_object_rep* copy (void) const
+    { return new handle_cdef_object (*this); }
+
   bool is_valid (void) const { return true; }
 
+protected:
+  // Restricted copying!
+  handle_cdef_object (const handle_cdef_object& obj)
+    : cdef_object_scalar (obj) { }
+
 private:
-  // No copying
-  handle_cdef_object (const handle_cdef_object&);
+  // No assignment
   handle_cdef_object& operator = (const handle_cdef_object&);
 };
 
@@ -385,10 +485,9 @@
   ~value_cdef_object (void);
 
   cdef_object_rep* clone (void) const
-    {
-      value_cdef_object* obj = new value_cdef_object (*this);
-      return obj;
-    }
+    { return new value_cdef_object (*this); }
+
+  cdef_object_rep* copy (void) const { return clone (); }
 
   bool is_valid (void) const { return true; }
 
@@ -412,10 +511,12 @@
   public:
     cdef_class_rep (void)
 	: handle_cdef_object (), member_count (0), handle_class (false),
-          object_count (0) { }
+          object_count (0), meta (false) { }
 
     cdef_class_rep (const std::list<cdef_class>& superclasses);
 
+    cdef_object_rep* copy (void) const { return new cdef_class_rep (*this); }
+
     bool is_class (void) const { return true; }
 
     std::string get_name (void) const
@@ -423,6 +524,10 @@
 
     void set_name (const std::string& nm) { put ("Name", nm); }
 
+    bool is_abstract (void) const { return get ("Abstract").bool_value (); }
+
+    bool is_sealed (void) const { return get ("Sealed").bool_value (); }
+
     cdef_method find_method (const std::string& nm, bool local = false);
 
     void install_method (const cdef_method& meth);
@@ -449,6 +554,8 @@
 
     octave_value construct (const octave_value_list& args);
 
+    cdef_object construct_object (const octave_value_list& args);
+
     void initialize_object (cdef_object& obj);
 
     void run_constructor (cdef_object& obj, const octave_value_list& args);
@@ -478,6 +585,10 @@
           delete this;
       }
 
+    void mark_as_meta_class (void) { meta = true; }
+
+    bool is_meta_class (void) const { return meta; }
+
   private:
     void load_all_methods (void);
 
@@ -521,11 +632,22 @@
     // The number of objects of this class.
     octave_refcount<octave_idx_type> object_count;
 
+    // TRUE if this class is a built-in meta class.
+    bool meta;
+
     // Utility iterator typedef's.
     typedef std::map<std::string,cdef_method>::iterator method_iterator;
     typedef std::map<std::string,cdef_method>::const_iterator method_const_iterator;
     typedef std::map<std::string,cdef_property>::iterator property_iterator;
     typedef std::map<std::string,cdef_property>::const_iterator property_const_iterator;
+
+  private:
+    cdef_class_rep (const cdef_class_rep& c)
+      : handle_cdef_object (c), directory (c.directory),
+        method_map (c.method_map), property_map (c.property_map),
+        member_count (c.member_count), handle_class (c.handle_class),
+        implicit_ctor_list (c.implicit_ctor_list),
+        object_count (c.object_count), meta (c.meta) { }
   };
 
 public:
@@ -584,6 +706,10 @@
 
   string_vector get_names (void) { return get_rep ()->get_names (); }
 
+  bool is_abstract (void) const { return get_rep ()->is_abstract (); }
+
+  bool is_sealed (void) const { return get_rep ()->is_sealed (); }
+
   void set_directory (const std::string& dir)
     { get_rep ()->set_directory (dir); }
 
@@ -614,6 +740,9 @@
   octave_value construct (const octave_value_list& args)
     { return get_rep ()->construct (args); }
 
+  cdef_object construct_object (const octave_value_list& args)
+    { return get_rep ()->construct_object (args); }
+
   void initialize_object (cdef_object& obj)
     { get_rep ()->initialize_object (obj); }
 
@@ -626,6 +755,10 @@
   bool is_handle_class (void) const
     { return get_rep ()->is_handle_class (); }
 
+  void mark_as_meta_class (void) { get_rep ()->mark_as_meta_class (); }
+
+  bool is_meta_class (void) const { return get_rep ()->is_meta_class (); }
+
   static const cdef_class& meta_class (void) { return _meta_class; }
   static const cdef_class& meta_property (void) { return _meta_property; }
   static const cdef_class& meta_method (void) { return _meta_method; }
@@ -672,6 +805,8 @@
 class
 cdef_property : public cdef_object
 {
+  friend cdef_class;
+
 private:
 
   class
@@ -681,6 +816,8 @@
     cdef_property_rep (void)
 	: handle_cdef_object () { }
 
+    cdef_object_rep* copy (void) const { return new cdef_property_rep (*this); }
+
     bool is_property (void) const { return true; }
 
     std::string get_name (void) const { return get("Name").string_value (); }
@@ -689,19 +826,17 @@
 
     bool is_constant (void) const { return get("Constant").bool_value (); }
 
-    octave_value get_value (void) const { return default_value; }
+    octave_value get_value (void) const { return get ("DefaultValue"); }
 
     octave_value get_value (const cdef_object& obj);
 
-    void set_value (const octave_value& val) { default_value = val; }
-
     void set_value (cdef_object& obj, const octave_value& val);
 
   private:
-    bool is_recursive_set (const cdef_object& obj) const;
+    cdef_property_rep (const cdef_property_rep& p)
+      : handle_cdef_object (p) { }
 
-  private:
-    octave_value default_value;
+    bool is_recursive_set (const cdef_object& obj) const;
   };
 
 public:
@@ -738,8 +873,6 @@
   void set_value (cdef_object& obj, const octave_value& val)
     { get_rep ()->set_value (obj, val); }
 
-  void set_value (const octave_value& val) { get_rep ()->set_value (val); }
- 
   bool check_get_access (void) const;
   
   bool check_set_access (void) const;
@@ -759,6 +892,8 @@
 class
 cdef_method : public cdef_object
 {
+  friend cdef_class;
+
 private:
 
   class
@@ -767,6 +902,8 @@
   public:
     cdef_method_rep (void) : handle_cdef_object () { }
 
+    cdef_object_rep* copy (void) const { return new cdef_method_rep(*this); }
+
     bool is_method (void) const { return true; }
 
     std::string get_name (void) const { return get("Name").string_value (); }
@@ -787,6 +924,9 @@
     bool is_constructor (void) const;
 
   private:
+    cdef_method_rep (const cdef_method_rep& m)
+      : handle_cdef_object (m), function (m.function) { }
+
     void check_method (void);
 
   private:
@@ -907,6 +1047,16 @@
     }
 }
 
+inline cdef_object_rep*
+cdef_object_base::make_array (void) const
+{
+  cdef_object_rep* r = new cdef_object_array ();
+
+  r->set_class (get_class ());
+
+  return r;
+}
+
 inline cdef_method
 cdef_class::find_method (const std::string& nm, bool local)
 { return get_rep ()->find_method (nm, local); }
@@ -918,6 +1068,8 @@
 class
 cdef_package : public cdef_object
 {
+  friend cdef_class;
+
 private:
 
   class
@@ -926,6 +1078,8 @@
   public:
     cdef_package_rep (void) : handle_cdef_object (), member_count (0) { }
 
+    cdef_object_rep* copy (void) const { return new cdef_package_rep (*this); }
+
     bool is_package (void) const { return true; }
 
     std::string get_name (void) const { return get("Name").string_value (); }
@@ -976,6 +1130,12 @@
     typedef std::map<std::string, octave_value>::const_iterator function_const_iterator;
     typedef std::map<std::string, cdef_package>::iterator package_iterator;
     typedef std::map<std::string, cdef_package>::const_iterator package_const_iterator;
+
+  private:
+    cdef_package_rep (const cdef_package_rep& p)
+      : handle_cdef_object (p), class_map (p.class_map),
+        function_map (p.function_map), package_map (p.package_map),
+        member_count (p.member_count) { }
   };
 
 public:
@@ -1053,7 +1213,7 @@
     { return new octave_classdef (object.clone ()); }
 
   octave_base_value* empty_clone (void) const
-    { return new octave_classdef (); }
+    { return new octave_classdef (object.empty_clone ()); }
 
   cdef_object get_object (void) const { return object; }
 
@@ -1091,6 +1251,11 @@
                          const std::list<octave_value_list>& idx,
                          const octave_value& rhs);
 
+  octave_value
+  undef_subsasgn (const std::string& type,
+                  const std::list<octave_value_list>& idx,
+                  const octave_value& rhs);
+
   string_vector map_keys (void) const { return object.map_keys (); }
 
   dim_vector dims (void) const { return dim_vector (1, 1); }