GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
cdef-object.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_object_h)
27#define octave_cdef_object_h 1
28
29#include "octave-config.h"
30
31#include <map>
32#include <string>
33
34#include "oct-refcount.h"
35
36#include "cdef-fwd.h"
37#include "error.h"
38#include "oct-map.h"
39#include "ov.h"
40#include "ovl.h"
41
43
44// This is mainly a bootstrap class to declare the expected interface.
45// The actual base class is cdef_class_base, which is declared after
46// cdef_object, such that it can contain cdef_object objects.
47
48class OCTINTERP_API cdef_object_rep
49{
50public:
51
52 friend class cdef_object;
53
54 cdef_object_rep () : m_count (1) { }
55
57
58 virtual ~cdef_object_rep () = default;
59
60 virtual cdef_class get_class () const;
61
62 virtual void set_class (const cdef_class&)
63 {
64 err_invalid_object ("set_class");
65 }
66
67 virtual cdef_object_rep * clone () const
68 {
69 err_invalid_object ("clone");
70 }
71
72 virtual cdef_object_rep * empty_clone () const
73 {
74 err_invalid_object ("empty_clone");
75 }
76
77 virtual cdef_object_rep * copy () const
78 {
79 err_invalid_object ("copy");
80 }
81
82 virtual cdef_object_rep * make_array () const
83 {
84 err_invalid_object ("make_array");
85 }
86
87 virtual bool is_array () const { return false; }
88
89 virtual bool is_value_object () const { return false; }
90
91 virtual bool is_handle_object () const { return false; }
92
93 virtual bool is_meta_object () const { return false; }
94
96 {
97 err_invalid_object ("array_value");
98 }
99
100 virtual void put (const std::string&, const octave_value&)
101 { err_invalid_object ("put"); }
102
103 virtual octave_value get (const std::string&) const
104 {
105 err_invalid_object ("get");
106 }
107
108 virtual void set_property (octave_idx_type, const std::string&,
109 const octave_value&)
110 {
111 err_invalid_object ("set_property");
112 }
113
114 virtual octave_value get_property (octave_idx_type, const std::string&) const
115 {
116 err_invalid_object ("get_property");
117 }
118
119 virtual void break_closure_cycles (const std::shared_ptr<stack_frame>&)
120 {
121 err_invalid_object ("break_closure_cycles");
122 }
123
124 virtual octave_value_list
125 subsref (const std::string&, const std::list<octave_value_list>&,
126 int, std::size_t&, const cdef_class&, bool)
127 {
128 err_invalid_object ("subsref");
129 }
130
131 virtual octave_value
132 subsasgn (const std::string&, const std::list<octave_value_list>&,
133 const octave_value&)
134 {
135 err_invalid_object ("subsasgn");
136 }
137
138 virtual string_vector map_keys () const;
139
140 virtual bool is_valid () const { return false; }
141
142 OCTINTERP_API std::string class_name () const;
143
144 virtual void mark_for_construction (const cdef_class&)
145 {
146 err_invalid_object ("mark_for_construction");
147 }
148
149 virtual bool is_constructed_for (const cdef_class&) const
150 {
151 err_invalid_object ("is_constructed_for");
152 }
153
154 virtual bool is_partially_constructed_for (const cdef_class&) const
155 {
156 err_invalid_object ("is_partially_constructed_for");
157 }
158
159 virtual void mark_as_constructed ()
160 {
161 err_invalid_object ("mark_as_constructed");
162 }
163
164 virtual void mark_as_constructed (const cdef_class&)
165 {
166 err_invalid_object ("mark_as_constructed");
167 }
168
169 virtual bool is_constructed () const
170 {
171 err_invalid_object ("is_constructed");
172 }
173
174 virtual octave_idx_type static_count () const { return 0; }
175
176 virtual void destroy () { delete this; }
177
178 OCTINTERP_API void release (const cdef_object& obj);
179
180 virtual dim_vector dims () const { return dim_vector (); }
181
182protected:
183
184 // Reference count
186
187 // Restricted copying.
188
189 cdef_object_rep (const cdef_object_rep&) : m_count (1) { }
190
191private:
192
193 OCTAVE_NORETURN void err_invalid_object (const char *who) const
194 {
195 error ("%s: invalid object", who);
196 }
197};
198
199class OCTINTERP_API cdef_object
200{
201public:
202
203 // FIXME: use a null object?
204 cdef_object () : m_rep (new cdef_object_rep ()) { }
205
206 cdef_object (const cdef_object& obj) : m_rep (obj.m_rep)
207 { m_rep->m_count++; }
208
209 cdef_object (cdef_object_rep *r) : m_rep (r) { }
210
211 virtual ~cdef_object () { m_rep->release (*this); }
212
213 cdef_object& operator = (const cdef_object& obj)
214 {
215 if (m_rep != obj.m_rep)
216 {
217 m_rep->release (*this);
218
219 m_rep = obj.m_rep;
220 m_rep->m_count++;
221 }
222
223 return *this;
224 }
225
226 OCTINTERP_API cdef_class get_class () const;
227
228 void set_class (const cdef_class& cls) { m_rep->set_class (cls); }
229
230 std::string class_name () const { return m_rep->class_name (); }
231
232 cdef_object clone () const { return cdef_object (m_rep->clone ()); }
233
235 {
236 return cdef_object (m_rep->empty_clone ());
237 }
238
239 dim_vector dims () const { return m_rep->dims (); }
240
242 {
243 return cdef_object (m_rep->make_array ());
244 }
245
246 cdef_object copy () const { return cdef_object (m_rep->copy ()); }
247
248 bool is_array () const { return m_rep->is_array (); }
249
250 bool is_value_object () const { return m_rep->is_value_object (); }
251
252 bool is_handle_object () const { return m_rep->is_handle_object (); }
253
254 bool is_meta_object () const { return m_rep->is_meta_object (); }
255
257 { return m_rep->array_value (); }
258
259 void put (const std::string& pname, const octave_value& val)
260 {
261 m_rep->put (pname, val);
262 }
263
264 octave_value get (const std::string& pname) const
265 {
266 return m_rep->get (pname);
267 }
268
269 void set_property (octave_idx_type idx, const std::string& pname,
270 const octave_value& pval)
271 {
272 return m_rep->set_property (idx, pname, pval);
273 }
274
276 get_property (octave_idx_type idx, const std::string& pname) const
277 {
278 return m_rep->get_property (idx, pname);
279 }
280
281 void break_closure_cycles (const std::shared_ptr<stack_frame>& frame)
282 {
283 m_rep->break_closure_cycles (frame);
284 }
285
287 subsref (const std::string& type, const std::list<octave_value_list>& idx,
288 int nargout, std::size_t& skip, const cdef_class& context,
289 bool auto_add = false)
290 {
291 return m_rep->subsref (type, idx, nargout, skip, context, auto_add);
292 }
293
295 subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
296 const octave_value& rhs, int ignore_copies = 0)
297 {
298 make_unique (ignore_copies);
299 return m_rep->subsasgn (type, idx, rhs);
300 }
301
302 string_vector map_keys () const { return m_rep->map_keys (); }
303
304 OCTINTERP_API octave_map map_value () const;
305
306 const cdef_object_rep * get_rep () const { return m_rep; }
307
308 bool ok () const { return m_rep->is_valid (); }
309
311 {
312 m_rep->mark_for_construction (cls);
313 }
314
315 bool is_constructed () const { return m_rep->is_constructed (); }
316
317 bool is_constructed_for (const cdef_class& cls) const
318 {
319 return m_rep->is_constructed_for (cls);
320 }
321
323 {
324 return m_rep->is_partially_constructed_for (cls);
325 }
326
327 void mark_as_constructed () { m_rep->mark_as_constructed (); }
328
330 { m_rep->mark_as_constructed (cls); }
331
332 bool is (const cdef_object& obj) const { return m_rep == obj.m_rep; }
333
334protected:
335
336 cdef_object_rep * get_rep () { return m_rep; }
337
338 void make_unique (int ignore_copies)
339 {
340 if (m_rep->m_count > ignore_copies + 1)
341 *this = clone ();
342 }
343
344private:
345
346 cdef_object_rep *m_rep;
347};
348
349class OCTINTERP_API cdef_object_base : public cdef_object_rep
350{
351public:
352
354 : cdef_object_rep (), m_klass ()
355 { }
356
357 cdef_object_base& operator = (const cdef_object_base&) = delete;
358
360
361 OCTINTERP_API cdef_class get_class () const;
362
363 OCTINTERP_API void set_class (const cdef_class& cls);
364
366 {
367 return new cdef_object_base (*this);
368 }
369
370 OCTINTERP_API cdef_object_rep * make_array () const;
371
372protected:
373
374 // Restricted copying!
376 : cdef_object_rep (obj), m_klass (obj.m_klass)
377 { }
378
379private:
380
381 // The class of the object
382 cdef_object m_klass;
383};
384
385class OCTINTERP_API cdef_object_array : public cdef_object_base
386{
387public:
388
390
392 : cdef_object_base (), m_array (a)
393 { }
394
395 cdef_object_array& operator = (const cdef_object_array&) = delete;
396
397 ~cdef_object_array () = default;
398
400 {
401 return new cdef_object_array (*this);
402 }
403
404 dim_vector dims () const { return m_array.dims (); }
405
406 bool is_valid () const { return true; }
407
408 bool is_array () const { return true; }
409
410 Array<cdef_object> array_value () const { return m_array; }
411
412 OCTINTERP_API octave_value_list
413 subsref (const std::string& type, const std::list<octave_value_list>& idx,
414 int nargout, std::size_t& skip, const cdef_class& context,
415 bool auto_add);
416
417 OCTINTERP_API octave_value
418 subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
419 const octave_value& rhs);
420
421 void set_property (octave_idx_type idx, const std::string& pname,
422 const octave_value& pval)
423 {
424 cdef_object& tmp = m_array.elem (idx);
425
426 return tmp.put (pname, pval);
427 }
428
430 get_property (octave_idx_type idx, const std::string& pname) const
431 {
432 cdef_object tmp = m_array.elem (idx);
433
434 return tmp.get (pname);
435 }
436
437private:
438
439 Array<cdef_object> m_array;
440
441 void fill_empty_values () { fill_empty_values (m_array); }
442
443 OCTINTERP_API void fill_empty_values (Array<cdef_object>& arr);
444
445 // Private copying!
447 : cdef_object_base (obj), m_array (obj.m_array)
448 { }
449};
450
451class OCTINTERP_API cdef_object_scalar : public cdef_object_base
452{
453public:
454
456
457 cdef_object_scalar& operator = (const cdef_object_scalar&) = delete;
458
460
461 dim_vector dims () const { return dim_vector (1, 1); }
462
463 void break_closure_cycles (const std::shared_ptr<stack_frame>& frame);
464
465 void put (const std::string& pname, const octave_value& val)
466 {
467 m_map.assign (pname, val);
468 }
469
470 octave_value get (const std::string& pname) const
471 {
472 Cell val = m_map.contents (pname);
473
474 if (val.numel () < 1)
475 error ("get: unknown slot: %s", pname.c_str ());
476
477 return val(0, 0);
478 }
479
480 void set_property (octave_idx_type idx, const std::string& pname,
481 const octave_value& pval)
482 {
483 if (idx != 0)
484 error ("invalid index"); // FIXME
485
486 put (pname, pval);
487 }
488
490 get_property (octave_idx_type idx, const std::string& pname) const
491 {
492 if (idx != 0)
493 error ("invalid index"); // FIXME
494
495 return get (pname);
496 }
497
498 OCTINTERP_API octave_value_list
499 subsref (const std::string& type, const std::list<octave_value_list>& idx,
500 int nargout, std::size_t& skip, const cdef_class& context,
501 bool auto_add);
502
503 OCTINTERP_API octave_value
504 subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
505 const octave_value& rhs);
506
507 OCTINTERP_API void mark_for_construction (const cdef_class&);
508
509 OCTINTERP_API bool is_constructed_for (const cdef_class& cls) const;
510
511 OCTINTERP_API bool
512 is_partially_constructed_for (const cdef_class& cls) const;
513
514 void mark_as_constructed () { m_ctor_list.clear (); }
515
516 OCTINTERP_API void mark_as_constructed (const cdef_class& cls);
517
518 bool is_constructed () const { return m_ctor_list.empty (); }
519
520protected:
521
522 // Object property values
524
525 // Internal/temporary structure used during object construction
526 std::map< cdef_class, std::list<cdef_class>> m_ctor_list;
527
528protected:
529
530 // Restricted object copying!
532 : cdef_object_base (obj), m_map (obj.m_map), m_ctor_list (obj.m_ctor_list)
533 { }
534};
535
536class OCTINTERP_API handle_cdef_object : public cdef_object_scalar
537{
538public:
539
541
542 handle_cdef_object& operator = (const handle_cdef_object&) = delete;
543
544 OCTINTERP_API ~handle_cdef_object ();
545
547 {
548 handle_cdef_object *obj = const_cast<handle_cdef_object *> (this);
549 obj->m_count++;
550 return obj;
551 }
552
554 {
555 return new handle_cdef_object (*this);
556 }
557
558 bool is_valid () const { return true; }
559
560 bool is_handle_object () const { return true; }
561
562protected:
563
564 // Restricted copying!
568};
569
570class OCTINTERP_API value_cdef_object : public cdef_object_scalar
571{
572public:
573
575
576 value_cdef_object& operator = (const value_cdef_object&) = delete;
577
578 OCTINTERP_API ~value_cdef_object ();
579
581 {
582 return new value_cdef_object (*this);
583 }
584
585 cdef_object_rep * copy () const { return clone (); }
586
587 bool is_valid () const { return true; }
588
589 bool is_value_object () const { return true; }
590
591private:
592
593 // Private copying!
595 : cdef_object_scalar (obj)
596 { }
597};
598
599class OCTINTERP_API cdef_meta_object_rep : public handle_cdef_object
600{
601public:
602
604
605 cdef_meta_object_rep& operator = (const cdef_meta_object_rep&) = delete;
606
608
610 { return new cdef_meta_object_rep (*this); }
611
612 bool is_meta_object () const { return true; }
613
614 virtual bool is_class () const { return false; }
615
616 virtual bool is_property () const { return false; }
617
618 virtual bool is_method () const { return false; }
619
620 virtual bool is_package () const { return false; }
621
622 void doc_string (const std::string& txt) { m_doc_string = txt; }
623
624 std::string doc_string () const { return m_doc_string; }
625
626 virtual octave_value_list
627 meta_subsref (const std::string& /* type */,
628 const std::list<octave_value_list>& /* idx */,
629 int /* nargout */)
630 {
631 error ("subsref: invalid meta object");
632 }
633
634 virtual void meta_release () { }
635
636 virtual bool meta_accepts_postfix_index (char /* type */) const
637 {
638 return false;
639 }
640
641protected:
642
643 std::string m_doc_string;
644
645 // Restricted copying!
649};
650
651class OCTINTERP_API cdef_meta_object : public cdef_object
652{
653public:
654
656
657 // Object consistency is checked in sub-classes.
659
661
662 cdef_meta_object (const cdef_object& obj) : cdef_object (obj) { }
663
664 cdef_meta_object& operator = (const cdef_object&) = delete;
665
666 ~cdef_meta_object () = default;
667
668 bool is_class () const { return get_rep ()->is_class (); }
669
670 bool is_property () const { return get_rep ()->is_property (); }
671
672 bool is_method () const { return get_rep ()->is_method (); }
673
674 bool is_package () const { return get_rep ()->is_package (); }
675
676 void doc_string (const std::string& txt) { get_rep ()->doc_string (txt); }
677
678 std::string doc_string () const { return get_rep ()->doc_string (); }
679
681 meta_subsref (const std::string& type,
682 const std::list<octave_value_list>& idx, int nargout)
683 {
684 return get_rep ()->meta_subsref (type, idx, nargout);
685 }
686
687 void meta_release () { get_rep ()->meta_release (); }
688
689 bool meta_accepts_postfix_index (char type) const
690 {
691 return get_rep ()->meta_accepts_postfix_index (type);
692 }
693
694private:
695
696 cdef_meta_object_rep * get_rep ()
697 {
698 return dynamic_cast<cdef_meta_object_rep *> (cdef_object::get_rep ());
699 }
700
701 const cdef_meta_object_rep * get_rep () const
702 {
703 return dynamic_cast<const cdef_meta_object_rep *> (cdef_object::get_rep ());
704 }
705};
706
707OCTAVE_END_NAMESPACE(octave)
708
709#endif
N Dimensional Array with copy-on-write semantics.
Definition Array.h:130
octave_idx_type numel() const
Number of elements in the array.
Definition Array.h:418
Definition Cell.h:41
cdef_meta_object_rep(const cdef_meta_object_rep &obj)
virtual bool meta_accepts_postfix_index(char) const
cdef_object_rep * copy() const
virtual bool is_class() const
~cdef_meta_object_rep()=default
bool is_meta_object() const
std::string doc_string() const
virtual void meta_release()
virtual octave_value_list meta_subsref(const std::string &, const std::list< octave_value_list > &, int)
void doc_string(const std::string &txt)
virtual bool is_package() const
std::string m_doc_string
virtual bool is_property() const
virtual bool is_method() const
bool meta_accepts_postfix_index(char type) const
bool is_property() const
bool is_package() const
cdef_meta_object(const cdef_object &obj)
bool is_method() const
cdef_meta_object(cdef_meta_object_rep *r)
bool is_class() const
cdef_meta_object(const cdef_meta_object &obj)
~cdef_meta_object()=default
void doc_string(const std::string &txt)
octave_value_list meta_subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
std::string doc_string() const
bool is_valid() const
cdef_object_rep * clone() const
void set_property(octave_idx_type idx, const std::string &pname, const octave_value &pval)
dim_vector dims() const
~cdef_object_array()=default
Array< cdef_object > array_value() const
octave_value get_property(octave_idx_type idx, const std::string &pname) const
bool is_array() const
cdef_object_array(const Array< cdef_object > &a)
cdef_object_rep * empty_clone() const
cdef_object_base(const cdef_object_base &obj)
virtual void break_closure_cycles(const std::shared_ptr< stack_frame > &)
virtual octave_value_list subsref(const std::string &, const std::list< octave_value_list > &, int, std::size_t &, const cdef_class &, bool)
virtual bool is_array() const
Definition cdef-object.h:87
virtual void mark_as_constructed(const cdef_class &)
virtual void mark_as_constructed()
virtual cdef_object_rep * clone() const
Definition cdef-object.h:67
virtual bool is_constructed_for(const cdef_class &) const
virtual void set_class(const cdef_class &)
Definition cdef-object.h:62
virtual void set_property(octave_idx_type, const std::string &, const octave_value &)
virtual ~cdef_object_rep()=default
virtual Array< cdef_object > array_value() const
Definition cdef-object.h:95
virtual octave_value get(const std::string &) const
virtual bool is_constructed() const
virtual bool is_meta_object() const
Definition cdef-object.h:93
virtual octave_value get_property(octave_idx_type, const std::string &) const
virtual bool is_partially_constructed_for(const cdef_class &) const
cdef_object_rep(const cdef_object_rep &)
virtual void put(const std::string &, const octave_value &)
virtual cdef_object_rep * make_array() const
Definition cdef-object.h:82
virtual void destroy()
virtual bool is_handle_object() const
Definition cdef-object.h:91
virtual octave_idx_type static_count() const
virtual cdef_object_rep * copy() const
Definition cdef-object.h:77
virtual bool is_valid() const
virtual void mark_for_construction(const cdef_class &)
virtual cdef_object_rep * empty_clone() const
Definition cdef-object.h:72
virtual octave_value subsasgn(const std::string &, const std::list< octave_value_list > &, const octave_value &)
virtual dim_vector dims() const
virtual bool is_value_object() const
Definition cdef-object.h:89
refcount< octave_idx_type > m_count
octave_scalar_map m_map
std::map< cdef_class, std::list< cdef_class > > m_ctor_list
bool is_constructed() const
octave_value get_property(octave_idx_type idx, const std::string &pname) const
dim_vector dims() const
void put(const std::string &pname, const octave_value &val)
octave_value get(const std::string &pname) const
void set_property(octave_idx_type idx, const std::string &pname, const octave_value &pval)
cdef_object_scalar(const cdef_object_scalar &obj)
~cdef_object_scalar()=default
cdef_object clone() const
bool is_array() const
bool is_constructed() const
void break_closure_cycles(const std::shared_ptr< stack_frame > &frame)
void mark_as_constructed(const cdef_class &cls)
cdef_class get_class() const
void mark_for_construction(const cdef_class &cls)
bool is_partially_constructed_for(const cdef_class &cls) const
bool is_handle_object() const
void put(const std::string &pname, const octave_value &val)
void set_property(octave_idx_type idx, const std::string &pname, const octave_value &pval)
virtual ~cdef_object()
bool ok() const
cdef_object(const cdef_object &obj)
string_vector map_keys() const
void mark_as_constructed()
void set_class(const cdef_class &cls)
std::string class_name() const
bool is_meta_object() const
cdef_object_rep * get_rep()
dim_vector dims() const
cdef_object make_array() const
cdef_object & operator=(const cdef_object &obj)
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs, int ignore_copies=0)
const cdef_object_rep * get_rep() const
cdef_object empty_clone() const
bool is_value_object() const
cdef_object copy() const
cdef_object(cdef_object_rep *r)
bool is(const cdef_object &obj) const
void make_unique(int ignore_copies)
octave_value get(const std::string &pname) const
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout, std::size_t &skip, const cdef_class &context, bool auto_add=false)
bool is_constructed_for(const cdef_class &cls) const
octave_value get_property(octave_idx_type idx, const std::string &pname) const
Array< cdef_object > array_value() const
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
handle_cdef_object(const handle_cdef_object &obj)
cdef_object_rep * copy() const
bool is_handle_object() const
cdef_object_rep * clone() const
bool is_valid() const
cdef_object_rep * copy() const
bool is_value_object() const
bool is_valid() const
cdef_object_rep * clone() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
std::string release()
Definition defaults.cc:151
void error(const char *fmt,...)
Definition error.cc:1003