GNU Octave 11.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-2026 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
134 construct (const octave_value_list& args,
135 const bool default_initialize = false);
136
137 OCTINTERP_API cdef_object
138 construct_object (const octave_value_list& args,
139 const bool default_initialize = false);
140
141 OCTINTERP_API void initialize_object (cdef_object& obj);
142
143 OCTINTERP_API void
144 run_constructor (cdef_object& obj, const octave_value_list& args);
145
146 void mark_as_handle_class () { m_handle_class = true; }
147
148 bool is_handle_class () const { return m_handle_class; }
149
150 octave_idx_type static_count () const { return m_member_count; }
151
152 void destroy ()
153 {
154 if (m_member_count)
155 {
156 m_count++;
157 cdef_class lock (this);
158
159 m_member_count = 0;
160 m_method_map.clear ();
161 m_property_map.clear ();
162 m_property_rank_map.clear ();
163 }
164 else
165 delete this;
166 }
167
168 void mark_as_meta_class () { m_meta = true; }
169
170 bool is_meta_class () const { return m_meta; }
171
172 void file_name (const std::string& nm) { m_file_name = nm; }
173
174 std::string file_name () const { return m_file_name; }
175
176 private:
177
178 OCTINTERP_API void load_all_methods ();
179
180 OCTINTERP_API void find_names (std::set<std::string>& names, bool all);
181
182 OCTINTERP_API void
183 find_properties (std::map<property_key, cdef_property>& props,
184 int mode = 0);
185
186 OCTINTERP_API void
187 find_properties_aux (std::map<property_key, cdef_property>& props,
188 std::set<std::string>& prop_names,
189 int mode = 0);
190
191 OCTINTERP_API void
192 find_methods (std::map<std::string, cdef_method>& meths,
193 bool only_inherited, bool include_ctor = false);
194
195 cdef_class wrap ()
196 {
197 m_count++;
198 return cdef_class (this);
199 }
200
201 // The @-directory were this class is loaded from.
202 // (not used yet)
203
204 std::string m_directory;
205
206 std::string m_file_name;
207
208 // The methods defined by this class.
209
210 std::map<std::string, cdef_method> m_method_map;
211
212 // The properties defined by this class.
213
214 std::map<std::string, cdef_property> m_property_map;
215 std::map<std::string, unsigned int> m_property_rank_map;
216
217 // The number of members in this class (methods, properties...)
218
219 octave_idx_type m_member_count;
220
221 // TRUE if this class is a handle class. A class is a handle
222 // class when the abstract "handle" class is one of its superclasses.
223
224 bool m_handle_class;
225
226 // The list of super-class constructors that are called implicitly by the
227 // classdef engine when creating an object. These constructors are not
228 // called explicitly by the class constructor.
229
230 std::list<cdef_class> m_implicit_ctor_list;
231
232 // TRUE if this class is a built-in meta class.
233
234 bool m_meta;
235
236 // Utility iterator typedefs.
237
238 typedef std::map<std::string, cdef_method>::iterator method_iterator;
239 typedef std::map<std::string, cdef_method>::const_iterator method_const_iterator;
240 typedef std::map<property_key, cdef_property>::iterator property_iterator;
241 typedef std::map<property_key, cdef_property>::const_iterator property_const_iterator;
242
243 cdef_class_rep (const cdef_class_rep& c) = default;
244 };
245
246public:
247
248 // Create an invalid class object.
249
251
252 cdef_class (const std::string& nm,
253 const std::list<cdef_class>& superclasses)
254 : cdef_meta_object (new cdef_class_rep (superclasses))
255 {
256 get_rep ()->set_name (nm);
257 }
258
259 cdef_class (const cdef_class& cls) : cdef_meta_object (cls) { }
260
262 : cdef_meta_object (obj)
263 {
264 // This should never happen...
265 if (! is_class ())
266 error ("internal error: invalid assignment from %s to meta.class object",
267 class_name ().c_str ());
268 }
269
270 cdef_class& operator = (const cdef_class& cls)
271 {
273
274 return *this;
275 }
276
277 ~cdef_class () = default;
278
279 OCTINTERP_API cdef_method
280 find_method (const std::string& nm, bool local = false);
281
282 void install_method (const cdef_method& meth)
283 {
284 get_rep ()->install_method (meth);
285 }
286
287 Cell get_methods (bool include_ctor = false)
288 {
289 return get_rep ()->get_methods (include_ctor);
290 }
291
292 std::map<std::string, cdef_method>
293 get_method_map (bool only_inherited = false, bool include_ctor = false)
294 {
295 return get_rep ()->get_method_map (only_inherited, include_ctor);
296 }
297
298 OCTINTERP_API cdef_property find_property (const std::string& nm);
299
301 {
302 get_rep ()->install_property (prop);
303 }
304
305 Cell get_properties (int mode = property_normal)
306 {
307 return get_rep ()->get_properties (mode);
308 }
309
310 std::map<property_key, cdef_property>
311 get_property_map (int mode = property_normal)
312 {
313 return get_rep ()->get_property_map (mode);
314 }
315
316 string_vector get_names () { return get_rep ()->get_names (); }
317
318 bool is_abstract () const { return get_rep ()->is_abstract (); }
319
320 bool is_sealed () const { return get_rep ()->is_sealed (); }
321
322 void set_directory (const std::string& dir)
323 {
324 get_rep ()->set_directory (dir);
325 }
326
327 std::string get_directory () const
328 {
329 return get_rep ()->get_directory ();
330 }
331
332 std::string get_name () const { return get_rep ()->get_name (); }
333
334 bool is_builtin () const { return get_directory ().empty (); }
335
336 void delete_object (const cdef_object& obj)
337 {
338 get_rep ()->delete_object (obj);
339 }
340
341 //! Analyze the tree_classdef tree and transform it to a cdef_class
342 //!
343 //! <b>All attribute validation should occur here.</b>
344 //!
345 //! Classdef attribute values can be given in the form of
346 //! expressions. These expressions must be evaluated before
347 //! assigning them as attribute values. Evaluating them as they are
348 //! parsed causes trouble with possible recursion in the parser so we
349 //! do it here. For example
350 //!
351 //! @code
352 //! classdef recursion_class
353 //! methods (Access = ?recursion_class)
354 //! endmethods
355 //! endclassdef
356 //! @endcode
357 //!
358 //! will fail because each attempt to compute the metaclass of
359 //! recursion_class will cause recursion_class to be parsed again.
360
361 static OCTINTERP_API cdef_class
362 make_meta_class (interpreter& interp, tree_classdef *t,
363 bool is_at_folder = false);
364
365 octave_value get_method (const std::string& nm) const
366 {
367 return get_rep ()->get_method (nm);
368 }
369
371 {
372 return get_rep ()->get_method (ln);
373 }
374
375 OCTINTERP_API octave_value get_method_function (const std::string& nm);
376
378 {
379 return get_method_function (get_name ());
380 }
381
383 const bool default_initialize = false)
384 {
385 return get_rep ()->construct (args, default_initialize);
386 }
387
389 const bool default_initialize = false)
390 {
391 return get_rep ()->construct_object (args, default_initialize);
392 }
393
395 {
396 get_rep ()->initialize_object (obj);
397 }
398
400 {
401 get_rep ()->run_constructor (obj, args);
402 }
403
405 {
406 get_rep ()->mark_as_handle_class ();
407 }
408
409 bool is_handle_class () const
410 {
411 return get_rep ()->is_handle_class ();
412 }
413
414 void mark_as_meta_class () { get_rep ()->mark_as_meta_class (); }
415
416 bool is_meta_class () const { return get_rep ()->is_meta_class (); }
417
418 void file_name (const std::string& nm) { get_rep ()->file_name (nm); }
419
420 std::string file_name () const { return get_rep ()->file_name (); }
421
422public:
423
424 enum
425 {
428 property_all
429 };
430
431private:
432
433 cdef_class_rep * get_rep ()
434 {
435 return dynamic_cast<cdef_class_rep *> (cdef_object::get_rep ());
436 }
437
438 const cdef_class_rep * get_rep () const
439 {
440 return dynamic_cast<const cdef_class_rep *> (cdef_object::get_rep ());
441 }
442
443 friend OCTINTERP_API bool operator == (const cdef_class&, const cdef_class&);
444 friend OCTINTERP_API bool operator != (const cdef_class&, const cdef_class&);
445 friend OCTINTERP_API bool operator < (const cdef_class&, const cdef_class&);
446
447 friend void install_classdef (octave::interpreter& interp);
448};
449
450inline bool
451operator == (const cdef_class& clsa, const cdef_class& clsb)
452{
453 // FIXME: is this really the right way to check class equality?
454
455 return (clsa.get_rep () == clsb.get_rep ());
456}
457
458inline bool
459operator != (const cdef_class& clsa, const cdef_class& clsb)
460{
461 return ! (clsa == clsb);
462}
463
464// This is only to be able to use cdef_class as map keys.
465
466inline bool
467operator < (const cdef_class& clsa, const cdef_class& clsb)
468{
469 return clsa.get_rep () < clsb.get_rep ();
470}
471
472inline cdef_method
473cdef_class::find_method (const std::string& nm, bool local)
474{
475 return get_rep ()->find_method (nm, local);
476}
477
478inline cdef_property
479cdef_class::find_property (const std::string& nm)
480{
481 return get_rep ()->find_property (nm);
482}
483
484OCTAVE_END_NAMESPACE(octave)
485
486#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:451
bool operator!=(const cdef_class &clsa, const cdef_class &clsb)
Definition cdef-class.h:459
bool operator<(const cdef_class &clsa, const cdef_class &clsb)
Definition cdef-class.h:467
Definition Cell.h:41
cdef_method find_method(const std::string &nm, bool local=false)
Definition cdef-class.h:473
void mark_as_meta_class()
Definition cdef-class.h:414
void install_property(const cdef_property &prop)
Definition cdef-class.h:300
cdef_class(const std::string &nm, const std::list< cdef_class > &superclasses)
Definition cdef-class.h:252
void mark_as_handle_class()
Definition cdef-class.h:404
void install_method(const cdef_method &meth)
Definition cdef-class.h:282
bool is_abstract() const
Definition cdef-class.h:318
void run_constructor(cdef_object &obj, const octave_value_list &args)
Definition cdef-class.h:399
octave_value get_method(int ln) const
Definition cdef-class.h:370
octave_value get_method(const std::string &nm) const
Definition cdef-class.h:365
bool is_builtin() const
Definition cdef-class.h:334
string_vector get_names()
Definition cdef-class.h:316
cdef_object construct_object(const octave_value_list &args, const bool default_initialize=false)
Definition cdef-class.h:388
std::map< property_key, cdef_property > get_property_map(int mode=property_normal)
Definition cdef-class.h:311
octave_value get_constructor_function()
Definition cdef-class.h:377
std::string get_directory() const
Definition cdef-class.h:327
std::map< std::string, cdef_method > get_method_map(bool only_inherited=false, bool include_ctor=false)
Definition cdef-class.h:293
@ property_inherited
Definition cdef-class.h:427
cdef_class(const cdef_class &cls)
Definition cdef-class.h:259
bool is_sealed() const
Definition cdef-class.h:320
std::string get_name() const
Definition cdef-class.h:332
void file_name(const std::string &nm)
Definition cdef-class.h:418
std::string file_name() const
Definition cdef-class.h:420
void initialize_object(cdef_object &obj)
Definition cdef-class.h:394
void delete_object(const cdef_object &obj)
Definition cdef-class.h:336
~cdef_class()=default
bool is_handle_class() const
Definition cdef-class.h:409
octave_value construct(const octave_value_list &args, const bool default_initialize=false)
Definition cdef-class.h:382
bool is_meta_class() const
Definition cdef-class.h:416
cdef_property find_property(const std::string &nm)
Definition cdef-class.h:479
friend void install_classdef(octave::interpreter &interp)
Cell get_properties(int mode=property_normal)
Definition cdef-class.h:305
cdef_class(const cdef_object &obj)
Definition cdef-class.h:261
Cell get_methods(bool include_ctor=false)
Definition cdef-class.h:287
void set_directory(const std::string &dir)
Definition cdef-class.h:322
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:573
bool operator==(const dim_vector &a, const dim_vector &b)
Definition dim-vector.h:557
void error(const char *fmt,...)
Definition error.cc:1008
bool operator<(const time &t1, const time &t2)
Definition oct-time.h:139