GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
cdef-class.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_cdef_class_h)
27 #define octave_cdef_class_h 1
28 
29 #include "octave-config.h"
30 
31 #include <map>
32 #include <set>
33 #include <string>
34 
35 #include "oct-refcount.h"
36 
37 #include "cdef-method.h"
38 #include "cdef-object.h"
39 #include "cdef-package.h"
40 #include "cdef-property.h"
41 #include "error.h"
42 #include "ov.h"
43 #include "ovl.h"
44 
45 namespace octave
46 {
47  class interpreter;
48  class tree_classdef;
49 
50  class
52  {
53  private:
54 
55  class
57  {
58  public:
60  : cdef_meta_object_rep (), member_count (0), handle_class (false),
61  meta (false)
62  { }
63 
64  cdef_class_rep (const std::list<cdef_class>& superclasses);
65 
66  cdef_class_rep& operator = (const cdef_class_rep&) = delete;
67 
68  ~cdef_class_rep (void) = default;
69 
70  cdef_object_rep * copy (void) const { return new cdef_class_rep (*this); }
71 
72  bool is_class (void) const { return true; }
73 
74  std::string get_name (void) const
75  { return get ("Name").string_value (); }
76 
77  void set_name (const std::string& nm) { put ("Name", nm); }
78 
79  bool is_abstract (void) const { return get ("Abstract").bool_value (); }
80 
81  bool is_sealed (void) const { return get ("Sealed").bool_value (); }
82 
83  cdef_method find_method (const std::string& nm, bool local = false);
84 
85  void install_method (const cdef_method& meth);
86 
87  Cell get_methods (bool include_ctor);
88 
89  std::map<std::string, cdef_method>
90  get_method_map (bool only_inherited, bool include_ctor);
91 
92  cdef_property find_property (const std::string& nm);
93 
94  void install_property (const cdef_property& prop);
95 
96  Cell get_properties (int mode);
97 
98  std::map<std::string, cdef_property> get_property_map (int mode);
99 
100  string_vector get_names (void);
101 
102  void set_directory (const std::string& dir) { directory = dir; }
103 
104  std::string get_directory (void) const { return directory; }
105 
106  void delete_object (const cdef_object& obj);
107 
109  meta_subsref (const std::string& type,
110  const std::list<octave_value_list>& idx, int nargout);
111 
112  void meta_release (void);
113 
115  {
116  return (type == '(' || type == '.');
117  }
118 
119  octave_value get_method (const std::string& name) const;
120 
121  octave_value construct (const octave_value_list& args);
122 
123  cdef_object construct_object (const octave_value_list& args);
124 
125  void initialize_object (cdef_object& obj);
126 
127  void run_constructor (cdef_object& obj, const octave_value_list& args);
128 
129  void mark_as_handle_class (void) { handle_class = true; }
130 
131  bool is_handle_class (void) const { return handle_class; }
132 
133  octave_idx_type static_count (void) const { return member_count; }
134 
135  void destroy (void)
136  {
137  if (member_count)
138  {
139  m_count++;
140  cdef_class lock (this);
141 
142  member_count = 0;
143  method_map.clear ();
144  property_map.clear ();
145  }
146  else
147  delete this;
148  }
149 
150  void mark_as_meta_class (void) { meta = true; }
151 
152  bool is_meta_class (void) const { return meta; }
153 
154  void doc_string (const std::string& txt) { m_doc_string = txt; }
155 
156  std::string doc_string (void) const { return m_doc_string; }
157 
158  private:
159 
160  void load_all_methods (void);
161 
162  void find_names (std::set<std::string>& names, bool all);
163 
164  void find_properties (std::map<std::string,cdef_property>& props,
165  int mode = 0);
166 
167  void find_methods (std::map<std::string, cdef_method>& meths,
168  bool only_inherited, bool include_ctor = false);
169 
171  {
172  m_count++;
173  return cdef_class (this);
174  }
175 
176  // The @-directory were this class is loaded from.
177  // (not used yet)
178 
179  std::string directory;
180 
181  std::string m_doc_string;
182 
183  // The methods defined by this class.
184 
185  std::map<std::string,cdef_method> method_map;
186 
187  // The properties defined by this class.
188 
189  std::map<std::string,cdef_property> property_map;
190 
191  // The number of members in this class (methods, properties...)
192 
194 
195  // TRUE if this class is a handle class. A class is a handle
196  // class when the abstract "handle" class is one of its superclasses.
197 
199 
200  // The list of super-class constructors that are called implicitly by the
201  // the classdef engine when creating an object. These constructors are not
202  // called explicitly by the class constructor.
203 
204  std::list<cdef_class> implicit_ctor_list;
205 
206  // TRUE if this class is a built-in meta class.
207 
208  bool meta;
209 
210  // Utility iterator typedefs.
211 
212  typedef std::map<std::string,cdef_method>::iterator method_iterator;
213  typedef std::map<std::string,cdef_method>::const_iterator method_const_iterator;
214  typedef std::map<std::string,cdef_property>::iterator property_iterator;
215  typedef std::map<std::string,cdef_property>::const_iterator property_const_iterator;
216 
217  cdef_class_rep (const cdef_class_rep& c) = default;
218  };
219 
220  public:
221 
222  // Create an invalid class object.
223 
224  cdef_class (void) : cdef_meta_object () { }
225 
226  cdef_class (const std::string& nm, const std::list<cdef_class>& superclasses)
227  : cdef_meta_object (new cdef_class_rep (superclasses))
228  {
229  get_rep ()->set_name (nm);
230  }
231 
232  cdef_class (const cdef_class& cls) : cdef_meta_object (cls) { }
233 
234  cdef_class (const cdef_object& obj)
235  : cdef_meta_object (obj)
236  {
237  // This should never happen...
238  if (! is_class ())
239  error ("internal error: invalid assignment from %s to meta.class object",
240  class_name ().c_str ());
241  }
242 
243  cdef_class& operator = (const cdef_class& cls)
244  {
246 
247  return *this;
248  }
249 
250  ~cdef_class (void) = default;
251 
252  cdef_method find_method (const std::string& nm, bool local = false);
253 
254  void install_method (const cdef_method& meth)
255  {
256  get_rep ()->install_method (meth);
257  }
258 
259  Cell get_methods (bool include_ctor = false)
260  {
261  return get_rep ()->get_methods (include_ctor);
262  }
263 
264  std::map<std::string, cdef_method>
265  get_method_map (bool only_inherited = false, bool include_ctor = false)
266  {
267  return get_rep ()->get_method_map (only_inherited, include_ctor);
268  }
269 
270  cdef_property find_property (const std::string& nm);
271 
272  void install_property (const cdef_property& prop)
273  {
274  get_rep ()->install_property (prop);
275  }
276 
277  Cell get_properties (int mode = property_normal)
278  {
279  return get_rep ()->get_properties (mode);
280  }
281 
282  std::map<std::string, cdef_property>
283  get_property_map (int mode = property_normal)
284  {
285  return get_rep ()->get_property_map (mode);
286  }
287 
288  string_vector get_names (void) { return get_rep ()->get_names (); }
289 
290  bool is_abstract (void) const { return get_rep ()->is_abstract (); }
291 
292  bool is_sealed (void) const { return get_rep ()->is_sealed (); }
293 
294  void set_directory (const std::string& dir)
295  {
296  get_rep ()->set_directory (dir);
297  }
298 
299  std::string get_directory (void) const
300  {
301  return get_rep ()->get_directory ();
302  }
303 
304  std::string get_name (void) const { return get_rep ()->get_name (); }
305 
306  bool is_builtin (void) const { return get_directory ().empty (); }
307 
308  void delete_object (const cdef_object& obj)
309  {
310  get_rep ()->delete_object (obj);
311  }
312 
313  //! Analyze the tree_classdef tree and transform it to a cdef_class
314  //!
315  //! <b>All attribute validation should occur here.</b>
316  //!
317  //! Classdef attribute values can be given in the form of
318  //! expressions. These expressions must be evaluated before
319  //! assigning them as attribute values. Evaluating them as they are
320  //! parsed causes trouble with possible recursion in the parser so we
321  //! do it here. For example
322  //!
323  //! @code
324  //! classdef recursion_class
325  //! methods (Access = ?recursion_class)
326  //! endmethods
327  //! endclassdef
328  //! @endcode
329  //!
330  //! will fail because each attempt to compute the metaclass of
331  //! recursion_class will cause recursion_class to be parsed again.
332 
333  static cdef_class
334  make_meta_class (interpreter& interp, tree_classdef *t,
335  bool is_at_folder = false);
336 
337  octave_value get_method (const std::string& nm) const
338  {
339  return get_rep ()->get_method (nm);
340  }
341 
342  octave_value get_method_function (const std::string& nm);
343 
345  {
346  return get_method_function (get_name ());
347  }
348 
350  {
351  return get_rep ()->construct (args);
352  }
353 
355  {
356  return get_rep ()->construct_object (args);
357  }
358 
360  {
361  get_rep ()->initialize_object (obj);
362  }
363 
365  {
366  get_rep ()->run_constructor (obj, args);
367  }
368 
370  {
371  get_rep ()->mark_as_handle_class ();
372  }
373 
374  bool is_handle_class (void) const
375  {
376  return get_rep ()->is_handle_class ();
377  }
378 
379  void mark_as_meta_class (void) { get_rep ()->mark_as_meta_class (); }
380 
381  bool is_meta_class (void) const { return get_rep ()->is_meta_class (); }
382 
383  void doc_string (const std::string& txt) { get_rep ()->doc_string (txt); }
384 
385  std::string doc_string (void) const { return get_rep ()->doc_string (); }
386 
387  public:
388 
389  enum
390  {
393  property_all
394  };
395 
396  private:
397 
399  {
400  return dynamic_cast<cdef_class_rep *> (cdef_object::get_rep ());
401  }
402 
403  const cdef_class_rep * get_rep (void) const
404  {
405  return dynamic_cast<const cdef_class_rep *> (cdef_object::get_rep ());
406  }
407 
408  friend bool operator == (const cdef_class&, const cdef_class&);
409  friend bool operator != (const cdef_class&, const cdef_class&);
410  friend bool operator < (const cdef_class&, const cdef_class&);
411 
412  friend void install_classdef (interpreter& interp);
413  };
414 
415  inline bool
416  operator == (const cdef_class& clsa, const cdef_class& clsb)
417  {
418  // FIXME: is this really the right way to check class equality?
419 
420  return (clsa.get_rep () == clsb.get_rep ());
421  }
422 
423  inline bool
424  operator != (const cdef_class& clsa, const cdef_class& clsb)
425  {
426  return ! (clsa == clsb);
427  }
428 
429  // This is only to be able to use cdef_class as map keys.
430 
431  inline bool
432  operator < (const cdef_class& clsa, const cdef_class& clsb)
433  {
434  return clsa.get_rep () < clsb.get_rep ();
435  }
436 
437  inline cdef_method
438  cdef_class::find_method (const std::string& nm, bool local)
439  {
440  return get_rep ()->find_method (nm, local);
441  }
442 
443  inline cdef_property
444  cdef_class::find_property (const std::string& nm)
445  {
446  return get_rep ()->find_property (nm);
447  }
448 }
449 
450 #endif
Definition: Cell.h:43
void set_name(const std::string &nm)
Definition: cdef-class.h:77
octave_idx_type static_count(void) const
Definition: cdef-class.h:133
std::string doc_string(void) const
Definition: cdef-class.h:156
bool meta_accepts_postfix_index(char type) const
Definition: cdef-class.h:114
std::map< std::string, cdef_property >::iterator property_iterator
Definition: cdef-class.h:214
cdef_property find_property(const std::string &nm)
Definition: cdef-class.cc:358
void set_directory(const std::string &dir)
Definition: cdef-class.h:102
cdef_class_rep(const cdef_class_rep &c)=default
std::map< std::string, cdef_method > method_map
Definition: cdef-class.h:185
std::map< std::string, cdef_method >::const_iterator method_const_iterator
Definition: cdef-class.h:213
std::list< cdef_class > implicit_ctor_list
Definition: cdef-class.h:204
void doc_string(const std::string &txt)
Definition: cdef-class.h:154
cdef_object_rep * copy(void) const
Definition: cdef-class.h:70
std::map< std::string, cdef_property >::const_iterator property_const_iterator
Definition: cdef-class.h:215
std::map< std::string, cdef_method >::iterator method_iterator
Definition: cdef-class.h:212
cdef_method find_method(const std::string &nm, bool local=false)
Definition: cdef-class.cc:92
std::map< std::string, cdef_property > property_map
Definition: cdef-class.h:189
std::string get_name(void) const
Definition: cdef-class.h:74
std::string get_directory(void) const
Definition: cdef-class.h:104
~cdef_class(void)=default
std::string doc_string(void) const
Definition: cdef-class.h:385
Cell get_methods(bool include_ctor=false)
Definition: cdef-class.h:259
void delete_object(const cdef_object &obj)
Definition: cdef-class.h:308
friend void install_classdef(interpreter &interp)
void set_directory(const std::string &dir)
Definition: cdef-class.h:294
void install_property(const cdef_property &prop)
Definition: cdef-class.h:272
bool is_builtin(void) const
Definition: cdef-class.h:306
void doc_string(const std::string &txt)
Definition: cdef-class.h:383
void install_method(const cdef_method &meth)
Definition: cdef-class.h:254
bool is_meta_class(void) const
Definition: cdef-class.h:381
cdef_class(const cdef_object &obj)
Definition: cdef-class.h:234
bool is_abstract(void) const
Definition: cdef-class.h:290
std::string get_directory(void) const
Definition: cdef-class.h:299
const cdef_class_rep * get_rep(void) const
Definition: cdef-class.h:403
bool is_sealed(void) const
Definition: cdef-class.h:292
cdef_method find_method(const std::string &nm, bool local=false)
Definition: cdef-class.h:438
cdef_class(const cdef_class &cls)
Definition: cdef-class.h:232
cdef_property find_property(const std::string &nm)
Definition: cdef-class.h:444
octave_value get_method(const std::string &nm) const
Definition: cdef-class.h:337
string_vector get_names(void)
Definition: cdef-class.h:288
void initialize_object(cdef_object &obj)
Definition: cdef-class.h:359
Cell get_properties(int mode=property_normal)
Definition: cdef-class.h:277
std::map< std::string, cdef_method > get_method_map(bool only_inherited=false, bool include_ctor=false)
Definition: cdef-class.h:265
octave_value construct(const octave_value_list &args)
Definition: cdef-class.h:349
cdef_class(const std::string &nm, const std::list< cdef_class > &superclasses)
Definition: cdef-class.h:226
std::map< std::string, cdef_property > get_property_map(int mode=property_normal)
Definition: cdef-class.h:283
cdef_class_rep * get_rep(void)
Definition: cdef-class.h:398
void mark_as_handle_class(void)
Definition: cdef-class.h:369
bool is_handle_class(void) const
Definition: cdef-class.h:374
std::string get_name(void) const
Definition: cdef-class.h:304
void mark_as_meta_class(void)
Definition: cdef-class.h:379
octave_value get_constructor_function(void)
Definition: cdef-class.h:344
void run_constructor(cdef_object &obj, const octave_value_list &args)
Definition: cdef-class.h:364
cdef_object construct_object(const octave_value_list &args)
Definition: cdef-class.h:354
cdef_object & operator=(const cdef_object &obj)
Definition: cdef-object.h:211
const cdef_object_rep * get_rep(void) const
Definition: cdef-object.h:298
void error(const char *fmt,...)
Definition: error.cc:968
QString name
bool operator<(const cdef_class &clsa, const cdef_class &clsb)
Definition: cdef-class.h:432
bool operator!=(const cdef_class &clsa, const cdef_class &clsb)
Definition: cdef-class.h:424
bool operator==(const cdef_class &clsa, const cdef_class &clsb)
Definition: cdef-class.h:416