GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
cdef-object.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2024 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 (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "cdef-class.h"
31 #include "cdef-object.h"
32 #include "cdef-property.h"
33 #include "cdef-utils.h"
34 #include "interpreter.h"
35 #include "interpreter-private.h"
36 #include "ov-classdef.h"
37 
38 // Define to 1 to enable debugging statements.
39 #define DEBUG_TRACE 0
40 
42 
43 void
45 {
46  // We need to be careful to keep a reference to the object if we are
47  // calling the delete method. The object is passed to the delete
48  // method as an argument and if the count is already zero when we
49  // do that, then we will increment the count while creating the
50  // argument list for the delete method and then it will be decremented
51  // back to zero and we'll find ourselves in an infinite loop.
52 
53  if (m_count - 1 > static_count ())
54  {
55  --m_count;
56  return;
57  }
58 
59  if (is_handle_object () && ! is_meta_object ())
60  {
61  unwind_protect frame;
62 
63  // Clear interrupts.
66 
67  // Disallow quit().
68  frame.protect_var (quit_allowed);
69  quit_allowed = false;
70 
71  interpreter& interp = __get_interpreter__ ();
72 
73  interpreter_try (frame);
74 
75  try
76  {
77  // Call classdef "delete()" method on object
78  get_class ().delete_object (obj);
79  }
80  catch (const interrupt_exception&)
81  {
82  interp.recover_from_exception ();
83 
84  warning ("interrupt occurred in handle class delete method");
85  }
86  catch (const execution_exception& ee)
87  {
88  interp.recover_from_exception ();
89 
90  std::string msg = ee.message ();
91 
92  warning ("error caught while executing handle class delete method:\n%s\n",
93  msg.c_str ());
94  }
95  catch (const exit_exception&)
96  {
97  // This shouldn't happen since we disabled quit above.
98  warning ("exit disabled while executing handle class delete method");
99  }
100  catch (...) // Yes, the black hole. We're in a d-tor.
101  {
102  // This shouldn't happen, in theory.
103  warning ("internal error: unhandled exception in handle class delete method");
104  }
105  }
106 
107  // Now it is safe to set the count to zero.
108  m_count--;
109 
110  destroy ();
111 }
112 
115 {
116  err_invalid_object ("get_class");
117 }
118 
119 std::string
121 {
122  return get_class ().get_name ();
123 }
124 
127 {
128  cdef_class cls = get_class ();
129 
130  if (cls.ok ())
131  return cls.get_names ();
132 
133  return string_vector ();
134 }
135 
138 {
139  octave_map retval;
140 
141  warning_with_id ("Octave:classdef-to-struct",
142  "struct: converting a classdef object into a struct "
143  "overrides the access restrictions defined for properties. "
144  "All properties are returned, including private and "
145  "protected ones.");
146 
147  cdef_class cls = get_class ();
148 
149  if (cls.ok ())
150  {
151  std::map<std::string, cdef_property> props;
152 
154 
155  // FIXME: Why not const here?
156  for (auto& prop_val : props)
157  {
158  if (is_array ())
159  {
160  Array<cdef_object> a_obj = array_value ();
161 
162  Cell cvalue (a_obj.dims ());
163 
164  for (octave_idx_type i = 0; i < a_obj.numel (); i++)
165  cvalue (i) = prop_val.second.get_value (a_obj(i), false);
166 
167  retval.setfield (prop_val.first, cvalue);
168  }
169  else
170  {
171  Cell cvalue (dim_vector (1, 1),
172  prop_val.second.get_value (*this, false));
173 
174  retval.setfield (prop_val.first, cvalue);
175  }
176  }
177  }
178 
179  return retval;
180 }
181 
184 {
185  return m_rep->get_class ();
186 }
187 
190 {
191  return cdef_class (m_klass);
192 }
193 
194 void
196 {
197  if ((m_klass.ok () && cls.ok () && cls != get_class ())
198  || (m_klass.ok () && ! cls.ok ())
199  || (! m_klass.ok () && cls.ok ()))
200  {
201  m_klass = cls;
202  }
203 }
204 
207 {
209 
210  r->set_class (get_class ());
211 
212  return r;
213 }
214 
216 cdef_object_array::subsref (const std::string& type,
217  const std::list<octave_value_list>& idx,
218  int /* nargout */, std::size_t& skip,
219  const cdef_class& /* context */, bool auto_add)
220 {
221  octave_value_list retval;
222 
223  skip = 1;
224 
225  switch (type[0])
226  {
227  case '(':
228  {
229  const octave_value_list& ival = idx.front ();
230 
231  if (ival.empty ())
232  {
233  m_count++;
234  retval(0) = to_ov (cdef_object (this));
235  break;
236  }
237 
238  bool is_scalar = true;
239  Array<idx_vector> iv (dim_vector (1, ival.length ()));
240 
241  for (int i = 0; i < ival.length (); i++)
242  {
243  try
244  {
245  iv(i) = ival(i).index_vector ();
246  }
247  catch (index_exception& ie)
248  {
249  // Rethrow to allow more info to be reported later.
250  ie.set_pos_if_unset (ival.length (), i+1);
251  throw;
252  }
253 
254  is_scalar = is_scalar && iv(i).is_scalar ();
255  }
256 
257  Array<cdef_object> ires = m_array.index (iv, auto_add);
258 
259  // If resizing is enabled (auto_add = true), it's possible
260  // indexing was out-of-bound and the result array contains
261  // invalid cdef_objects.
262 
263  if (auto_add)
264  fill_empty_values (ires);
265 
266  if (is_scalar)
267  retval(0) = to_ov (ires(0));
268  else
269  {
270  cdef_object array_obj (new cdef_object_array (ires));
271 
272  array_obj.set_class (get_class ());
273 
274  retval(0) = to_ov (array_obj);
275  }
276  }
277  break;
278 
279  case '.':
280  if (type.size () == 1 && idx.size () == 1)
281  {
282  Cell c (dims ());
283 
284  octave_idx_type n = m_array.numel ();
285 
286  // dummy variables
287  std::size_t dummy_skip;
288  cdef_class dummy_cls;
289 
290  for (octave_idx_type i = 0; i < n; i++)
291  {
292  octave_value_list r = m_array(i).subsref (type, idx, 1,
293  dummy_skip,
294  dummy_cls);
295 
296  if (r.length () > 0)
297  c(i) = r(0);
298  }
299 
300  retval(0) = octave_value (c, true);
301 
302  break;
303  }
304  OCTAVE_FALLTHROUGH;
305 
306  default:
307  error ("can't perform indexing operation on array of %s objects",
308  class_name ().c_str ());
309  break;
310  }
311 
312  return retval;
313 }
314 
316 cdef_object_array::subsasgn (const std::string& type,
317  const std::list<octave_value_list>& idx,
318  const octave_value& rhs)
319 {
320  octave_value retval;
321 
322  switch (type[0])
323  {
324  case '(':
325  if (type.length () == 1)
326  {
327  cdef_object rhs_obj = to_cdef (rhs);
328 
329  if (rhs_obj.get_class () != get_class ())
330  error ("can't assign %s object into array of %s objects",
331  rhs_obj.class_name ().c_str (),
332  class_name ().c_str ());
333 
334  const octave_value_list& ival = idx.front ();
335  bool is_scalar = true;
336  Array<idx_vector> iv (dim_vector (1, ival.length ()));
337 
338  for (int i = 0; i < ival.length (); i++)
339  {
340  try
341  {
342  iv(i) = ival(i).index_vector ();
343  }
344  catch (index_exception& ie)
345  {
346  ie.set_pos_if_unset (ival.length (), i+1);
347  throw; // var name set in pt-idx.cc / pt-assign.cc
348  }
349 
350  is_scalar = is_scalar && iv(i).is_scalar ();
351  }
352 
353  Array<cdef_object> rhs_mat;
354 
355  if (! rhs_obj.is_array ())
356  {
357  rhs_mat = Array<cdef_object> (dim_vector (1, 1));
358  rhs_mat(0) = rhs_obj;
359  }
360  else
361  rhs_mat = rhs_obj.array_value ();
362 
363  octave_idx_type n = m_array.numel ();
364 
365  m_array.assign (iv, rhs_mat, cdef_object ());
366 
367  if (m_array.numel () > n)
368  fill_empty_values ();
369 
370  m_count++;
371  retval = to_ov (cdef_object (this));
372  }
373  else
374  {
375  const octave_value_list& ivl = idx.front ();
376 
377  // Fill in trailing singleton dimensions so that
378  // array.index doesn't create a new blank entry (bug #46660).
379  const octave_idx_type one = static_cast<octave_idx_type> (1);
380  const octave_value_list& ival = ivl.length () >= 2
381  ? ivl : ((m_array.dims ()(0) == 1)
382  ? ovl (one, ivl(0))
383  : ovl (ivl(0), one));
384 
385  bool is_scalar = true;
386 
387  Array<idx_vector> iv (dim_vector (1, ival.length ()));
388 
389  for (int i = 0; i < ival.length (); i++)
390  {
391  try
392  {
393  iv(i) = ival(i).index_vector ();
394  }
395  catch (index_exception& ie)
396  {
397  // Rethrow to allow more info to be reported later.
398  ie.set_pos_if_unset (ival.length (), i+1);
399  throw;
400  }
401 
402  is_scalar = is_scalar && iv(i).is_scalar ();
403 
404  if (! is_scalar)
405  error ("subsasgn: invalid indexing for object array assignment"
406  ", the index must reference a single object in the "
407  "array.");
408  }
409 
410  Array<cdef_object> a = m_array.index (iv, true);
411 
412  if (a.numel () != 1)
413  error ("subsasgn: invalid indexing for object array assignment");
414 
415  cdef_object obj = a(0);
416 
417  int ignore_copies = 0;
418 
419  // If the object in 'a' is not valid, this means the index
420  // was out-of-bound and we need to create a new object.
421 
422  if (! obj.ok ())
424  else
425  // Optimize the subsasgn call to come. There are 2 copies
426  // that we can safely ignore:
427  // - 1 in "array"
428  // - 1 in "a"
429  ignore_copies = 2;
430 
431  std::list<octave_value_list> next_idx (idx);
432 
433  next_idx.erase (next_idx.begin ());
434 
435  octave_value tmp = obj.subsasgn (type.substr (1), next_idx,
436  rhs, ignore_copies);
437 
438  cdef_object robj = to_cdef (tmp);
439 
440  if (! robj.ok ()
441  || robj.is_array ()
442  || robj.get_class () != get_class ())
443  error ("subsasgn: invalid assignment into array of %s objects",
444  class_name ().c_str ());
445 
446  // Small optimization, when dealing with handle
447  // objects, we don't need to re-assign the result
448  // of subsasgn back into the array.
449 
450  if (! robj.is (a(0)))
451  {
452  Array<cdef_object> rhs_a (dim_vector (1, 1),
453  robj);
454 
455  octave_idx_type n = m_array.numel ();
456 
457  m_array.assign (iv, rhs_a);
458 
459  if (m_array.numel () > n)
460  fill_empty_values ();
461  }
462 
463  m_count++;
464 
465  retval = to_ov (cdef_object (this));
466  }
467  break;
468 
469  default:
470  error ("can't perform indexing operation on array of %s objects",
471  class_name ().c_str ());
472  break;
473  }
474 
475  return retval;
476 }
477 
478 void
479 cdef_object_array::fill_empty_values (Array<cdef_object>& arr)
480 {
481  cdef_class cls = get_class ();
482 
483  cdef_object obj;
484 
485  int n = arr.numel ();
486 
487  for (int i = 0; i < n; i++)
488  {
489  if (! arr.xelem (i).ok ())
490  {
491  if (! obj.ok ())
492  {
493  obj = cls.construct_object (octave_value_list ());
494 
495  arr.xelem (i) = obj;
496  }
497  else
498  arr.xelem (i) = obj.copy ();
499  }
500  }
501 }
502 
503 void
504 cdef_object_scalar::break_closure_cycles (const std::shared_ptr<stack_frame>& frame)
505 {
506  for (octave_idx_type i = 0; i < m_map.nfields (); i++)
508 }
509 
511 cdef_object_scalar::subsref (const std::string& type,
512  const std::list<octave_value_list>& idx,
513  int nargout, std::size_t& skip,
514  const cdef_class& context, bool auto_add)
515 {
516  skip = 0;
517 
518  cdef_class cls = (context.ok () ? context : get_class ());
519 
520  octave_value_list retval;
521 
522  if (! cls.ok ())
523  return retval;
524 
525  switch (type[0])
526  {
527  case '.':
528  {
529  std::string name = (idx.front ())(0).string_value ();
530 
531  cdef_method meth = cls.find_method (name);
532 
533  if (meth.ok ())
534  {
535  int _nargout = (type.length () > 2 ? 1 : nargout);
536 
537  octave_value_list args;
538 
539  skip = 1;
540 
541  if (type.length () > 1 && type[1] == '(')
542  {
543  auto it = idx.begin ();
544 
545  args = *++it;
546 
547  skip++;
548  }
549 
550  if (meth.is_static ())
551  retval = meth.execute (args, _nargout, true, "subsref");
552  else
553  {
554  m_count++;
555  retval = meth.execute (cdef_object (this), args, _nargout,
556  true, "subsref");
557  }
558  }
559 
560  if (skip == 0)
561  {
562  cdef_property prop = cls.find_property (name);
563 
564  if (! prop.ok ())
565  error ("subsref: unknown method or property: %s", name.c_str ());
566 
567  if (prop.is_constant ())
568  retval(0) = prop.get_value (true, "subsref");
569  else
570  {
571  m_count++;
572  retval(0) = prop.get_value (cdef_object (this),
573  true, "subsref");
574  }
575 
576  skip = 1;
577  }
578  break;
579  }
580 
581  case '(':
582  {
583  const octave_value_list& ival = idx.front ();
584 
585  m_count++;
586  cdef_object this_obj (this);
587 
588  if (ival.empty ())
589  {
590  skip++;
591  retval(0) = to_ov (this_obj);
592  }
593  else
594  {
595  Array<cdef_object> arr (dim_vector (1, 1), this_obj);
596 
597  cdef_object new_obj = cdef_object (new cdef_object_array (arr));
598 
599  new_obj.set_class (get_class ());
600 
601  retval = new_obj.subsref (type, idx, nargout, skip, cls, auto_add);
602  }
603  }
604  break;
605 
606  default:
607  error ("object cannot be indexed with '%c'", type[0]);
608  break;
609  }
610 
611  return retval;
612 }
613 
615 cdef_object_scalar::subsasgn (const std::string& type,
616  const std::list<octave_value_list>& idx,
617  const octave_value& rhs)
618 {
619  octave_value retval;
620 
621  cdef_class cls = get_class ();
622 
623  switch (type[0])
624  {
625  case '.':
626  {
627  std::string name = (idx.front ())(0).string_value ();
628 
629  cdef_property prop = cls.find_property (name);
630 
631  if (! prop.ok ())
632  error ("subsasgn: unknown property: %s", name.c_str ());
633 
634  if (prop.is_constant ())
635  error ("subsasgn: cannot assign constant property: %s",
636  name.c_str ());
637 
638  m_count++;
639 
640  cdef_object obj (this);
641 
642  if (type.length () == 1)
643  {
644  prop.set_value (obj, rhs, true, "subsasgn");
645 
646  retval = to_ov (obj);
647  }
648  else
649  {
650  octave_value val = prop.get_value (obj, true, "subsasgn");
651 
652  std::list<octave_value_list> args (idx);
653 
654  args.erase (args.begin ());
655 
656  val = val.assign (octave_value::op_asn_eq,
657  type.substr (1), args, rhs);
658 
659  if (val.class_name () != "object"
660  || ! to_cdef (val).is_handle_object ())
661  prop.set_value (obj, val, true, "subsasgn");
662 
663  retval = to_ov (obj);
664  }
665  }
666  break;
667 
668  case '(':
669  {
670  m_count++;
671 
672  cdef_object this_obj (this);
673 
674  Array<cdef_object> arr (dim_vector (1, 1), this_obj);
675 
676  cdef_object new_obj = cdef_object (new cdef_object_array (arr));
677 
678  new_obj.set_class (get_class ());
679 
680  octave_value tmp = new_obj.subsasgn (type, idx, rhs);
681 
682  retval = tmp;
683  }
684  break;
685 
686  default:
687  error ("subsasgn: object cannot be index with '%c'", type[0]);
688  break;
689  }
690 
691  return retval;
692 }
693 
694 void
696 {
697  std::string cls_name = cls.get_name ();
698 
699  Cell supcls = cls.get ("SuperClasses").cell_value ();
700 
701  std::list<cdef_class> supcls_list = lookup_classes (supcls);
702 
703  m_ctor_list[cls] = supcls_list;
704 }
705 
706 bool
708 {
709  return (is_constructed ()
710  || m_ctor_list.find (cls) == m_ctor_list.end ());
711 }
712 
713 bool
715 {
716  if (is_constructed ())
717  return true;
718 
719  std::map<cdef_class, std::list<cdef_class>>::const_iterator it
720  = m_ctor_list.find (cls);
721 
722  if (it == m_ctor_list.end () || it->second.empty ())
723  return true;
724 
725  for (const auto& cdef_cls : it->second)
726  if (! is_partially_constructed_for (cdef_cls))
727  return false;
728 
729  return true;
730 }
731 
732 void
734 {
735  m_ctor_list.erase (cls);
736 }
737 
739 {
740 #if DEBUG_TRACE
741  std::cerr << "deleting " << get_class ().get_name ()
742  << " object (handle)" << std::endl;
743 #endif
744 }
745 
747 {
748 #if DEBUG_TRACE
749  std::cerr << "deleting " << get_class ().get_name ()
750  << " object (value)" << std::endl;
751 #endif
752 }
753 
754 OCTAVE_END_NAMESPACE(octave)
bool is_scalar(const dim_vector &dim)
Definition: Array-util.cc:116
cdef_object to_cdef(const octave_value &val)
Definition: cdef-utils.cc:143
std::list< cdef_class > lookup_classes(const Cell &cls_list)
Definition: cdef-utils.cc:113
octave_value to_ov(const cdef_object &obj)
Definition: cdef-utils.cc:128
Array< T, Alloc > index(const octave::idx_vector &i) const
Indexing without resizing.
Definition: Array-base.cc:710
void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
Definition: Array-base.cc:1128
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:503
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:524
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
Definition: Cell.h:43
void protect_var(T &var)
cdef_method find_method(const std::string &nm, bool local=false)
Definition: cdef-class.h:457
string_vector get_names()
Definition: cdef-class.h:302
std::map< std::string, cdef_property > get_property_map(int mode=property_normal)
Definition: cdef-class.h:297
std::string get_name() const
Definition: cdef-class.h:318
void delete_object(const cdef_object &obj)
Definition: cdef-class.h:322
cdef_property find_property(const std::string &nm)
Definition: cdef-class.h:463
cdef_object construct_object(const octave_value_list &args)
Definition: cdef-class.h:373
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
Definition: cdef-method.h:164
bool is_static() const
Definition: cdef-method.h:184
dim_vector dims() const
Definition: cdef-object.h:412
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)
Definition: cdef-object.cc:216
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: cdef-object.cc:316
cdef_class get_class() const
Definition: cdef-object.cc:189
void set_class(const cdef_class &cls)
Definition: cdef-object.cc:195
cdef_object_rep * make_array() const
Definition: cdef-object.cc:206
void release(const cdef_object &obj)
Definition: cdef-object.cc:44
virtual string_vector map_keys() const
Definition: cdef-object.cc:126
virtual bool is_meta_object() const
Definition: cdef-object.h:95
friend class cdef_object
Definition: cdef-object.h:54
virtual void destroy()
Definition: cdef-object.h:178
virtual bool is_handle_object() const
Definition: cdef-object.h:93
std::string class_name() const
Definition: cdef-object.cc:120
virtual octave_idx_type static_count() const
Definition: cdef-object.h:176
virtual cdef_class get_class() const
Definition: cdef-object.cc:114
refcount< octave_idx_type > m_count
Definition: cdef-object.h:187
octave_scalar_map m_map
Definition: cdef-object.h:533
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: cdef-object.cc:615
std::map< cdef_class, std::list< cdef_class > > m_ctor_list
Definition: cdef-object.h:536
bool is_constructed() const
Definition: cdef-object.h:528
void mark_for_construction(const cdef_class &)
Definition: cdef-object.cc:695
bool is_partially_constructed_for(const cdef_class &cls) const
Definition: cdef-object.cc:714
void mark_as_constructed()
Definition: cdef-object.h:524
void break_closure_cycles(const std::shared_ptr< stack_frame > &frame)
Definition: cdef-object.cc:504
bool is_constructed_for(const cdef_class &cls) const
Definition: cdef-object.cc:707
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)
Definition: cdef-object.cc:511
bool is_array() const
Definition: cdef-object.h:252
cdef_class get_class() const
Definition: cdef-object.cc:183
octave_map map_value() const
Definition: cdef-object.cc:137
bool ok() const
Definition: cdef-object.h:312
void set_class(const cdef_class &cls)
Definition: cdef-object.h:232
std::string class_name() const
Definition: cdef-object.h:234
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs, int ignore_copies=0)
Definition: cdef-object.h:299
cdef_object copy() const
Definition: cdef-object.h:250
Array< cdef_object > array_value() const
Definition: cdef-object.h:260
bool is(const cdef_object &obj) const
Definition: cdef-object.h:336
octave_value get(const std::string &pname) const
Definition: cdef-object.h:268
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)
Definition: cdef-object.h:291
void set_value(cdef_object &obj, const octave_value &val, bool do_check_access=true, const std::string &who="")
bool is_constant() const
octave_value get_value(const cdef_object &obj, bool do_check_access=true, const std::string &who="") const
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
void set_pos_if_unset(octave_idx_type nd_arg, octave_idx_type dim_arg)
void recover_from_exception()
void setfield(const std::string &key, const Cell &val)
Definition: oct-map.cc:282
const octave_value & contents(const_iterator p) const
Definition: oct-map.h:197
octave_idx_type nfields() const
Definition: oct-map.h:210
bool empty() const
Definition: ovl.h:115
octave_idx_type length() const
Definition: ovl.h:113
std::string class_name() const
Definition: ov.h:1347
Cell cell_value() const
void break_closure_cycles(const std::shared_ptr< octave::stack_frame > &)
@ op_asn_eq
Definition: ov.h:135
octave_value & assign(assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
Definition: error.cc:1063
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1078
void() error(const char *fmt,...)
Definition: error.cc:988
void interpreter_try(octave::unwind_protect &)
interpreter & __get_interpreter__()
bool quit_allowed
Definition: interpreter.cc:88
octave_idx_type n
Definition: mx-inlines.cc:761
T * r
Definition: mx-inlines.cc:781
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
std::atomic< sig_atomic_t > octave_interrupt_state
Definition: quit.cc:39