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);