Mercurial > octave-nkf
comparison 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 |
comparison
equal
deleted
inserted
replaced
15895:ce8ad12ce8a0 | 15896:57be060d7672 |
---|---|
75 error ("get: unknown slot: %s", pname.c_str ()); | 75 error ("get: unknown slot: %s", pname.c_str ()); |
76 return octave_value (); | 76 return octave_value (); |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 virtual octave_value_list subsref (const std::string& type, | 80 virtual octave_value_list |
81 const std::list<octave_value_list>& idx, | 81 subsref (const std::string& type, const std::list<octave_value_list>& idx, |
82 int nargout, int& skip); | 82 int nargout, size_t& skip, const cdef_class& context); |
83 | 83 |
84 virtual octave_value subsasgn (const std::string& type, | 84 virtual octave_value |
85 const std::list<octave_value_list>& idx, | 85 subsasgn (const std::string& type, const std::list<octave_value_list>& idx, |
86 const octave_value& rhs); | 86 const octave_value& rhs); |
87 | 87 |
88 virtual string_vector map_keys(void) const; | 88 virtual string_vector map_keys(void) const; |
89 | 89 |
90 virtual bool is_valid (void) const { return false; } | 90 virtual bool is_valid (void) const { return false; } |
91 | 91 |
92 std::string class_name (void) const { return cname; } | 92 std::string class_name (void) const { return cname; } |
93 | 93 |
94 void set_class_name (const std::string& nm) | 94 void set_class_name (const std::string& nm) { cname = nm; } |
95 { cname = nm; } | 95 |
96 void mark_for_construction (const cdef_class&); | |
97 | |
98 //bool is_constructed_for (const cdef_class&) const; | |
99 | |
100 bool is_constructed_for (const std::string& nm) const | |
101 { | |
102 return (is_constructed () | |
103 || ctor_list.find (nm) == ctor_list.end ()); | |
104 } | |
105 | |
106 bool is_partially_constructed_for (const std::string& nm) const | |
107 { | |
108 std::map< std::string, std::list<std::string> >::const_iterator it; | |
109 | |
110 if (is_constructed ()) | |
111 return true; | |
112 else if ((it = ctor_list.find (nm)) == ctor_list.end () | |
113 || it->second.empty ()) | |
114 return true; | |
115 | |
116 for (std::list<std::string>::const_iterator lit = it->second.begin (); | |
117 lit != it->second.end (); ++lit) | |
118 if (! is_constructed_for (*lit)) | |
119 return false; | |
120 | |
121 return true; | |
122 } | |
123 | |
124 void mark_as_constructed (void) { ctor_list.clear (); } | |
125 | |
126 void mark_as_constructed (const std::string& nm) { ctor_list.erase (nm); } | |
127 | |
128 bool is_constructed (void) const { return ctor_list.empty (); } | |
96 | 129 |
97 protected: | 130 protected: |
98 /* reference count */ | 131 /* reference count */ |
99 octave_refcount<int> refcount; | 132 octave_refcount<int> refcount; |
100 | 133 |
102 std::string cname; | 135 std::string cname; |
103 | 136 |
104 /* object property values */ | 137 /* object property values */ |
105 Octave_map map; | 138 Octave_map map; |
106 | 139 |
107 private: | 140 /* Internal/temporary structure used during object construction */ |
108 // No copying | 141 std::map< std::string, std::list<std::string> > ctor_list; |
109 cdef_object_rep (const cdef_object_rep&); | 142 |
143 protected: | |
144 /* Restricted copying */ | |
145 cdef_object_rep (const cdef_object_rep& r) | |
146 : refcount (1), cname (r.cname), map (r.map), | |
147 ctor_list (r.ctor_list) { } | |
148 | |
149 private: | |
150 /* No assignment */ | |
110 cdef_object_rep& operator = (const cdef_object_rep& ); | 151 cdef_object_rep& operator = (const cdef_object_rep& ); |
111 }; | 152 }; |
112 | 153 |
113 class | 154 class |
114 cdef_object | 155 cdef_object |
162 { rep->put (pname, val); } | 203 { rep->put (pname, val); } |
163 | 204 |
164 octave_value get (const std::string& pname) const | 205 octave_value get (const std::string& pname) const |
165 { return rep->get (pname); } | 206 { return rep->get (pname); } |
166 | 207 |
167 octave_value_list subsref (const std::string& type, | 208 octave_value_list |
168 const std::list<octave_value_list>& idx, | 209 subsref (const std::string& type, const std::list<octave_value_list>& idx, |
169 int nargout, int& skip) | 210 int nargout, size_t& skip, const cdef_class& context) |
170 { return rep->subsref (type, idx, nargout, skip); } | 211 { return rep->subsref (type, idx, nargout, skip, context); } |
171 | 212 |
172 octave_value subsasgn (const std::string& type, | 213 octave_value |
173 const std::list<octave_value_list>& idx, | 214 subsasgn (const std::string& type, const std::list<octave_value_list>& idx, |
174 const octave_value& rhs) | 215 const octave_value& rhs) |
175 { return rep->subsasgn (type, idx, rhs); } | 216 { return rep->subsasgn (type, idx, rhs); } |
176 | 217 |
177 string_vector map_keys (void) const { return rep->map_keys (); } | 218 string_vector map_keys (void) const { return rep->map_keys (); } |
178 | 219 |
179 const cdef_object_rep* get_rep (void) const { return rep; } | 220 const cdef_object_rep* get_rep (void) const { return rep; } |
180 | 221 |
181 bool ok (void) const { return rep->is_valid (); } | 222 bool ok (void) const { return rep->is_valid (); } |
223 | |
224 void mark_for_construction (const cdef_class& cls) | |
225 { rep->mark_for_construction (cls); } | |
226 | |
227 bool is_constructed (void) const { return rep->is_constructed (); } | |
228 | |
229 bool is_constructed_for (const std::string& nm) const | |
230 { return rep->is_constructed_for (nm); } | |
231 | |
232 bool is_partially_constructed_for (const std::string& nm) const | |
233 { return rep->is_partially_constructed_for (nm); } | |
234 | |
235 void mark_as_constructed (void) { rep->mark_as_constructed (); } | |
236 | |
237 void mark_as_constructed (const std::string& nm) | |
238 { rep->mark_as_constructed (nm); } | |
182 | 239 |
183 protected: | 240 protected: |
184 cdef_object_rep* get_rep (void) { return rep; } | 241 cdef_object_rep* get_rep (void) { return rep; } |
185 | 242 |
186 private: | 243 private: |
251 { | 308 { |
252 public: | 309 public: |
253 cdef_class_rep (const std::string& nm) | 310 cdef_class_rep (const std::string& nm) |
254 : handle_cdef_object (nm), handle_class (false) { } | 311 : handle_cdef_object (nm), handle_class (false) { } |
255 | 312 |
313 cdef_class_rep (const std::string& nm, | |
314 const std::list<cdef_class>& superclasses); | |
315 | |
256 std::string get_name (void) const | 316 std::string get_name (void) const |
257 { return get ("Name").string_value (); } | 317 { return get ("Name").string_value (); } |
258 | 318 |
259 cdef_method find_method (const std::string& nm, bool local = false); | 319 cdef_method find_method (const std::string& nm, bool local = false); |
260 | 320 |
274 | 334 |
275 std::string get_directory (void) const { return directory; } | 335 std::string get_directory (void) const { return directory; } |
276 | 336 |
277 void delete_object (cdef_object obj); | 337 void delete_object (cdef_object obj); |
278 | 338 |
279 octave_value_list subsref_meta (const std::string& type, | 339 octave_value_list |
280 const std::list<octave_value_list>& idx, | 340 subsref_meta (const std::string& type, |
281 int nargout); | 341 const std::list<octave_value_list>& idx, int nargout); |
282 | 342 |
283 octave_value construct (const octave_value_list& args); | 343 octave_value construct (const octave_value_list& args); |
284 | 344 |
285 void initialize_object (cdef_object& obj); | 345 void initialize_object (cdef_object& obj); |
286 | 346 |
313 std::map<std::string,cdef_property> property_map; | 373 std::map<std::string,cdef_property> property_map; |
314 | 374 |
315 // TRUE if this class is a handle class. A class is a handle | 375 // TRUE if this class is a handle class. A class is a handle |
316 // class when the abstract "handle" class is one of its superclasses. | 376 // class when the abstract "handle" class is one of its superclasses. |
317 bool handle_class; | 377 bool handle_class; |
378 | |
379 // The list of super-class constructors that are called implicitly by the | |
380 // the classdef engine when creating an object. These constructors are not | |
381 // called explicitly by the class constructor. | |
382 std::list<std::string> implicit_ctor_list; | |
318 | 383 |
319 // Utility iterator typedef's. | 384 // Utility iterator typedef's. |
320 typedef std::map<std::string,cdef_method>::iterator method_iterator; | 385 typedef std::map<std::string,cdef_method>::iterator method_iterator; |
321 typedef std::map<std::string,cdef_method>::const_iterator method_const_iterator; | 386 typedef std::map<std::string,cdef_method>::const_iterator method_const_iterator; |
322 typedef std::map<std::string,cdef_property>::iterator property_iterator; | 387 typedef std::map<std::string,cdef_property>::iterator property_iterator; |
329 : cdef_object () { } | 394 : cdef_object () { } |
330 | 395 |
331 cdef_class (const std::string& nm) | 396 cdef_class (const std::string& nm) |
332 : cdef_object (new cdef_class_rep (nm)) { } | 397 : cdef_object (new cdef_class_rep (nm)) { } |
333 | 398 |
399 cdef_class (const std::string& nm, | |
400 const std::list<cdef_class>& superclasses) | |
401 : cdef_object (new cdef_class_rep (nm, superclasses)) { } | |
402 | |
334 cdef_class (const cdef_class& cls) | 403 cdef_class (const cdef_class& cls) |
335 : cdef_object (cls) { } | 404 : cdef_object (cls) { } |
336 | 405 |
337 cdef_class (const cdef_object& obj) | 406 cdef_class (const cdef_object& obj) |
338 : cdef_object (obj) | 407 : cdef_object (obj) |
531 cdef_method_rep (const std::string& nm) | 600 cdef_method_rep (const std::string& nm) |
532 : handle_cdef_object (nm) { } | 601 : handle_cdef_object (nm) { } |
533 | 602 |
534 octave_value get_function (void) const { return function; } | 603 octave_value get_function (void) const { return function; } |
535 | 604 |
536 void set_function (const octave_value& fcn) | 605 void set_function (const octave_value& fcn) { function = fcn; } |
537 { function = fcn; } | |
538 | 606 |
539 octave_value_list execute (const octave_value_list& args, int nargout); | 607 octave_value_list execute (const octave_value_list& args, int nargout); |
540 | 608 |
541 octave_value_list execute (const cdef_object& obj, | 609 octave_value_list execute (const cdef_object& obj, |
542 const octave_value_list& args, int nargout); | 610 const octave_value_list& args, int nargout); |
611 | |
612 bool is_constructor (void) const; | |
543 | 613 |
544 private: | 614 private: |
545 void check_method (void); | 615 void check_method (void); |
546 | 616 |
547 private: | 617 private: |
590 bool is_static (void) const | 660 bool is_static (void) const |
591 { return get ("Static").bool_value (); } | 661 { return get ("Static").bool_value (); } |
592 | 662 |
593 void set_function (const octave_value& fcn) | 663 void set_function (const octave_value& fcn) |
594 { get_rep ()->set_function (fcn); } | 664 { get_rep ()->set_function (fcn); } |
665 | |
666 octave_value get_function (void) const | |
667 { return get_rep ()->get_function (); } | |
668 | |
669 bool is_constructor (void) const | |
670 { return get_rep ()->is_constructor (); } | |
595 | 671 |
596 private: | 672 private: |
597 cdef_method_rep* get_rep (void) | 673 cdef_method_rep* get_rep (void) |
598 { return dynamic_cast<cdef_method_rep *> (cdef_object::get_rep ()); } | 674 { return dynamic_cast<cdef_method_rep *> (cdef_object::get_rep ()); } |
599 | 675 |
628 void install_class (const cdef_class& cls, const std::string& nm); | 704 void install_class (const cdef_class& cls, const std::string& nm); |
629 | 705 |
630 void install_function (const octave_value& fcn, const std::string& nm); | 706 void install_function (const octave_value& fcn, const std::string& nm); |
631 | 707 |
632 void install_package (const cdef_package& pack, const std::string& nm); | 708 void install_package (const cdef_package& pack, const std::string& nm); |
633 | |
634 octave_value_list subsref (const std::string& type, | |
635 const std::list<octave_value_list>& idx, | |
636 int nargout, int& skip); | |
637 | 709 |
638 Cell get_classes (void) const; | 710 Cell get_classes (void) const; |
639 | 711 |
640 Cell get_functions (void) const; | 712 Cell get_functions (void) const; |
641 | 713 |
719 { return new octave_classdef (object.clone ()); } | 791 { return new octave_classdef (object.clone ()); } |
720 | 792 |
721 octave_base_value* empty_clone (void) const | 793 octave_base_value* empty_clone (void) const |
722 { return new octave_classdef (); } | 794 { return new octave_classdef (); } |
723 | 795 |
724 cdef_object get_object (void) const | 796 cdef_object get_object (void) const { return object; } |
725 { return object; } | 797 |
798 cdef_object& get_object_ref (void) { return object; } | |
726 | 799 |
727 bool is_defined (void) const { return true; } | 800 bool is_defined (void) const { return true; } |
728 | 801 |
729 bool is_map (void) const { return true; } | 802 bool is_map (void) const { return true; } |
730 | 803 |
805 warning ("trying to cast non-object into object"); | 878 warning ("trying to cast non-object into object"); |
806 return cdef_object (); | 879 return cdef_object (); |
807 } | 880 } |
808 } | 881 } |
809 | 882 |
883 inline cdef_object& | |
884 to_cdef_ref (octave_value& val) | |
885 { | |
886 static cdef_object empty; | |
887 | |
888 if (val.type_name () == "object") | |
889 return dynamic_cast<octave_classdef *> (val.internal_rep ())->get_object_ref (); | |
890 else | |
891 { | |
892 warning ("trying to cast non-object into object"); | |
893 return empty; | |
894 } | |
895 } | |
896 | |
810 inline cdef_object | 897 inline cdef_object |
811 to_cdef (const cdef_object& obj) | 898 to_cdef (const cdef_object& obj) |
812 { return obj; } | 899 { return obj; } |
813 | 900 |
814 OCTINTERP_API void install_classdef (void); | 901 OCTINTERP_API void install_classdef (void); |