Mercurial > hg > octave-lyh
diff libinterp/octave-value/ov-classdef.h @ 15896:57be060d7672 classdef
Implement full object construction and superclass references.
* libinterp/octave-value/ov-classdef.h (cdef_object_rep::subsref): Add class
context argument.
(cdef_object_rep::ctor_list): New class member.
(cdef_object_rep::mark_for_construction, cdef_object_rep::is_constructed_for,
cdef_object_rep::is_partially_constructed_for,
cdef_object_rep::mark_as_constructed, cdef_object_rep::is_constructed,
cdef_object::mark_for_construction, cdef_object::is_constructed_for,
cdef_object::is_partially_constructed_for, cdef_object::mark_as_constructed,
cdef_object:is_constructed): New methods to manipulate the new ctor_list
class member.
(cdef_object_rep::cdef_object_rep (const cdef_object_rep&)): New copy
constructor.
(cdef_class::cdef_class_rep (std::string, std::list<cdef_class>)): New
utility constructor.
(cdef_class (std::string, std::list<cdef_class>)): Likewise.
(cdef_class::cdef_class_rep::implicit_ctor_list): New class member.
(cdef_method::cdef_method_rep::is_constructor, cdef_method::is_construcror):
New methods.
(cdef_method::get_function): Likewise.
(cdef_package::cdef_package_rep::subsref): Remove method.
(octave_classdef::get_object_ref): New method.
(to_cdef_ref): New function.
* libinterp/octave-value/ov-classdef.cc (is_superclass): Add max_depth argument.
(is_direct_superclass): New utility function.
(get_class_context): Add bool and std::string return values, as new reference
arguments. Add overload without any arguments.
(check_access): Check for valid class context when required.
(make_class): Remove super_name_list argument. Do not set SuperClasses
explicitly, use new cdef_class constructor instead.
(octave_classdef::subsref): Change skip variable to size_t (avoids compilation
warning). Call cdef_object::subsref with additional class context argument.
(class octave_classdef_superclass_ref): New utility class.
(F__superclass_reference__): Use it.
(cdef_object_rep::subsref): Add class context argument.
(cdef_object_rep::mark_for_construction): New method.
(handle_cdef_object::~handle_cdef_object, value_cdef_object::~value_cdef_object,
cdef_class::cdef_class_rep::subsref_meta, cdef_class::make_meta_class): Use gnulib::printf explicitly.
(cdef_class::cdef_class_rep (std::string, std::list<cdef_class>)): New
constructor.
(class ctor_analyzer): New utility class.
(cdef_class::cdef_class_rep::install_method): Use it to analyze constructors
and detect explicit superclass constructor calls.
(cdef_class::cdef_class_rep::initialize_object): Call
cdef_object::mark_for_construction.
(cdef_class::cdef_class_rep::run_constructor): Run all implicit superclass
constructors first.
(cdef_class::cdef_class_rep::construct): Call cdef_object::mark_as_constructed.
(cdef_class::make_meta_class): Remove snamelist variable.
(cdef_property::cdef_property_rep::get_value,
cdef_property::cdef_property_rep::set_value): Check if object is partially
constructed for the property-defining class.
(cdef_method::cdef_method_rep::is_constructor): New method.
(cdef_package::cdef_package_rep::subsref): Delete method.
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Thu, 03 Jan 2013 21:01:11 -0500 |
parents | 2b6fe094e615 |
children | b8bff84022d6 |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.h +++ b/libinterp/octave-value/ov-classdef.h @@ -77,13 +77,13 @@ } } - virtual octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, int& skip); + virtual octave_value_list + subsref (const std::string& type, const std::list<octave_value_list>& idx, + int nargout, size_t& skip, const cdef_class& context); - virtual octave_value subsasgn (const std::string& type, - const std::list<octave_value_list>& idx, - const octave_value& rhs); + 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; @@ -91,8 +91,41 @@ std::string class_name (void) const { return cname; } - void set_class_name (const std::string& nm) - { cname = nm; } + void set_class_name (const std::string& nm) { cname = nm; } + + void mark_for_construction (const cdef_class&); + + //bool is_constructed_for (const cdef_class&) const; + + bool is_constructed_for (const std::string& nm) const + { + return (is_constructed () + || ctor_list.find (nm) == ctor_list.end ()); + } + + bool is_partially_constructed_for (const std::string& nm) const + { + std::map< std::string, std::list<std::string> >::const_iterator it; + + if (is_constructed ()) + return true; + else if ((it = ctor_list.find (nm)) == ctor_list.end () + || it->second.empty ()) + return true; + + for (std::list<std::string>::const_iterator lit = it->second.begin (); + lit != it->second.end (); ++lit) + if (! is_constructed_for (*lit)) + return false; + + return true; + } + + void mark_as_constructed (void) { ctor_list.clear (); } + + void mark_as_constructed (const std::string& nm) { ctor_list.erase (nm); } + + bool is_constructed (void) const { return ctor_list.empty (); } protected: /* reference count */ @@ -104,9 +137,17 @@ /* object property values */ Octave_map map; + /* Internal/temporary structure used during object construction */ + std::map< std::string, std::list<std::string> > ctor_list; + +protected: + /* Restricted copying */ + cdef_object_rep (const cdef_object_rep& r) + : refcount (1), cname (r.cname), map (r.map), + ctor_list (r.ctor_list) { } + private: - // No copying - cdef_object_rep (const cdef_object_rep&); + /* No assignment */ cdef_object_rep& operator = (const cdef_object_rep& ); }; @@ -164,14 +205,14 @@ octave_value get (const std::string& pname) const { return rep->get (pname); } - octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, int& skip) - { return rep->subsref (type, idx, nargout, skip); } + octave_value_list + subsref (const std::string& type, const std::list<octave_value_list>& idx, + int nargout, size_t& skip, const cdef_class& context) + { return rep->subsref (type, idx, nargout, skip, context); } - octave_value subsasgn (const std::string& type, - const std::list<octave_value_list>& idx, - const octave_value& rhs) + octave_value + subsasgn (const std::string& type, const std::list<octave_value_list>& idx, + const octave_value& rhs) { return rep->subsasgn (type, idx, rhs); } string_vector map_keys (void) const { return rep->map_keys (); } @@ -180,6 +221,22 @@ bool ok (void) const { return rep->is_valid (); } + void mark_for_construction (const cdef_class& cls) + { rep->mark_for_construction (cls); } + + bool is_constructed (void) const { return rep->is_constructed (); } + + bool is_constructed_for (const std::string& nm) const + { return rep->is_constructed_for (nm); } + + bool is_partially_constructed_for (const std::string& nm) const + { return rep->is_partially_constructed_for (nm); } + + void mark_as_constructed (void) { rep->mark_as_constructed (); } + + void mark_as_constructed (const std::string& nm) + { rep->mark_as_constructed (nm); } + protected: cdef_object_rep* get_rep (void) { return rep; } @@ -253,6 +310,9 @@ cdef_class_rep (const std::string& nm) : handle_cdef_object (nm), handle_class (false) { } + cdef_class_rep (const std::string& nm, + const std::list<cdef_class>& superclasses); + std::string get_name (void) const { return get ("Name").string_value (); } @@ -276,9 +336,9 @@ void delete_object (cdef_object obj); - octave_value_list subsref_meta (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout); + octave_value_list + subsref_meta (const std::string& type, + const std::list<octave_value_list>& idx, int nargout); octave_value construct (const octave_value_list& args); @@ -316,6 +376,11 @@ // class when the abstract "handle" class is one of its superclasses. bool handle_class; + // The list of super-class constructors that are called implicitly by the + // the classdef engine when creating an object. These constructors are not + // called explicitly by the class constructor. + std::list<std::string> implicit_ctor_list; + // 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; @@ -331,6 +396,10 @@ cdef_class (const std::string& nm) : cdef_object (new cdef_class_rep (nm)) { } + cdef_class (const std::string& nm, + const std::list<cdef_class>& superclasses) + : cdef_object (new cdef_class_rep (nm, superclasses)) { } + cdef_class (const cdef_class& cls) : cdef_object (cls) { } @@ -533,14 +602,15 @@ octave_value get_function (void) const { return function; } - void set_function (const octave_value& fcn) - { function = fcn; } + void set_function (const octave_value& fcn) { function = fcn; } octave_value_list execute (const octave_value_list& args, int nargout); octave_value_list execute (const cdef_object& obj, const octave_value_list& args, int nargout); + bool is_constructor (void) const; + private: void check_method (void); @@ -593,6 +663,12 @@ void set_function (const octave_value& fcn) { get_rep ()->set_function (fcn); } + octave_value get_function (void) const + { return get_rep ()->get_function (); } + + bool is_constructor (void) const + { return get_rep ()->is_constructor (); } + private: cdef_method_rep* get_rep (void) { return dynamic_cast<cdef_method_rep *> (cdef_object::get_rep ()); } @@ -631,10 +707,6 @@ void install_package (const cdef_package& pack, const std::string& nm); - octave_value_list subsref (const std::string& type, - const std::list<octave_value_list>& idx, - int nargout, int& skip); - Cell get_classes (void) const; Cell get_functions (void) const; @@ -721,8 +793,9 @@ octave_base_value* empty_clone (void) const { return new octave_classdef (); } - cdef_object get_object (void) const - { return object; } + cdef_object get_object (void) const { return object; } + + cdef_object& get_object_ref (void) { return object; } bool is_defined (void) const { return true; } @@ -807,6 +880,20 @@ } } +inline cdef_object& +to_cdef_ref (octave_value& val) +{ + static cdef_object empty; + + if (val.type_name () == "object") + return dynamic_cast<octave_classdef *> (val.internal_rep ())->get_object_ref (); + else + { + warning ("trying to cast non-object into object"); + return empty; + } +} + inline cdef_object to_cdef (const cdef_object& obj) { return obj; }