GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
cdef-class.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2012-2025 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#include <utility>
35
36#include "oct-refcount.h"
37
38#include "cdef-fwd.h"
39#include "cdef-method.h"
40#include "cdef-object.h"
41#include "cdef-package.h"
42#include "cdef-property.h"
43#include "error.h"
44#include "ov.h"
45#include "ovl.h"
46
48
49class interpreter;
50class tree_classdef;
51
52// When we want to preserve the order in which properties were first defined,
53// we index them with a std::pair key made of:
54// - first, their rank in the property list;
55// - and second, their name.
56typedef std::pair<unsigned int, std::string> property_key;
57
58class OCTINTERP_API cdef_class : public cdef_meta_object
59{
60private:
61
62 class cdef_class_rep : public cdef_meta_object_rep
63 {
64 public:
65 cdef_class_rep ()
66 : cdef_meta_object_rep (), m_member_count (0), m_handle_class (false),
67 m_meta (false)
68 { }
69
70 OCTINTERP_API cdef_class_rep (const std::list<cdef_class>& superclasses);
71
72 cdef_class_rep& operator = (const cdef_class_rep&) = delete;
73
74 ~cdef_class_rep () = default;
75
76 cdef_object_rep * copy () const { return new cdef_class_rep (*this); }
77
78 bool is_class () const { return true; }
79
80 std::string get_name () const
81 { return get ("Name").string_value (); }
82
83 void set_name (const std::string& nm) { put ("Name", nm); }
84
85 bool is_abstract () const { return get ("Abstract").bool_value (); }
86
87 bool is_sealed () const { return get ("Sealed").bool_value (); }
88
89 OCTINTERP_API cdef_method
90 find_method (const std::string& nm, bool local = false);
91
92 OCTINTERP_API void
93 install_method (const cdef_method& meth);
94
95 OCTINTERP_API Cell
96 get_methods (bool include_ctor);
97
98 OCTINTERP_API std::map<std::string, cdef_method>
99 get_method_map (bool only_inherited, bool include_ctor);
100
101 OCTINTERP_API cdef_property find_property (const std::string& nm);
102
103 OCTINTERP_API void install_property (const cdef_property& prop);
104
105 OCTINTERP_API Cell get_properties (int mode);
106
107 OCTINTERP_API std::map<property_key, cdef_property>
108 get_property_map (int mode);
109
110 OCTINTERP_API string_vector get_names ();
111
112 void set_directory (const std::string& dir) { m_directory = dir; }
113
114 std::string get_directory () const { return m_directory; }
115
116 OCTINTERP_API void delete_object (const cdef_object& obj);
117
118 OCTINTERP_API octave_value_list
119 meta_subsref (const std::string& type,
120 const std::list<octave_value_list>& idx, int nargout);
121
122 OCTINTERP_API void meta_release ();
123
124 bool meta_accepts_postfix_index (char type) const
125 {
126 return (type == '(' || type == '.');
127 }
128
129 OCTINTERP_API octave_value get_method (const std::string& name) const;
130
131 OCTINTERP_API octave_value get_method (int line) const;
132
133 OCTINTERP_API octave_value construct (const octave_value_list& args);
134
135 OCTINTERP_API cdef_object
136 construct_object (const octave_value_list& args);
137
138 OCTINTERP_API void initialize_object (cdef_object& obj);
139
140 OCTINTERP_API void
141 run_constructor (cdef_object& obj, const octave_value_list& args);
142
143 void mark_as_handle_class () { m_handle_class = true; }
144
145 bool is_handle_class () const { return m_handle_class; }
146
147 octave_idx_type static_count () const { return m_member_count; }
148
149 void destroy ()
150 {
151 if (m_member_count)
152 {
153 m_count++;
154 cdef_class lock (this);
155
156 m_member_count = 0;
157 m_method_map.clear ();
158 m_property_map.clear ();
159 m_property_rank_map.clear ();
160 }
161 else
162 delete this;
163 }
164
165 void mark_as_meta_class () { m_meta = true; }
166
167 bool is_meta_class () const { return m_meta; }
168
169 void file_name (const std::string& nm) { m_file_name = nm; }
170
171 std::string file_name () const { return m_file_name; }
172
173 private:
174
175 OCTINTERP_API void load_all_methods ();
176
177 OCTINTERP_API void find_names (std::set<std::string>& names, bool all);
178
179 OCTINTERP_API void
180 find_properties (std::map<property_key, cdef_property>& props,
181 int mode = 0);
182
183 OCTINTERP_API void
184 find_properties_aux (std::map<property_key, cdef_property>& props,
185 std::set<std::string>& prop_names,
186 int mode = 0);
187
188 OCTINTERP_API void
189 find_methods (std::map<std::string, cdef_method>& meths,
190 bool only_inherited, bool include_ctor = false);
191
192 cdef_class wrap ()
193 {
194 m_count++;
195 return cdef_class (this);
196 }
197
198 // The @-directory were this class is loaded from.
199 // (not used yet)
200
201 std::string m_directory;
202
203 std::string m_file_name;
204
205 // The methods defined by this class.
206
207 std::map<std::string, cdef_method> m_method_map;
208
209 // The properties defined by this class.
210
211 std::map<std::string, cdef_property> m_property_map;
212 std::map<std::string, unsigned int> m_property_rank_map;
213
214 // The number of members in this class (methods, properties...)
215
216 octave_idx_type m_member_count;
217
218 // TRUE if this class is a handle class. A class is a handle
219 // class when the abstract "handle" class is one of its superclasses.
220
221 bool m_handle_class;
222
223 // The list of super-class constructors that are called implicitly by the
224 // classdef engine when creating an object. These constructors are not
225 // called explicitly by the class constructor.
226
227 std::list<cdef_class> m_implicit_ctor_list;
228
229 // TRUE if this class is a built-in meta class.
230
231 bool m_meta;
232
233 // Utility iterator typedefs.
234
235 typedef std::map<std::string, cdef_method>::iterator method_iterator;
236 typedef std::map<std::string, cdef_method>::const_iterator method_const_iterator;
237 typedef std::map<property_key, cdef_property>::iterator property_iterator;
238 typedef std::map<property_key, cdef_property>::const_iterator property_const_iterator;
239
240 cdef_class_rep (const cdef_class_rep& c) = default;
241 };
242
243public:
244
245 // Create an invalid class object.
246
248
249 cdef_class (const std::string& nm,
250 const std::list<cdef_class>& superclasses)
251 : cdef_meta_object (new cdef_class_rep (superclasses))
252 {
253 get_rep ()->set_name (nm);
254 }
255
256 cdef_class (const cdef_class& cls) : cdef_meta_object (cls) { }
257
259 : cdef_meta_object (obj)
260 {
261 // This should never happen...
262 if (! is_class ())
263 error ("internal error: invalid assignment from %s to meta.class object",
264 class_name ().c_str ());
265 }
266
267 cdef_class& operator = (const cdef_class& cls)
268 {
270
271 return *this;
272 }
273
274 ~cdef_class () = default;
275
276 OCTINTERP_API cdef_method
277 find_method (const std::string& nm, bool local = false);
278
279 void install_method (const cdef_method& meth)
280 {
281 get_rep ()->install_method (meth);
282 }
283
284 Cell get_methods (bool include_ctor = false)
285 {
286 return get_rep ()->get_methods (include_ctor);
287 }
288
289 std::map<std::string, cdef_method>
290 get_method_map (bool only_inherited = false, bool include_ctor = false)
291 {
292 return get_rep ()->get_method_map (only_inherited, include_ctor);
293 }
294
295 OCTINTERP_API cdef_property find_property (const std::string& nm);
296
298 {
299 get_rep ()->install_property (prop);
300 }
301
302 Cell get_properties (int mode = property_normal)
303 {
304 return get_rep ()->get_properties (mode);
305 }
306
307 std::map<property_key, cdef_property>
308 get_property_map (int mode = property_normal)
309 {
310 return get_rep ()->get_property_map (mode);
311 }
312
313 string_vector get_names () { return get_rep ()->get_names (); }
314
315 bool is_abstract () const { return get_rep ()->is_abstract (); }
316
317 bool is_sealed () const { return get_rep ()->is_sealed (); }
318
319 void set_directory (const std::string& dir)
320 {
321 get_rep ()->set_directory (dir);
322 }
323
324 std::string get_directory () const
325 {
326 return get_rep ()->get_directory ();
327 }
328
329 std::string get_name () const { return get_rep ()->get_name (); }
330
331 bool is_builtin () const { return get_directory ().empty (); }
332
333 void delete_object (const cdef_object& obj)
334 {
335 get_rep ()->delete_object (obj);
336 }
337
338 //! Analyze the tree_classdef tree and transform it to a cdef_class
339 //!
340 //! <b>All attribute validation should occur here.</b>
341 //!
342 //! Classdef attribute values can be given in the form of
343 //! expressions. These expressions must be evaluated before
344 //! assigning them as attribute values. Evaluating them as they are
345 //! parsed causes trouble with possible recursion in the parser so we
346 //! do it here. For example
347 //!
348 //! @code
349 //! classdef recursion_class
350 //! methods (Access = ?recursion_class)
351 //! endmethods
352 //! endclassdef
353 //! @endcode
354 //!
355 //! will fail because each attempt to compute the metaclass of
356 //! recursion_class will cause recursion_class to be parsed again.
357
358 static OCTINTERP_API cdef_class
359 make_meta_class (interpreter& interp, tree_classdef *t,
360 bool is_at_folder = false);
361
362 octave_value get_method (const std::string& nm) const
363 {
364 return get_rep ()->get_method (nm);
365 }
366
368 {
369 return get_rep ()->get_method (ln);
370 }
371
372 OCTINTERP_API octave_value get_method_function (const std::string& nm);
373
375 {
376 return get_method_function (get_name ());
377 }
378
380 {
381 return get_rep ()->construct (args);
382 }
383
385 {
386 return get_rep ()->construct_object (args);
387 }
388
390 {
391 get_rep ()->initialize_object (obj);
392 }
393
395 {
396 get_rep ()->run_constructor (obj, args);
397 }
398
400 {
401 get_rep ()->mark_as_handle_class ();
402 }
403
404 bool is_handle_class () const
405 {
406 return get_rep ()->is_handle_class ();
407 }
408
409 void mark_as_meta_class () { get_rep ()->mark_as_meta_class (); }
410
411 bool is_meta_class () const { return get_rep ()->is_meta_class (); }
412
413 void file_name (const std::string& nm) { get_rep ()->file_name (nm); }
414
415 std::string file_name () const { return get_rep ()->file_name (); }
416
417public:
418
419 enum
420 {
423 property_all
424 };
425
426private:
427
428 cdef_class_rep * get_rep ()
429 {
430 return dynamic_cast<cdef_class_rep *> (cdef_object::get_rep ());
431 }
432
433 const cdef_class_rep * get_rep () const
434 {
435 return dynamic_cast<const cdef_class_rep *> (cdef_object::get_rep ());
436 }
437
438 friend OCTINTERP_API bool operator == (const cdef_class&, const cdef_class&);
439 friend OCTINTERP_API bool operator != (const cdef_class&, const cdef_class&);
440 friend OCTINTERP_API bool operator < (const cdef_class&, const cdef_class&);
441
442 friend void install_classdef (octave::interpreter& interp);
443};
444
445inline bool
446operator == (const cdef_class& clsa, const cdef_class& clsb)
447{
448 // FIXME: is this really the right way to check class equality?
449
450 return (clsa.get_rep () == clsb.get_rep ());
451}
452
453inline bool
454operator != (const cdef_class& clsa, const cdef_class& clsb)
455{
456 return ! (clsa == clsb);
457}
458
459// This is only to be able to use cdef_class as map keys.
460
461inline bool
462operator < (const cdef_class& clsa, const cdef_class& clsb)
463{
464 return clsa.get_rep () < clsb.get_rep ();
465}
466
467inline cdef_method
468cdef_class::find_method (const std::string& nm, bool local)
469{
470 return get_rep ()->find_method (nm, local);
471}
472
473inline cdef_property
474cdef_class::find_property (const std::string& nm)
475{
476 return get_rep ()->find_property (nm);
477}
478
479OCTAVE_END_NAMESPACE(octave)
480
481#endif
std::pair< unsigned int, std::string > property_key
Definition cdef-class.h:56
bool operator==(const cdef_class &clsa, const cdef_class &clsb)
Definition cdef-class.h:446
bool operator!=(const cdef_class &clsa, const cdef_class &clsb)
Definition cdef-class.h:454
bool operator<(const cdef_class &clsa, const cdef_class &clsb)
Definition cdef-class.h:462
Definition Cell.h:41
cdef_method find_method(const std::string &nm, bool local=false)
Definition cdef-class.h:468
void mark_as_meta_class()
Definition cdef-class.h:409
octave_value construct(const octave_value_list &args)
Definition cdef-class.h:379
void install_property(const cdef_property &prop)
Definition cdef-class.h:297
cdef_class(const std::string &nm, const std::list< cdef_class > &superclasses)
Definition cdef-class.h:249
void mark_as_handle_class()
Definition cdef-class.h:399
void install_method(const cdef_method &meth)
Definition cdef-class.h:279
bool is_abstract() const
Definition cdef-class.h:315
void run_constructor(cdef_object &obj, const octave_value_list &args)
Definition cdef-class.h:394
octave_value get_method(int ln) const
Definition cdef-class.h:367
octave_value get_method(const std::string &nm) const
Definition cdef-class.h:362
bool is_builtin() const
Definition cdef-class.h:331
string_vector get_names()
Definition cdef-class.h:313
std::map< property_key, cdef_property > get_property_map(int mode=property_normal)
Definition cdef-class.h:308
octave_value get_constructor_function()
Definition cdef-class.h:374
std::string get_directory() const
Definition cdef-class.h:324
std::map< std::string, cdef_method > get_method_map(bool only_inherited=false, bool include_ctor=false)
Definition cdef-class.h:290
@ property_inherited
Definition cdef-class.h:422
cdef_class(const cdef_class &cls)
Definition cdef-class.h:256
bool is_sealed() const
Definition cdef-class.h:317
std::string get_name() const
Definition cdef-class.h:329
void file_name(const std::string &nm)
Definition cdef-class.h:413
std::string file_name() const
Definition cdef-class.h:415
void initialize_object(cdef_object &obj)
Definition cdef-class.h:389
void delete_object(const cdef_object &obj)
Definition cdef-class.h:333
~cdef_class()=default
bool is_handle_class() const
Definition cdef-class.h:404
bool is_meta_class() const
Definition cdef-class.h:411
cdef_property find_property(const std::string &nm)
Definition cdef-class.h:474
friend void install_classdef(octave::interpreter &interp)
Cell get_properties(int mode=property_normal)
Definition cdef-class.h:302
cdef_object construct_object(const octave_value_list &args)
Definition cdef-class.h:384
cdef_class(const cdef_object &obj)
Definition cdef-class.h:258
Cell get_methods(bool include_ctor=false)
Definition cdef-class.h:284
void set_directory(const std::string &dir)
Definition cdef-class.h:319
cdef_object & operator=(const cdef_object &obj)
const cdef_object_rep * get_rep() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
bool operator!=(const dim_vector &a, const dim_vector &b)
Definition dim-vector.h:532
bool operator==(const dim_vector &a, const dim_vector &b)
Definition dim-vector.h:516
void error(const char *fmt,...)
Definition error.cc:1003
bool operator<(const time &t1, const time &t2)
Definition oct-time.h:140