23 #if defined (HAVE_CONFIG_H) 52 OCTAVE_NORETURN
static 62 acc_s =
"class-restricted";
64 error (
"%s: method `%s' has %s access and cannot be run in this context",
65 from.c_str (), meth.
get_name ().c_str (), acc_s.c_str ());
68 OCTAVE_NORETURN
static 79 acc_s =
"class-restricted";
82 error (
"%s: property `%s' has %s access and cannot be set in this context",
83 from.c_str (), prop.
get_name ().c_str (), acc_s.c_str ());
85 error (
"%s: property `%s' has %s access and cannot be obtained in this context",
86 from.c_str (), prop.
get_name ().c_str (), acc_s.c_str ());
92 std::string::size_type pos =
nm.find_last_of (
'.');
94 if (pos != std::string::npos)
95 return nm.substr (pos + 1);
106 of->stash_dispatch_class (class_name);
151 bool load_if_not_found =
true)
155 return cdm.
find_class (
name, error_if_not_found, load_if_not_found);
182 static std::list<cdef_class>
185 std::list<cdef_class>
retval;
187 for (
int i = 0;
i < cls_list.
numel ();
i++)
198 to_ov (
const std::list<cdef_class>& class_list)
200 Cell cls (class_list.size (), 1);
203 for (
const auto& cdef_cls : class_list)
204 cls(
i++) =
to_ov (cdef_cls);
211 bool allow_equal =
true,
int max_depth = -1)
215 if (allow_equal && clsa == clsb)
217 else if (max_depth != 0)
221 for (
int i = 0; !
retval &&
i <
c.numel ();
i++)
226 max_depth < 0 ? max_depth : max_depth-1);
246 if (args.
length () == 1 && args(0).type_name () ==
"object")
265 in_constructor =
false;
303 bool is_prop_set =
false)
309 if (acc_s ==
"public")
319 if (acc_s ==
"private")
321 else if (acc_s ==
"protected")
332 if (! meth_name.empty ())
341 else if (! prop_name.empty ())
352 prop_name, is_prop_set);
380 for (
int i = 0;
i < acc.
numel ();
i++)
390 error (
"invalid property/method access in class `%s'",
407 if (! uf || ! uf->
body ())
431 if (stack_fcn && stack_fcn == method_fcn)
450 if (pl && pl->
size () > 0)
460 return obj.
is (arg0_obj);
474 if (args.
length () == 1 && args(0).type_name () ==
"object")
489 if (args.
length () == 1 && args(0).type_name () ==
"object" 490 && args(0).class_name () ==
"meta.class")
507 if (args.
length () == 1 && args(0).type_name () ==
"object" 508 && args(0).class_name () ==
"meta.class")
526 error (
"fromName: invalid number of parameters");
528 std::string name = args(0).xstring_value (
"fromName: CLASS_NAME must be a string");
538 if (args.
length () <= 1 || args(0).type_name () !=
"object")
539 error (
"fevalStatic: first argument must be a meta.class object");
543 std::string meth_name = args(1).xstring_value (
"fevalStatic: method name must be a string");
548 error (
"fevalStatic: method not found: %s", meth_name.c_str ());
551 error (
"fevalStatic: method `%s' is not static", meth_name.c_str ());
561 if (args.
length () != 2 || args(0).type_name () !=
"object" 562 || args(0).class_name () !=
"meta.class")
563 error (
"getConstant: first argument must be a meta.class object");
567 std::string prop_name = args(1).xstring_value (
"getConstant: property name must be a string");
572 error (
"getConstant: property not found: %s",
576 error (
"getConstant: property `%s' is not constant",
584 #define META_CLASS_CMP(OP, CLSA, CLSB, FUN) \ 585 static octave_value_list \ 586 class_ ## OP (const octave_value_list& args, int ) \ 588 octave_value_list retval; \ 590 if (args.length () != 2 \ 591 || args(0).type_name () != "object" \ 592 || args(1).type_name () != "object" \ 593 || args(0).class_name () != "meta.class" \ 594 || args(1).class_name () != "meta.class") \ 595 error (#OP ": invalid arguments"); \ 597 cdef_class clsa = to_cdef (args(0)); \ 599 cdef_class clsb = to_cdef (args(1)); \ 601 retval(0) = FUN (CLSA, CLSB); \ 618 if (args.length () == 1 && args(0).type_name () ==
"object")
624 if (!
retval(0).is_defined ())
626 "no default value for property `%s'",
645 const std::list<cdef_class>& super_list)
651 cls.
put (
"Abstract",
false);
652 cls.
put (
"ConstructOnLoad",
false);
653 cls.
put (
"ContainingPackage",
Matrix ());
654 cls.
put (
"Description",
"");
655 cls.
put (
"DetailedDescription",
"");
657 cls.
put (
"Hidden",
false);
658 cls.
put (
"InferiorClasses",
Cell ());
660 cls.
put (
"Properties",
Cell ());
661 cls.
put (
"Sealed",
false);
663 if (
name ==
"handle")
665 cls.
put (
"HandleCompatible",
true);
668 else if (super_list.empty ())
670 cls.
put (
"HandleCompatible",
false);
674 bool all_handle_compatible =
true;
675 bool has_handle_class =
false;
677 for (
const auto& cl : super_list)
679 all_handle_compatible = all_handle_compatible
680 && cl.get (
"HandleCompatible").bool_value ();
681 has_handle_class = has_handle_class || cl.is_handle_class ();
684 if (has_handle_class && ! all_handle_compatible)
685 error (
"%s: cannot mix handle and non-HandleCompatible classes",
688 cls.
put (
"HandleCompatible", all_handle_compatible);
689 if (has_handle_class)
712 cls.
put (
"Sealed",
true);
729 prop.
put (
"Description",
"");
730 prop.
put (
"DetailedDescription",
"");
731 prop.
put (
"Abstract",
false);
732 prop.
put (
"Constant",
false);
733 prop.
put (
"GetAccess", get_access);
734 prop.
put (
"SetAccess", set_access);
735 prop.
put (
"Dependent",
false);
736 prop.
put (
"Transient",
false);
737 prop.
put (
"Hidden",
false);
738 prop.
put (
"GetObservable",
false);
739 prop.
put (
"SetObservable",
false);
740 prop.
put (
"GetMethod", get_method);
741 prop.
put (
"SetMethod", set_method);
742 prop.
put (
"DefiningClass",
to_ov (cls));
744 prop.
put (
"HasDefault",
false);
771 meth.
put (
"Abstract",
false);
772 meth.
put (
"Access", m_access);
773 meth.
put (
"DefiningClass",
to_ov (cls));
774 meth.
put (
"Description",
"");
775 meth.
put (
"DetailedDescription",
"");
776 meth.
put (
"Hidden",
false);
777 meth.
put (
"Sealed",
true);
778 meth.
put (
"Static", is_static);
819 pack.
put (
"ContainingPackage",
Matrix ());
844 const std::list<octave_value_list>& idx,
875 if (
type.length () > skip && idx.size () > skip)
883 const std::list<octave_value_list>& idx,
896 if (
type.length () > skip && idx.size () > skip)
904 const std::list<octave_value_list>& idx,
927 retlist = meth.
execute (args, 1,
true,
"subsasgn");
929 if (retlist.
empty ())
930 error (
"overloaded method `subsasgn' did not return any value");
944 const std::list<octave_value_list>& idx,
947 if (
type.length () == 1 &&
type[0] ==
'(')
949 object =
object.make_array ();
981 if (lv.
length () != 1 || ! lv(0).is_scalar_type ())
982 error (
"@%s/numel: invalid return value", cls.
get_name ().c_str ());
984 retval = lv(0).idx_type_value (
true);
1006 if (
object.is_array ())
1008 os << class_name () << '>
'; 1013 octave_classdef::print_name_tag (std::ostream& os, 1014 const std::string& name) const 1016 return octave_base_value::print_name_tag (os, name); 1020 octave_classdef::print_with_name (std::ostream& os, const std::string& name, 1023 octave_base_value::print_with_name (os, name, print_padding); 1027 octave_classdef::is_instance_of (const std::string& cls_name) const 1029 cdef_class cls = lookup_class (cls_name, false, false); 1032 return is_superclass (cls, object.get_class ()); 1037 //---------------------------------------------------------------------------- 1039 class octave_classdef_meta : public octave_function 1042 octave_classdef_meta (const cdef_meta_object& obj) 1045 ~octave_classdef_meta (void) 1046 { object.meta_release (); } 1048 bool is_classdef_meta (void) const { return true; } 1050 bool is_package (void) const { return object.is_package(); } 1052 octave_function * function_value (bool = false) { return this; } 1055 subsref (const std::string& type, 1056 const std::list<octave_value_list>& idx, 1059 return object.meta_subsref (type, idx, nargout); 1062 octave_value_list call (octave::tree_evaluator&, int nargout, 1063 const octave_value_list& args) 1065 // Emulate ()-type meta subsref 1067 std::list<octave_value_list> idx (1, args); 1068 std::string type ("("); 1070 return subsref (type, idx, nargout); 1073 bool accepts_postfix_index (char type) const 1074 { return object.meta_accepts_postfix_index (type); } 1077 is_classdef_constructor (const std::string& cname = "") const 1079 bool retval = false; 1081 if (object.is_class ()) 1087 cdef_class cls (object); 1089 if (cls.get_name () == cname) 1098 cdef_meta_object object; 1101 //---------------------------------------------------------------------------- 1103 class octave_classdef_superclass_ref : public octave_function 1106 octave_classdef_superclass_ref (const octave_value_list& a) 1107 : octave_function (), args (a) { } 1109 ~octave_classdef_superclass_ref (void) = default; 1111 bool is_classdef_superclass_ref (void) const { return true; } 1113 octave_function * function_value (bool = false) { return this; } 1116 call (octave::tree_evaluator&, int nargout, const octave_value_list& idx) 1118 octave_value_list retval; 1120 std::string meth_name; 1121 bool in_constructor; 1124 ctx = get_class_context (meth_name, in_constructor); 1127 error ("superclass calls can only occur in methods or constructors"); 1129 std::string mname = args(0).string_value (); 1130 std::string cname = args(1).string_value (); 1132 cdef_class cls = lookup_class (cname); 1136 if (! is_direct_superclass (cls, ctx)) 1137 error ("`%s' is not
a direct superclass
of `%
s'", 1138 cname.c_str (), ctx.get_name ().c_str ()); 1140 if (! is_constructed_object (mname)) 1141 error ("cannot call superclass constructor with variable `%s'", 1144 octave::symbol_scope scope 1147 octave_value sym = scope.varval (mname); 1149 cls.run_constructor (to_cdef_ref (sym), idx); 1155 if (mname != meth_name) 1157 mname.c_str (), meth_name.c_str ()); 1159 if (! is_strict_superclass (cls, ctx)) 1160 error ("`%
s' is not a superclass of `%s'", 1161 cname.c_str (), ctx.get_name ().c_str ()); 1163 // I see 2 possible implementations here: 1164 // 1) use cdef_object::subsref with a different class 1165 // context; this avoids duplicating code, but 1166 // assumes the object is always the first argument 1167 // 2) lookup the method manually and call 1168 // cdef_method::execute; this duplicates part of 1169 // logic in cdef_object::subsref, but avoid the 1171 // Not being sure about the assumption of 1), I 1172 // go with option 2) for the time being. 1174 cdef_method meth = cls.find_method (meth_name, false); 1177 error ("no
method `%
s' found in superclass `%s'", 1178 meth_name.c_str (), cname.c_str ()); 1180 retval = meth.execute (idx, nargout, true, 1188 bool is_constructed_object (const std::string nm) 1190 octave::call_stack& cs 1193 octave_function *of = cs.current (); 1195 if (of->is_classdef_constructor ()) 1197 octave_user_function *uf = of->user_function_value (true); 1201 octave::tree_parameter_list *ret_list = uf->return_list (); 1203 if (ret_list && ret_list->length () == 1) 1204 return (ret_list->front ()->name () == nm); 1212 octave_value_list args; 1215 //---------------------------------------------------------------------------- 1218 cdef_object_rep::release (const cdef_object& obj) 1220 // We need to be careful to keep a reference to the object if we are 1221 // calling the delete method. The object is passed to the delete 1222 // method as an argument and if the count is already zero when we 1223 // do that, then we will increment the count while creating the 1224 // argument list for the delete method and then it will be decremented 1225 // back to zero and we'll find ourselves in an infinite loop. 1227 if (refcount - 1 > static_count ()) 1233 if (is_handle_object () && ! is_meta_object ()) 1235 octave::unwind_protect frame; 1237 // Clear interrupts. 1238 frame.protect_var (octave_interrupt_state); 1239 octave_interrupt_state = 0; 1242 frame.protect_var (quit_allowed); 1243 quit_allowed = false; 1245 interpreter_try (frame); 1249 // Call classdef "delete()
" method on object 1250 get_class ().delete_object (obj); 1252 catch (const octave::interrupt_exception&) 1254 octave::interpreter::recover_from_exception (); 1256 warning ("interrupt occurred in
handle class delete method"); 1258 catch (const octave::execution_exception&) 1260 std::string msg = last_error_message (); 1265 catch (const octave::exit_exception&) 1267 // This shouldn't happen since we disabled quit above. 1268 warning ("exit disabled
while executing
handle class delete method"); 1270 catch (...) // Yes, the black hole. We're in a d-tor. 1272 // This shouldn't happen, in theory. 1277 // Now it is safe to set the count to zero. 1284 cdef_object::map_value (void) const 1288 warning_with_id ("Octave:classdef-to-
struct", 1289 "struct: converting
a classdef
object into
a struct " 1291 "All
properties are returned, including
private and
" 1294 cdef_class cls = get_class (); 1298 std::map<std::string, cdef_property> props; 1300 props = cls.get_property_map (cdef_class::property_all); 1302 // FIXME: Why not const here? 1303 for (auto& prop_val : props) 1307 Array<cdef_object> a_obj = array_value (); 1309 Cell cvalue (a_obj.dims ()); 1311 for (octave_idx_type i = 0; i < a_obj.numel (); i++) 1312 cvalue (i) = prop_val.second.get_value (a_obj(i), false); 1314 retval.setfield (prop_val.first, cvalue); 1318 Cell cvalue (dim_vector (1, 1), 1319 prop_val.second.get_value (*this, false)); 1321 retval.setfield (prop_val.first, cvalue); 1330 cdef_object_rep::map_keys (void) const 1332 cdef_class cls = get_class (); 1335 return cls.get_names (); 1337 return string_vector (); 1341 cdef_object_scalar::subsref (const std::string& type, 1342 const std::list<octave_value_list>& idx, 1343 int nargout, size_t& skip, 1344 const cdef_class& context, bool auto_add) 1348 cdef_class cls = (context.ok () ? context : get_class ()); 1350 octave_value_list retval; 1359 std::string name = (idx.front ())(0).string_value (); 1361 cdef_method meth = cls.find_method (name); 1365 int _nargout = (type.length () > 2 ? 1 : nargout); 1367 octave_value_list args; 1371 if (type.length () > 1 && type[1] == '(') 1373 std::list<octave_value_list>::const_iterator it = idx.begin (); 1380 if (meth.is_static ()) 1381 retval = meth.execute (args, _nargout, true, "subsref
"); 1385 retval = meth.execute (cdef_object (this), args, _nargout, 1392 cdef_property prop = cls.find_property (name); 1397 if (prop.is_constant ()) 1398 retval(0) = prop.get_value (true, "subsref"); 1402 retval(0) = prop.get_value (cdef_object (this), 1413 const octave_value_list& ival = idx.front (); 1416 cdef_object this_obj (this); 1421 retval(0) = to_ov (this_obj); 1425 Array<cdef_object> arr (dim_vector (1, 1), this_obj); 1427 cdef_object new_obj = cdef_object (new cdef_object_array (arr)); 1429 new_obj.set_class (get_class ()); 1431 retval = new_obj.subsref (type, idx, nargout, skip, cls, auto_add); 1437 error ("object cannot be indexed with `%
c'", type[0]); 1445 cdef_object_scalar::subsasgn (const std::string& type, 1446 const std::list<octave_value_list>& idx, 1447 const octave_value& rhs) 1449 octave_value retval; 1451 cdef_class cls = get_class (); 1457 std::string name = (idx.front ())(0).string_value (); 1459 cdef_property prop = cls.find_property (name); 1462 error ("subsasgn: unknown property: %s", name.c_str ()); 1464 if (prop.is_constant ()) 1465 error ("subsasgn: cannot assign constant property: %s", 1470 cdef_object obj (this); 1472 if (type.length () == 1) 1474 prop.set_value (obj, rhs, true, "subsasgn"); 1476 retval = to_ov (obj); 1481 prop.get_value (obj, true, "subsasgn"); 1483 std::list<octave_value_list> args (idx); 1485 args.erase (args.begin ()); 1487 val = val.assign (octave_value::op_asn_eq, 1488 type.substr (1), args, rhs); 1490 if (val.class_name () != "object" 1491 || ! to_cdef (val).is_handle_object ()) 1492 prop.set_value (obj, val, true, "subsasgn"); 1494 retval = to_ov (obj); 1503 cdef_object this_obj (this); 1505 Array<cdef_object> arr (dim_vector (1, 1), this_obj); 1507 cdef_object new_obj = cdef_object (new cdef_object_array (arr)); 1509 new_obj.set_class (get_class ()); 1511 octave_value tmp = new_obj.subsasgn (type, idx, rhs); 1518 error ("subsasgn: object cannot be index with `%c'", type[0]); 1526 cdef_object_scalar::mark_for_construction (const cdef_class& cls) 1528 std::string cls_name = cls.get_name (); 1530 Cell supcls = cls.get ("SuperClasses
").cell_value (); 1532 std::list<cdef_class> supcls_list = lookup_classes (supcls); 1534 ctor_list[cls] = supcls_list; 1538 cdef_object_array::subsref (const std::string& type, 1539 const std::list<octave_value_list>& idx, 1540 int /* nargout */, size_t& skip, 1541 const cdef_class& /* context */, bool auto_add) 1543 octave_value_list retval; 1551 const octave_value_list& ival = idx.front (); 1556 retval(0) = to_ov (cdef_object (this)); 1560 bool is_scalar = true; 1561 Array<idx_vector> iv (dim_vector (1, ival.length ())); 1563 for (int i = 0; i < ival.length (); i++) 1567 iv(i) = ival(i).index_vector (); 1569 catch (octave::index_exception& e) 1571 // Rethrow to allow more info to be reported later. 1572 e.set_pos_if_unset (ival.length (), i+1); 1576 is_scalar = is_scalar && iv(i).is_scalar (); 1579 Array<cdef_object> ires = array.index (iv, auto_add); 1581 // If resizing is enabled (auto_add = true), it's possible 1582 // indexing was out-of-bound and the result array contains 1583 // invalid cdef_objects. 1586 fill_empty_values (ires); 1589 retval(0) = to_ov (ires(0)); 1592 cdef_object array_obj (new cdef_object_array (ires)); 1594 array_obj.set_class (get_class ()); 1596 retval(0) = to_ov (array_obj); 1602 if (type.size () == 1 && idx.size () == 1) 1606 octave_idx_type n = array.numel (); 1610 cdef_class dummy_cls; 1612 for (octave_idx_type i = 0; i < n; i++) 1614 octave_value_list r = array(i).subsref (type, idx, 1, dummy_skip, 1617 if (r.length () > 0) 1621 retval(0) = octave_value (c, true); 1628 error ("can
't perform indexing operation on array of %s objects", 1629 class_name ().c_str ()); 1637 cdef_object_array::subsasgn (const std::string& type, 1638 const std::list<octave_value_list>& idx, 1639 const octave_value& rhs) 1641 octave_value retval; 1646 if (type.length () == 1) 1648 cdef_object rhs_obj = to_cdef (rhs); 1650 if (rhs_obj.get_class () != get_class ()) 1652 rhs_obj.class_name ().c_str (), 1653 class_name ().c_str ()); 1655 const octave_value_list& ival = idx.front (); 1656 bool is_scalar = true; 1657 Array<idx_vector> iv (dim_vector (1, ival.length ())); 1659 for (int i = 0; i < ival.length (); i++) 1663 iv(i) = ival(i).index_vector (); 1665 catch (octave::index_exception& e) 1667 e.set_pos_if_unset (ival.length (), i+1); 1668 throw; // var name set in pt-idx.cc / pt-assign.cc 1671 is_scalar = is_scalar && iv(i).is_scalar (); 1674 Array<cdef_object> rhs_mat; 1676 if (! rhs_obj.is_array ()) 1678 rhs_mat = Array<cdef_object> (dim_vector (1, 1)); 1679 rhs_mat(0) = rhs_obj; 1682 rhs_mat = rhs_obj.array_value (); 1684 octave_idx_type n = array.numel (); 1686 array.assign (iv, rhs_mat, cdef_object ()); 1688 if (array.numel () > n) 1689 fill_empty_values (); 1692 retval = to_ov (cdef_object (this)); 1696 const octave_value_list& ivl = idx.front (); 1698 // Fill in trailing singleton dimensions so that 1699 // array.index doesn't create a new blank entry (bug #46660). 1700 const octave_idx_type one = static_cast<octave_idx_type> (1); 1701 const octave_value_list& ival = ivl.length () >= 2 1702 ? ivl : ((array.dims ()(0) == 1) 1704 : ovl (ivl(0), one)); 1706 bool is_scalar = true; 1708 Array<idx_vector> iv (dim_vector (1, ival.length ())); 1710 for (int i = 0; i < ival.length (); i++) 1714 iv(i) = ival(i).index_vector (); 1716 catch (octave::index_exception& e) 1718 // Rethrow to allow more info to be reported later. 1719 e.set_pos_if_unset (ival.length (), i+1); 1723 is_scalar = is_scalar && iv(i).is_scalar (); 1726 error ("subsasgn: invalid indexing
for object array assignment
" 1727 ", the index must reference
a single
object in the
" 1731 Array<cdef_object> a = array.index (iv, true); 1733 if (a.numel () != 1) 1734 error ("subsasgn: invalid indexing
for object array assignment
"); 1736 cdef_object obj = a(0); 1738 int ignore_copies = 0; 1740 // If the object in 'a' is not valid, this means the index 1741 // was out-of-bound and we need to create a new object. 1744 obj = get_class ().construct_object (octave_value_list ()); 1746 // Optimize the subsasgn call to come. There are 2 copies 1747 // that we can safely ignore: 1752 std::list<octave_value_list> next_idx (idx); 1754 next_idx.erase (next_idx.begin ()); 1756 octave_value tmp = obj.subsasgn (type.substr (1), next_idx, 1757 rhs, ignore_copies); 1759 cdef_object robj = to_cdef (tmp); 1763 || robj.get_class () != get_class ()) 1764 error ("subasgn: invalid assignment into
array of %
s objects
", 1765 class_name ().c_str ()); 1767 // Small optimization, when dealing with handle 1768 // objects, we don't need to re-assign the result 1769 // of subsasgn back into the array. 1771 if (! robj.is (a(0))) 1773 Array<cdef_object> rhs_a (dim_vector (1, 1), 1776 octave_idx_type n = array.numel (); 1778 array.assign (iv, rhs_a); 1780 if (array.numel () > n) 1781 fill_empty_values (); 1786 retval = to_ov (cdef_object (this)); 1791 error ("can
't perform indexing operation on array of %s objects", 1792 class_name ().c_str ()); 1800 cdef_object_array::fill_empty_values (Array<cdef_object>& arr) 1802 cdef_class cls = get_class (); 1806 int n = arr.numel (); 1808 for (int i = 0; i < n; i++) 1810 if (! arr.xelem (i).ok ()) 1814 obj = cls.construct_object (octave_value_list ()); 1816 arr.xelem (i) = obj; 1819 arr.xelem (i) = obj.copy (); 1825 cdef_object_scalar::is_constructed_for (const cdef_class& cls) const 1827 return (is_constructed () 1828 || ctor_list.find (cls) == ctor_list.end ()); 1832 cdef_object_scalar::is_partially_constructed_for (const cdef_class& cls) const 1834 std::map< cdef_class, std::list<cdef_class>>::const_iterator it; 1836 if (is_constructed ()) 1838 else if ((it = ctor_list.find (cls)) == ctor_list.end () 1839 || it->second.empty ()) 1842 for (const auto& cdef_cls : it->second) 1843 if (! is_constructed_for (cdef_cls)) 1850 cdef_object_scalar::mark_as_constructed (const cdef_class& cls) 1852 ctor_list.erase (cls); 1855 handle_cdef_object::~handle_cdef_object (void) 1858 std::cerr << "deleting " << get_class ().get_name () 1859 << " object (handle)" << std::endl; 1863 value_cdef_object::~value_cdef_object (void) 1866 std::cerr << "deleting " << get_class ().get_name () 1867 << " object (value)" << std::endl; 1871 cdef_class::cdef_class_rep::cdef_class_rep (const std::list<cdef_class>& superclasses) 1872 : cdef_meta_object_rep (), member_count (0), handle_class (false), 1873 object_count (0), meta (false) 1875 put ("SuperClasses", to_ov (superclasses)); 1876 implicit_ctor_list = superclasses; 1880 cdef_class::cdef_class_rep::find_method (const std::string& nm, bool local) 1882 method_iterator it = method_map.find (nm); 1884 if (it == method_map.end ()) 1886 // FIXME: look into class directory 1890 cdef_method& meth = it->second; 1892 // FIXME: check if method reload needed 1900 // Look into superclasses 1902 Cell super_classes = get ("SuperClasses").cell_value (); 1904 for (int i = 0; i < super_classes.numel (); i++) 1906 cdef_class cls = lookup_class (super_classes(i)); 1908 cdef_method meth = cls.find_method (nm); 1915 return cdef_method (); 1918 class ctor_analyzer : public octave::tree_walker 1921 ctor_analyzer (const std::string& ctor, const std::string& obj) 1922 : octave::tree_walker (), who (ctor), obj_name (obj) { } 1924 void visit_statement_list (octave::tree_statement_list& t) 1926 for (const auto& stmt_p : t) 1927 stmt_p->accept (*this); 1930 void visit_statement (octave::tree_statement& t) 1932 if (t.is_expression ()) 1933 t.expression ()->accept (*this); 1936 void visit_simple_assignment (octave::tree_simple_assignment& t) 1938 t.right_hand_side ()->accept (*this); 1941 void visit_multi_assignment (octave::tree_multi_assignment& t) 1943 t.right_hand_side ()->accept (*this); 1946 void visit_index_expression (octave::tree_index_expression& t) 1948 t.expression ()->accept (*this); 1951 void visit_funcall (octave::tree_funcall& t) 1953 octave_value fcn = t.function (); 1955 if (fcn.is_function ()) 1957 octave_function *of = fcn.function_value (true); 1961 if (of->name () == "__superclass_reference__") 1963 octave_value_list args = t.arguments (); 1965 if (args(0).string_value () == obj_name) 1967 std::string class_name = args(1).string_value (); 1969 cdef_class cls = lookup_class (class_name, false); 1972 ctor_list.push_back (cls); 1979 std::list<cdef_class> get_constructor_list (void) const 1980 { return ctor_list; } 1983 void visit_anon_fcn_handle (octave::tree_anon_fcn_handle&) { } 1984 void visit_argument_list (octave::tree_argument_list&) { } 1985 void visit_binary_expression (octave::tree_binary_expression&) { } 1986 void visit_break_command (octave::tree_break_command&) { } 1987 void visit_colon_expression (octave::tree_colon_expression&) { } 1988 void visit_continue_command (octave::tree_continue_command&) { } 1989 void visit_decl_command (octave::tree_decl_command&) { } 1990 void visit_decl_init_list (octave::tree_decl_init_list&) { } 1991 void visit_decl_elt (octave::tree_decl_elt&) { } 1992 void visit_simple_for_command (octave::tree_simple_for_command&) { } 1993 void visit_complex_for_command (octave::tree_complex_for_command&) { } 1994 void visit_octave_user_script (octave_user_script&) { } 1995 void visit_octave_user_function (octave_user_function&) { } 1996 void visit_function_def (octave::tree_function_def&) { } 1997 void visit_identifier (octave::tree_identifier&) { } 1998 void visit_if_clause (octave::tree_if_clause&) { } 1999 void visit_if_command (octave::tree_if_command&) { } 2000 void visit_if_command_list (octave::tree_if_command_list&) { } 2001 void visit_switch_case (octave::tree_switch_case&) { } 2002 void visit_switch_case_list (octave::tree_switch_case_list&) { } 2003 void visit_switch_command (octave::tree_switch_command&) { } 2004 void visit_matrix (octave::tree_matrix&) { } 2005 void visit_cell (octave::tree_cell&) { } 2006 void visit_no_op_command (octave::tree_no_op_command&) { } 2007 void visit_constant (octave::tree_constant&) { } 2008 void visit_fcn_handle (octave::tree_fcn_handle&) { } 2009 void visit_parameter_list (octave::tree_parameter_list&) { } 2010 void visit_postfix_expression (octave::tree_postfix_expression&) { } 2011 void visit_prefix_expression (octave::tree_prefix_expression&) { } 2012 void visit_return_command (octave::tree_return_command&) { } 2013 void visit_return_list (octave::tree_return_list&) { } 2014 void visit_try_catch_command (octave::tree_try_catch_command&) { } 2015 void visit_unwind_protect_command (octave::tree_unwind_protect_command&) { } 2016 void visit_while_command (octave::tree_while_command&) { } 2017 void visit_do_until_command (octave::tree_do_until_command&) { } 2020 // The name of the constructor being analyzed. 2023 // The name of the first output argument of the constructor. 2024 std::string obj_name; 2026 // The list of superclass constructors that are explicitly called. 2027 std::list<cdef_class> ctor_list; 2031 cdef_class::cdef_class_rep::install_method (const cdef_method& meth) 2033 method_map[meth.get_name ()] = meth; 2037 if (meth.is_constructor ()) 2039 // Analyze the constructor code to determine what superclass 2040 // constructors are called explicitly. 2042 octave_function *of = meth.get_function ().function_value (true); 2046 octave_user_function *uf = of->user_function_value (true); 2050 octave::tree_parameter_list *ret_list = uf->return_list (); 2051 octave::tree_statement_list *body = uf->body (); 2053 if (! ret_list || ret_list->size () != 1) 2054 error ("%s: invalid constructor output arguments", 2055 meth.get_name ().c_str ()); 2057 std::string obj_name = ret_list->front ()->name (); 2058 ctor_analyzer a (meth.get_name (), obj_name); 2062 std::list<cdef_class> explicit_ctor_list 2063 = a.get_constructor_list (); 2065 for (const auto& cdef_cls : explicit_ctor_list) 2068 std::cerr << "explicit superclass constructor: " 2069 << cdef_cls.get_name () << std::endl; 2072 implicit_ctor_list.remove (cdef_cls); 2080 cdef_class::cdef_class_rep::load_all_methods (void) 2082 // FIXME: re-scan class directory 2086 cdef_class::cdef_class_rep::get_methods (void) 2088 std::map<std::string,cdef_method> meths; 2090 find_methods (meths, false); 2092 Cell c (meths.size (), 1); 2096 for (const auto& nm_mthd : meths) 2097 c(idx++, 0) = to_ov (nm_mthd.second); 2103 cdef_class::cdef_class_rep::find_methods (std::map<std::string, 2104 cdef_method>& meths, 2105 bool only_inherited) 2107 load_all_methods (); 2109 method_const_iterator it; 2111 for (it = method_map.begin (); it != method_map.end (); ++it) 2113 if (! it->second.is_constructor ()) 2115 std::string nm = it->second.get_name (); 2117 if (meths.find (nm) == meths.end ()) 2121 octave_value acc = it->second.get ("Access"); 2123 if (! acc.is_string () 2124 || acc.string_value () == "private") 2128 meths[nm] = it->second; 2133 // Look into superclasses 2135 Cell super_classes = get ("SuperClasses").cell_value (); 2137 for (int i = 0; i < super_classes.numel (); i++) 2139 cdef_class cls = lookup_class (super_classes(i)); 2141 cls.get_rep ()->find_methods (meths, true); 2146 cdef_class::cdef_class_rep::find_property (const std::string& nm) 2148 property_iterator it = property_map.find (nm); 2150 if (it != property_map.end ()) 2152 cdef_property& prop = it->second; 2158 // Look into superclasses 2160 Cell super_classes = get ("SuperClasses").cell_value (); 2162 for (int i = 0; i < super_classes.numel (); i++) 2164 cdef_class cls = lookup_class (super_classes(i)); 2166 cdef_property prop = cls.find_property (nm); 2172 return cdef_property (); 2176 cdef_class::cdef_class_rep::install_property (const cdef_property& prop) 2178 property_map[prop.get_name ()] = prop; 2184 cdef_class::cdef_class_rep::get_properties (int mode) 2186 std::map<std::string,cdef_property> props; 2188 props = get_property_map (mode); 2190 Cell c (props.size (), 1); 2194 for (const auto& pname_prop : props) 2195 c(idx++, 0) = to_ov (pname_prop.second); 2200 std::map<std::string, cdef_property> 2201 cdef_class::cdef_class_rep::get_property_map (int mode) 2203 std::map<std::string,cdef_property> props; 2205 find_properties (props, mode); 2211 cdef_class::cdef_class_rep::find_properties (std::map<std::string, 2212 cdef_property>& props, 2215 property_const_iterator it; 2217 for (it = property_map.begin (); it != property_map.end (); ++it) 2219 std::string nm = it->second.get_name (); 2221 if (props.find (nm) == props.end ()) 2223 if (mode == property_inherited) 2225 octave_value acc = it->second.get ("GetAccess"); 2227 if (! acc.is_string () 2228 || acc.string_value () == "private") 2232 props[nm] = it->second; 2236 // Look into superclasses 2238 Cell super_classes = get ("SuperClasses").cell_value (); 2240 for (int i = 0; i < super_classes.numel (); i++) 2242 cdef_class cls = lookup_class (super_classes(i)); 2244 cls.get_rep ()->find_properties (props, 2245 (mode == property_all 2247 : property_inherited)); 2252 cdef_class::cdef_class_rep::find_names (std::set<std::string>& names, 2255 load_all_methods (); 2257 for (const auto& cls_fnmap : method_map) 2259 if (! cls_fnmap.second.is_constructor ()) 2261 std::string nm = cls_fnmap.second.get_name (); 2265 octave_value acc = cls_fnmap.second.get ("Access"); 2267 if (! acc.is_string() 2268 || acc.string_value () != "public") 2276 for (const auto& pname_prop : property_map) 2278 std::string nm = pname_prop.second.get_name (); 2282 octave_value acc = pname_prop.second.get ("GetAccess"); 2284 if (! acc.is_string() 2285 || acc.string_value () != "public") 2292 // Look into superclasses 2294 Cell super_classes = get ("SuperClasses").cell_value (); 2296 for (int i = 0; i < super_classes.numel (); i++) 2298 cdef_class cls = lookup_class (super_classes(i)); 2300 cls.get_rep ()->find_names (names, all); 2305 cdef_class::cdef_class_rep::get_names (void) 2307 std::set<std::string> names; 2309 find_names (names, false); 2311 string_vector v (names); 2313 return v.sort (true); 2317 cdef_class::cdef_class_rep::delete_object (const cdef_object& obj) 2319 cdef_method dtor = find_method ("delete"); 2322 dtor.execute (obj, octave_value_list (), 0, true, "destructor"); 2324 // FIXME: should we destroy corresponding properties here? 2326 // Call "delete" in super classes 2328 Cell super_classes = get ("SuperClasses").cell_value (); 2330 for (int i = 0; i < super_classes.numel (); i++) 2332 cdef_class cls = lookup_class (super_classes(i)); 2334 if (cls.get_name () != "handle") 2335 cls.delete_object (obj); 2340 cdef_class::cdef_class_rep::meta_subsref (const std::string& type, 2341 const std::list<octave_value_list>& idx, 2346 octave_value_list retval; 2354 std::cerr << "constructor" << std::endl; 2357 retval(0) = construct (idx.front ()); 2362 // Static method, constant (or property?) 2365 std::cerr << "static method/property" << std::endl; 2368 if (idx.front ().length () != 1) 2369 error ("invalid meta.class indexing"); 2371 std::string nm = idx.front ()(0).xstring_value ("invalid meta.class indexing, expected a method or property name"); 2373 cdef_method meth = find_method (nm); 2377 if (! meth.is_static ()) 2378 error ("method `%s' is not
static", nm.c_str ()); 2380 octave_value_list args; 2382 if (type.length () > 1 && idx.size () > 1 2385 args = *(++(idx.begin ())); 2389 retval = meth.execute (args, (type.length () > skip 2390 ? 1 : nargout), true, 2395 cdef_property prop = find_property (nm); 2400 if (! prop.is_constant ()) 2401 error ("property `%s' is not constant
", nm.c_str ()); 2403 retval(0) = prop.get_value (true, "meta.class
"); 2409 error ("invalid meta.class indexing
"); 2413 if (type.length () > skip && idx.size () > skip && ! retval.empty ()) 2414 retval = retval(0).next_subsref (nargout, type, idx, skip); 2420 cdef_class::cdef_class_rep::meta_release (void) 2425 cdm.unregister_class (wrap ()); 2429 cdef_class::cdef_class_rep::initialize_object (cdef_object& obj) 2431 // Populate the object with default property values 2433 std::list<cdef_class> super_classes = lookup_classes ( 2434 get ("SuperClasses
").cell_value ()); 2436 for (auto& cls : super_classes) 2437 cls.initialize_object (obj); 2439 for (const auto& pname_prop : property_map) 2441 if (! pname_prop.second.get ("Dependent
").bool_value ()) 2443 octave_value pvalue = pname_prop.second.get ("DefaultValue
"); 2445 if (pvalue.is_defined ()) 2446 obj.put (pname_prop.first, pvalue); 2448 obj.put (pname_prop.first, octave_value (Matrix ())); 2453 obj.mark_for_construction (cdef_class (this)); 2457 cdef_class::cdef_class_rep::run_constructor (cdef_object& obj, 2458 const octave_value_list& args) 2460 octave_value_list empty_args; 2462 for (const auto& cls : implicit_ctor_list) 2464 cdef_class supcls = lookup_class (cls); 2466 supcls.run_constructor (obj, empty_args); 2469 std::string cls_name = get_name (); 2470 std::string ctor_name = get_base_name (cls_name); 2472 cdef_method ctor = find_method (ctor_name); 2476 octave_value_list ctor_args (args); 2477 octave_value_list ctor_retval; 2479 ctor_args.prepend (to_ov (obj)); 2480 ctor_retval = ctor.execute (ctor_args, 1, true, "constructor
"); 2482 if (ctor_retval.length () != 1) 2484 ctor_name.c_str ()); 2486 obj = to_cdef (ctor_retval(0)); 2489 obj.mark_as_constructed (wrap ()); 2493 cdef_class::cdef_class_rep::construct (const octave_value_list& args) 2495 cdef_object obj = construct_object (args); 2500 return octave_value (); 2504 cdef_class::cdef_class_rep::construct_object (const octave_value_list& args) 2507 error ("cannot instantiate
object for abstract class `%
s'", 2508 get_name ().c_str ()); 2512 if (is_meta_class ()) 2514 // This code path is only used to create empty meta objects 2515 // as filler for the empty values within a meta object array. 2517 cdef_class this_cls = wrap (); 2519 static cdef_object empty_class; 2522 = octave::__get_cdef_manager__ ("cdef_class::cdef_class_rep::construct_object"); 2524 if (this_cls == cdm.meta_class ()) 2526 if (! empty_class.ok ()) 2527 empty_class = cdm.make_class ("", std::list<cdef_class> ()); 2530 else if (this_cls == cdm.meta_property ()) 2532 static cdef_property empty_property; 2534 if (! empty_class.ok ()) 2535 empty_class = cdm.make_class ("", std::list<cdef_class> ()); 2536 if (! empty_property.ok ()) 2537 empty_property = cdm.make_property (empty_class, ""); 2538 obj = empty_property; 2540 else if (this_cls == cdm.meta_method ()) 2542 static cdef_method empty_method; 2544 if (! empty_class.ok ()) 2545 empty_class = cdm.make_class ("", std::list<cdef_class> ()); 2546 if (! empty_method.ok ()) 2547 empty_method = cdm.make_method (empty_class, "", octave_value ()); 2550 else if (this_cls == cdm.meta_package ()) 2552 static cdef_package empty_package; 2554 if (! empty_package.ok ()) 2555 empty_package = cdm.make_package (""); 2556 obj = empty_package; 2559 panic_impossible (); 2565 if (is_handle_class ()) 2566 obj = cdef_object (new handle_cdef_object ()); 2568 obj = cdef_object (new value_cdef_object ()); 2569 obj.set_class (wrap ()); 2571 initialize_object (obj); 2573 run_constructor (obj, args); 2578 return cdef_object (); 2582 compute_attribute_value (octave::tree_evaluator& tw, 2583 octave::tree_classdef_attribute *t) 2585 octave::tree_expression *expr = t->expression (); 2589 if (expr->is_identifier ()) 2591 std::string s = expr->name (); 2594 return std::string ("public"); 2595 else if (s == "protected") 2596 return std::string ("protected"); 2597 else if (s == "private") 2598 return std::string ("private"); 2601 return tw.evaluate (expr); 2604 return octave_value (true); 2607 template <typename T> 2609 attribute_value_to_string (T *t, octave_value v) 2612 return v.string_value (); 2613 else if (t->expression ()) 2614 return t->expression ()->original_text (); 2620 cdef_class::make_meta_class (octave::interpreter& interp, 2621 octave::tree_classdef *t, bool is_at_folder) 2624 std::string class_name, full_class_name; 2628 class_name = full_class_name = t->ident ()->name (); 2629 if (! t->package_name ().empty ()) 2630 full_class_name = t->package_name () + '.
' + full_class_name; 2633 std::cerr << "class: " << full_class_name << std::endl; 2636 std::list<cdef_class> slist; 2638 if (t->superclass_list ()) 2640 for (auto& scls : (*t->superclass_list ())) 2642 std::string sclass_name = (scls)->class_name (); 2645 std::cerr << "superclass: " << sclass_name << std::endl; 2648 cdef_class sclass = lookup_class (sclass_name); 2650 if (sclass.get ("Sealed").bool_value ()) 2651 error ("`%s' cannot inherit from `%
s', because it is sealed", 2652 full_class_name.c_str (), sclass_name.c_str ()); 2654 slist.push_back (sclass); 2659 = octave::__get_cdef_manager__ ("cdef_class::make_meta_class"); 2661 retval = cdm.make_class (full_class_name, slist); 2663 // Package owning this class 2665 if (! t->package_name ().empty ()) 2667 cdef_package pack = cdm.find_package (t->package_name ()); 2670 retval.put ("ContainingPackage", to_ov (pack)); 2675 octave::tree_evaluator& tw = interp.get_evaluator (); 2677 if (t->attribute_list ()) 2679 for (const auto& attr : (*t->attribute_list ())) 2681 std::string aname = attr->ident ()->name (); 2682 octave_value avalue = compute_attribute_value (tw, attr); 2685 std::cerr << "class attribute: " << aname << " = " 2686 << attribute_value_to_string (attr, avalue) << std::endl; 2689 retval.put (aname, avalue); 2693 octave::tree_classdef_body *b = t->body (); 2697 // Keep track of the get/set accessor methods. They will be used 2698 // later on when creating properties. 2700 std::map<std::string, octave_value> get_methods; 2701 std::map<std::string, octave_value> set_methods; 2705 std::list<octave::tree_classdef_methods_block *> mb_list = b->methods_list (); 2707 octave::load_path& lp = interp.get_load_path (); 2709 for (auto& mb_p : mb_list) 2711 std::map<std::string, octave_value> amap; 2714 std::cerr << "method block" << std::endl; 2717 // Method attributes 2719 if (mb_p->attribute_list ()) 2721 for (auto& attr_p : *mb_p->attribute_list ()) 2723 std::string aname = attr_p->ident ()->name (); 2724 octave_value avalue = compute_attribute_value (tw, attr_p); 2727 std::cerr << "method attribute: " << aname << " = " 2728 << attribute_value_to_string (attr_p, avalue) 2732 amap[aname] = avalue; 2738 if (mb_p->element_list ()) 2740 for (auto& mtd : *mb_p->element_list ()) 2742 std::string mname = mtd.function_value ()->name (); 2743 std::string mprefix = mname.substr (0, 4); 2745 if (mprefix == "get.") 2746 get_methods[mname.substr (4)] = 2747 make_fcn_handle (mtd, full_class_name + '>
' + mname); 2748 else if (mprefix == "set.") 2749 set_methods[mname.substr (4)] = 2750 make_fcn_handle (mtd, full_class_name + '>
' + mname); 2753 cdef_method meth = cdm.make_method (retval, mname, mtd); 2756 std::cerr << (mname == class_name ? "constructor" 2758 << ": " << mname << std::endl; 2761 for (auto& attrnm_val : amap) 2762 meth.put (attrnm_val.first, attrnm_val.second); 2764 retval.install_method (meth); 2772 // Look for all external methods visible on octave path at the 2773 // time of loading of the class. 2775 // FIXME: This is an "extension" to Matlab behavior, which only looks 2776 // in the @-folder containing the original classdef file. However, 2777 // this is easier to implement it that way at the moment. 2779 std::list<std::string> external_methods 2780 = lp.methods (full_class_name); 2782 for (const auto& mtdnm : external_methods) 2784 // FIXME: should we issue a warning if the method is already 2785 // defined in the classdef file? 2787 if (mtdnm != class_name 2788 && ! retval.find_method (mtdnm, true).ok ()) 2790 // Create a dummy method that is used until the actual 2791 // method is loaded. 2792 octave_user_function *fcn = new octave_user_function (); 2794 fcn->stash_function_name (mtdnm); 2797 = cdm.make_method (retval, mtdnm, octave_value (fcn)); 2799 retval.install_method (meth); 2806 // FIXME: default property expression should be able to call static 2807 // methods of the class being constructed. A restricted CLASSNAME 2808 // symbol should be added to the scope before evaluating default 2809 // value expressions. 2811 std::list<octave::tree_classdef_properties_block *> pb_list 2812 = b->properties_list (); 2814 for (auto& pb_p : pb_list) 2816 std::map<std::string, octave_value> amap; 2819 std::cerr << "property block" << std::endl; 2822 // Property attributes 2824 if (pb_p->attribute_list ()) 2826 for (auto& attr_p : *pb_p->attribute_list ()) 2828 std::string aname = attr_p->ident ()->name (); 2829 octave_value avalue = compute_attribute_value (tw, attr_p); 2832 std::cerr << "property attribute: " << aname << " = " 2833 << attribute_value_to_string (attr_p, avalue) 2837 if (aname == "Access") 2839 amap["GetAccess"] = avalue; 2840 amap["SetAccess"] = avalue; 2843 amap[aname] = avalue; 2849 if (pb_p->element_list ()) 2851 for (auto& prop_p : *pb_p->element_list ()) 2853 std::string prop_name = prop_p->ident ()->name (); 2855 cdef_property prop = cdm.make_property (retval, prop_name); 2858 std::cerr << "property: " << prop_p->ident ()->name () 2862 octave::tree_expression *expr = prop_p->expression (); 2865 octave_value pvalue = tw.evaluate (expr); 2868 std::cerr << "property default: " 2869 << attribute_value_to_string (*pit, pvalue) 2873 prop.put ("DefaultValue", pvalue); 2876 // Install property attributes. This is done before assigning 2877 // the property accessors so we can do validation by using 2878 // cdef_property methods. 2880 for (auto& attrnm_val : amap) 2881 prop.put (attrnm_val.first, attrnm_val.second); 2883 // Install property access methods, if any. Remove the 2884 // accessor methods from the temporary storage map, so we can 2885 // detect which ones are invalid and do not correspond to a 2886 // defined property. 2888 std::map<std::string, octave_value>::iterator git = 2889 get_methods.find (prop_name); 2891 if (git != get_methods.end ()) 2893 make_function_of_class (retval, git->second); 2894 prop.put ("GetMethod", git->second); 2895 get_methods.erase (git); 2898 std::map<std::string, octave_value>::iterator sit = 2899 set_methods.find (prop_name); 2901 if (sit != set_methods.end ()) 2903 make_function_of_class (retval, sit->second); 2904 prop.put ("SetMethod", sit->second); 2905 set_methods.erase (sit); 2908 retval.install_property (prop); 2918 cdef_class::get_method_function (const std::string& /* nm */) 2920 octave_classdef_meta *p = new octave_classdef_meta (*this); 2926 cdef_property::cdef_property_rep::get_value (const cdef_object& obj, 2927 bool do_check_access, 2928 const std::string& who) 2930 octave_value retval; 2932 if (do_check_access && ! check_get_access ()) 2933 err_property_access (who, wrap (), false); 2935 if (! obj.is_constructed ()) 2937 cdef_class cls (to_cdef (get ("DefiningClass"))); 2939 if (! obj.is_partially_constructed_for (cls)) 2940 error ("cannot reference properties of class `%s' for non-constructed
object", 2941 cls.get_name ().c_str ()); 2944 octave_value get_fcn = get ("GetMethod
"); 2946 // FIXME: should check whether we're already in get accessor method 2948 if (get_fcn.isempty () || is_method_executing (get_fcn, obj)) 2949 retval = obj.get (get ("Name
").string_value ()); 2952 octave_value_list args; 2954 args(0) = to_ov (obj); 2956 args = octave::feval (get_fcn, args, 1); 2965 cdef_property::cdef_property_rep::get_value (bool do_check_access, 2966 const std::string& who) 2968 if (do_check_access && ! check_get_access ()) 2969 err_property_access (who, wrap (), false); 2971 return get ("DefaultValue
"); 2975 cdef_property::cdef_property_rep::is_recursive_set (const cdef_object& /* obj */) const 2982 cdef_property::cdef_property_rep::set_value (cdef_object& obj, 2983 const octave_value& val, 2984 bool do_check_access, 2985 const std::string& who) 2987 if (do_check_access && ! check_set_access ()) 2988 err_property_access (who, wrap (), true); 2990 if (! obj.is_constructed ()) 2992 cdef_class cls (to_cdef (get ("DefiningClass
"))); 2994 if (! obj.is_partially_constructed_for (cls)) 2995 error ("cannot reference
properties of class `%
s' for non-constructed object", 2996 cls.get_name ().c_str ()); 2999 octave_value set_fcn = get ("SetMethod"); 3001 if (set_fcn.isempty () || is_method_executing (set_fcn, obj)) 3002 obj.put (get ("Name").string_value (), val); 3005 octave_value_list args; 3007 args(0) = to_ov (obj); 3010 args = octave::feval (set_fcn, args, 1); 3012 if (args.length () > 0 && args(0).is_defined ()) 3014 if (args (0).is_classdef_object ()) 3016 cdef_object new_obj = to_cdef (args(0)); 3021 ::warning ("set-method of property `%s' returned
a non-classdef
object", 3022 get_name ().c_str ()); 3028 cdef_property::cdef_property_rep::check_get_access (void) const 3030 cdef_class cls (to_cdef (get ("DefiningClass
"))); 3032 return ::check_access (cls, get ("GetAccess
"), "", 3033 get_name (), false); 3039 cdef_property::cdef_property_rep::check_set_access (void) const 3041 cdef_class cls (to_cdef (get ("DefiningClass
"))); 3043 return ::check_access (cls, get ("SetAccess
"), "", 3050 cdef_method::cdef_method_rep::check_method (void) 3054 if (is_dummy_method (function)) 3056 octave::load_path& lp 3059 std::string name = get_name (); 3060 std::string cls_name = dispatch_type; 3061 std::string pack_name; 3063 size_t pos = cls_name.rfind ('.'); 3065 if (pos != std::string::npos) 3067 pack_name = cls_name.substr (0, pos); 3068 cls_name = cls_name.substr (pos + 1); 3071 std::string dir_name; 3072 std::string file_name = lp.find_method (cls_name, name, 3073 dir_name, pack_name); 3075 if (! file_name.empty ()) 3078 = octave::load_fcn_from_file (file_name, dir_name, 3079 dispatch_type, pack_name); 3081 if (ov_fcn.is_defined ()) 3085 make_function_of_class (dispatch_type, function); 3091 // FIXME: check out-of-date status 3094 if (is_dummy_method (function)) 3095 error ("no definition
found for method `%
s' of class `%s'", 3096 get_name ().c_str (), dispatch_type.c_str ()); 3101 cdef_method::cdef_method_rep::execute (const octave_value_list& args, 3102 int nargout, bool do_check_access, 3103 const std::string& who) 3105 octave_value_list retval; 3107 if (do_check_access && ! check_access ()) 3108 err_method_access (who, wrap ()); 3110 if (get ("Abstract
").bool_value ()) 3111 error ("%
s: cannot execute
abstract method", 3112 get ("Name
").string_value ().c_str ()); 3116 if (function.is_defined ()) 3117 retval = octave::feval (function, args, nargout); 3123 cdef_method::cdef_method_rep::execute (const cdef_object& obj, 3124 const octave_value_list& args, 3125 int nargout, bool do_check_access, 3126 const std::string& who) 3128 octave_value_list retval; 3130 if (do_check_access && ! check_access ()) 3131 err_method_access (who, wrap ()); 3133 if (get ("Abstract
").bool_value ()) 3134 error ("%
s: cannot execute
abstract method", 3135 get ("Name
").string_value ().c_str ()); 3139 if (function.is_defined ()) 3141 octave_value_list new_args; 3143 new_args.resize (args.length () + 1); 3145 new_args(0) = to_ov (obj); 3146 for (int i = 0; i < args.length (); i++) 3147 new_args(i+1) = args(i); 3149 retval = octave::feval (function, new_args, nargout); 3156 cdef_method::cdef_method_rep::is_constructor (void) const 3158 if (function.is_function()) 3159 return function.function_value ()->is_classdef_constructor (); 3165 cdef_method::cdef_method_rep::check_access (void) const 3167 cdef_class cls (to_cdef (get ("DefiningClass
"))); 3169 return ::check_access (cls, get ("Access
"), get_name ()); 3173 cdef_method::cdef_method_rep::meta_subsref 3174 (const std::string& type, const std::list<octave_value_list>& idx, 3177 octave_value_list retval; 3182 retval = (execute (idx.front (), type.length () > 1 ? 1 : nargout, true)); 3186 error ("invalid meta.method indexing
"); 3190 if (type.length () > 1 && idx.size () > 1 && ! retval.empty ()) 3191 retval = retval(0).next_subsref (nargout, type, idx, 1); 3197 lookup_package (const std::string& name, bool error_if_not_found = true, 3198 bool load_if_not_found = true) 3200 cdef_manager& cdm = octave::__get_cdef_manager__ ("lookup_package"); 3202 return cdm.find_package (name, error_if_not_found, load_if_not_found); 3205 static octave_value_list 3206 package_fromName (const octave_value_list& args, int /* nargout */) 3208 octave_value_list retval; 3210 if (args.length () != 1) 3211 error ("fromName: invalid
number of parameters
"); 3213 std::string name = args(0).xstring_value ("fromName: PACKAGE_NAME must be
a string"); 3215 retval(0) = to_ov (lookup_package (name, false)); 3220 static octave_value_list 3221 package_get_classes (const octave_value_list& args, int /* nargout */) 3223 octave_value_list retval (1, Matrix ()); 3225 if (args.length () == 1 && args(0).type_name () == "object" 3226 && args(0).class_name () == "meta.package
") 3228 cdef_package pack (to_cdef (args(0))); 3230 retval(0) = pack.get_classes (); 3236 static octave_value_list 3237 package_get_functions (const octave_value_list& args, int /* nargout */) 3239 octave_value_list retval (1, Matrix ()); 3241 if (args.length () == 0 && args(0).type_name () == "object" 3242 && args(0).class_name () == "meta.package
") 3244 cdef_package pack (to_cdef (args(0))); 3246 retval(0) = pack.get_functions (); 3252 static octave_value_list 3253 package_get_packages (const octave_value_list& args, int /* nargout */) 3255 octave_value_list retval (1, Matrix ()); 3257 if (args.length () == 0 && args(0).type_name () == "object" 3258 && args(0).class_name () == "meta.package
") 3260 cdef_package pack (to_cdef (args(0))); 3262 retval(0) = pack.get_packages (); 3268 static octave_value_list 3269 package_getAllPackages (octave::interpreter& interp, 3270 const octave_value_list& /* args */, int /* nargout */) 3272 std::map<std::string, cdef_package> toplevel_packages; 3274 octave::load_path& lp = interp.get_load_path (); 3276 std::list<std::string> names = lp.get_all_package_names (); 3280 toplevel_packages["meta
"] = cdm.find_package ("meta
", false, false); 3282 for (const auto& nm : names) 3283 toplevel_packages[nm] = cdm.find_package (nm, false, true); 3285 Cell c (toplevel_packages.size (), 1); 3289 for (const auto& nm_pkg : toplevel_packages) 3290 c(i++,0) = to_ov (nm_pkg.second); 3292 return octave_value_list (octave_value (c)); 3296 cdef_package::cdef_package_rep::install_class (const cdef_class& cls, 3297 const std::string& nm) 3299 class_map[nm] = cls; 3305 cdef_package::cdef_package_rep::install_function (const octave_value& fcn, 3306 const std::string& nm) 3308 function_map[nm] = fcn; 3312 cdef_package::cdef_package_rep::install_package (const cdef_package& pack, 3313 const std::string& nm) 3315 package_map[nm] = pack; 3320 template <typename T1, typename T2> 3322 map2Cell (const std::map<T1, T2>& m) 3324 Cell retval (1, m.size ()); 3327 for (typename std::map<T1, T2>::const_iterator it = m.begin (); 3328 it != m.end (); ++it, ++i) 3330 retval(i) = to_ov (it->second); 3337 cdef_package::cdef_package_rep::get_classes (void) const 3338 { return map2Cell (class_map); } 3341 cdef_package::cdef_package_rep::get_functions (void) const 3342 { return map2Cell (function_map); } 3345 cdef_package::cdef_package_rep::get_packages (void) const 3346 { return map2Cell (package_map); } 3349 cdef_package::cdef_package_rep::find (const std::string& nm) 3351 std::string symbol_name = get_name () + '.' + nm; 3353 octave::symbol_table& symtab 3356 return symtab.find (symbol_name, octave_value_list (), true, false); 3360 cdef_package::cdef_package_rep::meta_subsref 3361 (const std::string& type, const std::list<octave_value_list>& idx, 3364 octave_value_list retval; 3370 if (idx.front ().length () != 1) 3371 error ("invalid meta.package indexing
"); 3373 std::string nm = idx.front ()(0).xstring_value ("invalid meta.package indexing, expected
a symbol
name"); 3376 std::cerr << "meta.package query:
" << nm << std::endl; 3379 octave_value o = find (nm); 3381 if (! o.is_defined ()) 3382 error ("member `%
s' in package `%s' does not exist
", 3383 nm.c_str (), get_name ().c_str ()); 3385 if (o.is_function ()) 3387 octave_function *fcn = o.function_value (); 3389 // NOTE: the case where the package query is the last 3390 // part of this subsref index is handled in the parse 3391 // tree, because there is some logic to handle magic 3392 // "end
" that makes it impossible to execute the 3393 // function call at this stage. 3395 if (type.size () > 1 3396 && ! fcn->accepts_postfix_index (type[1])) 3398 octave_value_list tmp_args; 3400 retval = octave::feval (o, tmp_args, nargout); 3405 if (type.size () > 1 && idx.size () > 1) 3406 retval = retval(0).next_subsref (nargout, type, 3409 else if (type.size () > 1 && idx.size () > 1) 3410 retval = o.next_subsref (nargout, type, idx, 1); 3417 error ("invalid meta.package indexing
"); 3425 cdef_package::cdef_package_rep::meta_release (void) 3427 // FIXME: Do we really want to unregister the package, as it 3428 // could still be referenced by classes or sub-packages? 3429 // If the package object is recreated later on, it won't 3430 // match the one already referenced by those classes or 3436 // Don't delete the "meta
" package. 3437 if (this != cdm.meta ().get_rep ()) 3438 cdm.unregister_package (wrap ()); 3441 //---------------------------------------------------------------------------- 3443 cdef_manager::cdef_manager (octave::interpreter& interp) 3444 : m_interpreter (interp), m_all_classes (), m_all_packages (), 3445 m_meta_class (), m_meta_property (), m_meta_method (), 3446 m_meta_package (), m_meta () 3448 octave::type_info& ti = m_interpreter.get_type_info (); 3450 octave_classdef::register_type (ti); 3453 cdef_class tmp_handle = make_class ("handle"); 3455 m_meta_class = make_meta_class ("meta.class
", tmp_handle); 3457 tmp_handle.set_class (m_meta_class); 3458 m_meta_class.set_class (m_meta_class); 3461 m_meta_property = make_meta_class ("meta.property
", tmp_handle); 3463 m_meta_method = make_meta_class ("meta.method
", tmp_handle); 3465 m_meta_package = make_meta_class ("meta.package
", tmp_handle); 3467 cdef_class tmp_meta_event 3468 = make_meta_class ("meta.event
", tmp_handle); 3470 cdef_class tmp_meta_dynproperty 3471 = make_meta_class ("meta.dynamicproperty
", tmp_handle); 3473 // meta.class properties 3474 m_meta_class.install_property 3475 (make_attribute (m_meta_class, "Abstract
")); 3477 m_meta_class.install_property 3478 (make_attribute (m_meta_class, "ConstructOnLoad
")); 3480 m_meta_class.install_property 3481 (make_property (m_meta_class, "ContainingPackage
")); 3483 m_meta_class.install_property 3484 (make_property (m_meta_class, "Description
")); 3486 m_meta_class.install_property 3487 (make_property (m_meta_class, "DetailedDescription
")); 3489 m_meta_class.install_property 3490 (make_property (m_meta_class, "Events
")); 3492 m_meta_class.install_property 3493 (make_attribute (m_meta_class, "HandleCompatible
")); 3495 m_meta_class.install_property 3496 (make_attribute (m_meta_class, "Hidden
")); 3498 m_meta_class.install_property 3499 (make_property (m_meta_class, "InferiorClasses
", 3500 make_fcn_handle (class_get_inferiorclasses, 3501 "meta.class>
get.InferiorClasses
"), 3502 "public", Matrix (), "private")); 3504 m_meta_class.install_property 3505 (make_property (m_meta_class, "Methods
", 3506 make_fcn_handle (class_get_methods, 3507 "meta.class>
get.Methods
"), 3508 "public", Matrix (), "private")); 3510 m_meta_class.install_property 3511 (make_property (m_meta_class, "MethodList
", 3512 make_fcn_handle (class_get_methods, 3513 "meta.class>
get.MethodList
"), 3514 "public", Matrix (), "private")); 3516 m_meta_class.install_property (make_attribute (m_meta_class, "Name
")); 3518 m_meta_class.install_property 3519 (make_property (m_meta_class, "Properties
", 3520 make_fcn_handle (class_get_properties, 3521 "meta.class>
get.Properties
"), 3522 "public", Matrix (), "private")); 3524 m_meta_class.install_property 3525 (make_property (m_meta_class, "PropertyList
", 3526 make_fcn_handle (class_get_properties, 3527 "meta.class>
get.PropertyList
"), 3528 "public", Matrix (), "private")); 3530 m_meta_class.install_property (make_attribute (m_meta_class, "Sealed
")); 3532 m_meta_class.install_property 3533 (make_property (m_meta_class, "SuperClasses
", 3534 make_fcn_handle (class_get_superclasses, 3535 "meta.class>
get.SuperClasses
"), 3536 "public", Matrix (), "private")); 3538 m_meta_class.install_property 3539 (make_property (m_meta_class, "SuperClassList
", 3540 make_fcn_handle (class_get_superclasses, 3541 "meta.class>
get.SuperClassList
"), 3542 "public", Matrix (), "private")); 3544 // meta.class methods 3545 m_meta_class.install_method 3546 (make_method (m_meta_class, "fromName
", class_fromName, "public", true)); 3548 m_meta_class.install_method 3549 (make_method (m_meta_class, "fevalStatic
", class_fevalStatic, "public", 3552 m_meta_class.install_method 3553 (make_method (m_meta_class, "getConstant
", class_getConstant, "public", 3556 m_meta_class.install_method (make_method (m_meta_class, "eq
", class_eq)); 3557 m_meta_class.install_method (make_method (m_meta_class, "ne
", class_ne)); 3558 m_meta_class.install_method (make_method (m_meta_class, "lt
", class_lt)); 3559 m_meta_class.install_method (make_method (m_meta_class, "le
", class_le)); 3560 m_meta_class.install_method (make_method (m_meta_class, "gt
", class_gt)); 3561 m_meta_class.install_method (make_method (m_meta_class, "ge
", class_ge)); 3563 // meta.method properties 3564 m_meta_method.install_property 3565 (make_attribute (m_meta_method, "Abstract
")); 3567 m_meta_method.install_property 3568 (make_attribute (m_meta_method, "Access
")); 3570 m_meta_method.install_property 3571 (make_attribute (m_meta_method, "DefiningClass
")); 3573 m_meta_method.install_property 3574 (make_attribute (m_meta_method, "Description
")); 3576 m_meta_method.install_property 3577 (make_attribute (m_meta_method, "DetailedDescription
")); 3579 m_meta_method.install_property 3580 (make_attribute (m_meta_method, "Hidden
")); 3582 m_meta_method.install_property 3583 (make_attribute (m_meta_method, "Name
")); 3585 m_meta_method.install_property 3586 (make_attribute (m_meta_method, "Sealed
")); 3588 m_meta_method.install_property 3589 (make_attribute (m_meta_method, "Static
")); 3591 // meta.property properties 3592 m_meta_property.install_property 3593 (make_attribute (m_meta_property, "Name
")); 3595 m_meta_property.install_property 3596 (make_attribute (m_meta_property, "Description
")); 3598 m_meta_property.install_property 3599 (make_attribute (m_meta_property, "DetailedDescription
")); 3601 m_meta_property.install_property 3602 (make_attribute (m_meta_property, "Abstract
")); 3604 m_meta_property.install_property 3605 (make_attribute (m_meta_property, "Constant
")); 3607 m_meta_property.install_property 3608 (make_attribute (m_meta_property, "GetAccess
")); 3610 m_meta_property.install_property 3611 (make_attribute (m_meta_property, "SetAccess
")); 3613 m_meta_property.install_property 3614 (make_attribute (m_meta_property, "Dependent
")); 3616 m_meta_property.install_property 3617 (make_attribute (m_meta_property, "Transient
")); 3619 m_meta_property.install_property 3620 (make_attribute (m_meta_property, "Hidden
")); 3622 m_meta_property.install_property 3623 (make_attribute (m_meta_property, "GetObservable
")); 3625 m_meta_property.install_property 3626 (make_attribute (m_meta_property, "SetObservable
")); 3628 m_meta_property.install_property 3629 (make_attribute (m_meta_property, "GetMethod
")); 3631 m_meta_property.install_property 3632 (make_attribute (m_meta_property, "SetMethod
")); 3634 m_meta_property.install_property 3635 (make_attribute (m_meta_property, "DefiningClass
")); 3637 m_meta_property.install_property 3638 (make_property (m_meta_property, "DefaultValue
", 3639 make_fcn_handle (property_get_defaultvalue, 3640 "meta.property>
get.DefaultValue
"), 3641 "public", Matrix (), "private")); 3643 m_meta_property.install_property 3644 (make_attribute (m_meta_property, "HasDefault
")); 3646 // meta.property events 3647 // FIXME: add events 3651 tmp_handle.install_method 3652 (make_method (tmp_handle, "delete", handle_delete)); 3654 // meta.package properties 3656 m_meta_package.install_property 3657 (make_attribute (m_meta_package, "Name
")); 3659 m_meta_package.install_property 3660 (make_property (m_meta_package, "ContainingPackage
")); 3662 m_meta_package.install_property 3663 (make_property (m_meta_package, "ClassList
", 3664 make_fcn_handle (package_get_classes, 3665 "meta.package>
get.ClassList
"), 3666 "public", Matrix (), "private")); 3668 m_meta_package.install_property 3669 (make_property (m_meta_package, "Classes
", 3670 make_fcn_handle (package_get_classes, 3671 "meta.package>
get.Classes
"), 3672 "public", Matrix (), "private")); 3674 m_meta_package.install_property 3675 (make_property (m_meta_package, "FunctionList
", 3676 make_fcn_handle (package_get_functions, 3677 "meta.package>
get.FunctionList
"), 3678 "public", Matrix (), "private")); 3680 m_meta_package.install_property 3681 (make_property (m_meta_package, "Functions
", 3682 make_fcn_handle (package_get_functions, 3683 "meta.package>
get.Functions
"), 3684 "public", Matrix (), "private")); 3686 m_meta_package.install_property 3687 (make_property (m_meta_package, "PackageList
", 3688 make_fcn_handle (package_get_packages, 3689 "meta.package>
get.PackageList
"), 3690 "public", Matrix (), "private")); 3692 m_meta_package.install_property 3693 (make_property (m_meta_package, "Packages
", 3694 make_fcn_handle (package_get_packages, 3695 "meta.package>
get.Packages
"), 3696 "public", Matrix (), "private")); 3698 m_meta_package.install_method 3699 (make_method (m_meta_package, "fromName
", package_fromName, 3702 m_meta_package.install_method 3703 (make_method (m_meta_package, "getAllPackages
", package_getAllPackages, 3706 // create "meta
" package 3707 cdef_package package_meta 3709 = make_package ("meta
"); 3711 package_meta.install_class (m_meta_class, "class"); 3712 package_meta.install_class (m_meta_property, "property"); 3713 package_meta.install_class (m_meta_method, "method"); 3714 package_meta.install_class (m_meta_package, "package
"); 3715 package_meta.install_class (tmp_meta_event, "event
"); 3716 package_meta.install_class (tmp_meta_dynproperty, "dynproperty
"); 3718 octave::symbol_table& symtab = m_interpreter.get_symbol_table (); 3720 // install built-in classes into the symbol table 3721 symtab.install_built_in_function 3723 octave_value (m_meta_class.get_constructor_function ())); 3725 symtab.install_built_in_function 3727 octave_value (m_meta_method.get_constructor_function ())); 3729 symtab.install_built_in_function 3731 octave_value (m_meta_property.get_constructor_function ())); 3733 symtab.install_built_in_function 3735 octave_value (m_meta_package.get_constructor_function ())); 3737 // FIXME: meta.event and meta.dynproperty are not implemented 3738 // and should not be installed into symbol table. 3740 // symtab.install_built_in_function 3742 // octave_value (tmp_meta_event.get_constructor_function ())); 3744 // symtab.install_built_in_function 3745 // ("meta.dynproperty
", 3746 // octave_value (tmp_meta_dynproperty.get_constructor_function ())); 3750 cdef_manager::find_class (const std::string& name, bool error_if_not_found, 3751 bool load_if_not_found) 3753 std::map<std::string, cdef_class>::iterator it = m_all_classes.find (name); 3755 if (it == m_all_classes.end ()) 3757 if (load_if_not_found) 3759 octave_value ov_cls; 3761 size_t pos = name.rfind ('.'); 3763 if (pos == std::string::npos) 3765 octave::symbol_table& symtab 3768 ov_cls = symtab.find (name); 3772 std::string pack_name = name.substr (0, pos); 3774 cdef_package pack = find_package (pack_name, false, true); 3777 ov_cls = pack.find (name.substr (pos+1)); 3780 if (ov_cls.is_defined ()) 3781 it = m_all_classes.find (name); 3785 if (it == m_all_classes.end ()) 3787 if (error_if_not_found) 3788 error ("class not
found: %
s", name.c_str ()); 3792 cdef_class cls = it->second; 3794 if (! cls.is_builtin ()) 3795 cls = lookup_class (cls); 3800 m_all_classes.erase (it); 3803 return cdef_class (); 3807 cdef_manager::find_method_symbol (const std::string& method_name, 3808 const std::string& class_name) 3810 octave_function *retval = nullptr; 3812 cdef_class cls = find_class (class_name, false, false); 3816 cdef_method meth = cls.find_method (method_name); 3819 retval = new octave_classdef_meta (meth); 3826 cdef_manager::find_package (const std::string& name, bool error_if_not_found, 3827 bool load_if_not_found) 3829 cdef_package retval; 3831 std::map<std::string, cdef_package>::const_iterator it 3832 = m_all_packages.find (name); 3834 if (it != m_all_packages.end ()) 3836 retval = it->second; 3839 error ("invalid package `%
s'", name.c_str ()); 3843 octave::load_path& lp 3844 = octave::__get_load_path__ ("cdef_manager::find_package"); 3846 if (load_if_not_found && lp.find_package (name)) 3848 size_t pos = name.find ('.
'); 3850 if (pos == std::string::npos) 3851 retval = make_package (name, ""); 3854 std::string parent_name = name.substr (0, pos); 3856 retval = make_package (name, parent_name); 3859 else if (error_if_not_found) 3860 error ("unknown package `%s'", name.c_str ()); 3867 cdef_manager::find_package_symbol (const std::string& pack_name) 3869 octave_function *retval = nullptr; 3871 cdef_package pack = find_package (pack_name, false); 3874 retval = new octave_classdef_meta (pack); 3879 //---------------------------------------------------------------------------- 3881 DEFUN (__meta_get_package__, args, , 3882 doc: /* -*- texinfo -*- 3883 @deftypefn {} {} __meta_get_package__ () 3884 Undocumented internal function. 3887 if (args.length () != 1) 3890 std::string cname = args(0).xstring_value ("PACKAGE_NAME must be
a string"); 3892 return to_ov (lookup_package (cname)); 3895 DEFUN (__superclass_reference__, args, , 3896 doc: /* -*- texinfo -*- 3897 @deftypefn {} {} __superclass_reference__ () 3898 Undocumented internal function. 3901 return ovl (new octave_classdef_superclass_ref (args)); 3904 DEFUN (__meta_class_query__, args, , 3905 doc: /* -*- texinfo -*- 3906 @deftypefn {} {} __meta_class_query__ () 3907 Undocumented internal function. 3911 std::cerr << "__meta_class_query__ (
" 3912 << args(0).string_value () << ')' 3916 if (args.length () != 1) 3919 std::string cls = args(0).xstring_value ("CLASS_NAME must be
a string"); 3921 return to_ov (lookup_class (cls)); 3924 DEFUN (metaclass, args, , 3925 doc: /* -*- texinfo -*- 3926 @deftypefn {} {} metaclass (obj) 3927 Returns the meta.class object corresponding to the class of @var{obj}. 3930 if (args.length () != 1) 3933 cdef_object obj = to_cdef (args(0)); 3935 return to_ov (obj.get_class ()); 3939 ;;; Local Variables: ***
bool called_from_builtin(void)
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
virtual bool is_user_function(void) const
is already an absolute the name is checked against the file system instead of Octave s loadpath In this if otherwise an empty string is returned If the first argument is a cell array of search each directory of the loadpath for element of the cell array and return the first that matches If the second optional argument return a cell array containing the list of all files that have the same name in the path If no files are found
cdef_property make_attribute(const cdef_class &cls, const std::string &name)
const cdef_class & meta_method(void) const
Cell get_properties(int mode=property_normal)
bool is_direct_superclass(const cdef_class &clsa, const cdef_class &clsb)
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
static bool check_access(const cdef_class &cls, const octave_value &acc, const std::string &meth_name="", const std::string &prop_name="", bool is_prop_set=false)
std::string string_value(bool force=false) const
cdef_class make_meta_class(const std::string &name, const cdef_class &super)
for fields that display a single number
virtual void assign(const std::string &, const octave_value &)
std::string get_name(void) const
static bool in_class_method(const cdef_class &cls)
octave_value_list(* fcn)(const octave_value_list &, int)
void error(const char *fmt,...)
octave_value_list splice(octave_idx_type offset, octave_idx_type len, const octave_value_list &lst=octave_value_list()) const
octave::tree_statement_list * body(void)
static octave_value_list class_get_inferiorclasses(const octave_value_list &args, int)
#define META_CLASS_CMP(OP, CLSA, CLSB, FUN)
static std::list< cdef_class > lookup_classes(const Cell &cls_list)
static octave_value_list class_getConstant(const octave_value_list &args, int)
static octave_value_list class_get_properties(const octave_value_list &args, int)
void register_class(const cdef_class &cls)
bool is_defined(void) const
static void make_function_of_class(const std::string &class_name, const octave_value &fcn)
const cdef_class & meta_package(void) const
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
cdef_manager & __get_cdef_manager__(const std::string &who)
static std::string get_base_name(const std::string &nm)
void register_package(const cdef_package &pkg)
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
static octave_value_list package_getAllPackages(octave::interpreter &interp, const octave_value_list &, int)
OCTAVE_EXPORT octave_value_list or class The return code an ordinary file in Octave s or(after appending @samp{.m}) a function file in Octave 's ode
virtual bool is_classdef_constructor(const std::string &="") const
static octave_value_list class_get_methods(const octave_value_list &args, int)
static octave_value_list handle_delete(const octave_value_list &, int)
cdef_class make_class(const std::string &name, const std::list< cdef_class > &super_list=std::list< cdef_class >())
static cdef_package lookup_package(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
bool is_defined(void) const
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
octave::tree_parameter_list * parameter_list(void)
virtual octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
then the function must return scalars which will be concatenated into the return array(s). If code
nd deftypefn *std::string name
static octave_value_list class_fromName(const octave_value_list &args, int)
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
octave_value_list property_get_defaultvalue(const octave_value_list &args, int)
virtual octave_user_function * user_function_value(bool silent=false)
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
static octave_value to_ov(const std::list< cdef_class > &class_list)
cdef_method find_method(const std::string &nm, bool local=false)
std::string dispatch_class(void) const
octave_idx_type numel(const octave_value_list &idx)
static bool is_dummy_method(const octave_value &fcn)
octave_value get(const std::string &pname) const
void error_with_id(const char *id, const char *fmt,...)
void mark_as_external(const std::string &dtype)
nd example The result of the integration is returned in the value of it is recommended to verify this value for difficult integrands and then a warning is issued and as such
void put(const std::string &pname, const octave_value &val)
bool is_strict_superclass(const cdef_class &clsa, const cdef_class &clsb)
octave_value_list execute(const octave_value_list &args, int nargout, bool do_check_access=true, const std::string &who="")
virtual bool is_class_method(const std::string &="") const
void mark_as_class_method(void)
#define panic_impossible()
octave_value find(const std::string &nm)
octave_value_list(* meth)(octave::interpreter &, const octave_value_list &, int)
virtual octave_idx_type numel(void) const
octave_function * function_value(bool silent=false) const
static void register_type(void)
void mark_as_meta_class(void)
virtual bool is_anonymous_function_of_class(const std::string &="") const
static bool is_superclass(const cdef_class &clsa, const cdef_class &clsb, bool allow_equal=true, int max_depth=-1)
cdef_property find_property(const std::string &nm)
cdef_class find_class(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
cdef_package find_package(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
void indent(std::ostream &os) const
friend class octave_value
octave::tree_parameter_list * return_list(void)
octave_function * current(void) const
bool is_static(void) const
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
void mark_as_classdef_constructor(void)
octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
defaults to zero A value of zero computes the digamma a value the trigamma and so on The digamma function is defined
octave_value make_idx_args(const std::string &type, const std::list< octave_value_list > &idx, const std::string &who)
int register_type(const std::string &, const std::string &, const octave_value &, bool abort_on_duplicate=false)
static octave_value_list class_fevalStatic(const octave_value_list &args, int nargout)
bool is_constant(void) const
cdef_object to_cdef(const octave_value &val)
static OCTAVE_NORETURN void err_method_access(const std::string &from, const cdef_method &meth)
std::string get_name(void) const
void mark_as_handle_class(void)
static const std::string t_name
void set_class(const cdef_class &cls)
cdef_method make_method(const cdef_class &cls, const std::string &name, const octave_value &fcn, const std::string &m_access="public", bool is_static=false)
call_stack & __get_call_stack__(const std::string &who)
static octave_value make_fcn_handle(octave_builtin::fcn ff, const std::string &nm)
bool is_constructed_object(const std::string nm)
bool is(const cdef_object &obj) const
octave_idx_type length(void) const
defaults to zero A value of zero computes the digamma a value of
static octave_value_list class_get_superclasses(const octave_value_list &args, int)
std::string get_name(void) const
const cdef_class & meta_property(void) const
cdef_package make_package(const std::string &nm, const std::string &parent="")
octave::refcount< octave_idx_type > count
octave_value evaluate(tree_expression *expr, int nargout=1)
static bool is_method_executing(const octave_value &ov, const cdef_object &obj)
const cdef_class & meta_class(void) const
bool is_string(void) const
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
static OCTAVE_NORETURN void err_property_access(const std::string &from, const cdef_property &prop, bool is_set=false)
static cdef_class lookup_class(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
bool is_classdef_constructor(const std::string &cname="") const
octave_value get_value(const cdef_object &obj, bool do_check_access=true, const std::string &who="")
virtual octave_function * function_value(bool silent=false)
octave_value_list call(octave::tree_evaluator &, int nargout, const octave_value_list &idx)
octave_idx_type numel(void) const
Number of elements in the array.
octave_idx_type length(void) const
cdef_property make_property(const cdef_class &cls, const std::string &name, const octave_value &get_method=Matrix(), const std::string &get_access="public", const octave_value &set_method=Matrix(), const std::string &set_access="public")
write the output to stdout if nargout is
bool is_private_function(void) const
std::string name(void) const
std::string type_name(void) const
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
tree_evaluator & __get_evaluator__(const std::string &who)
static cdef_class get_class_context(std::string &name, bool &in_constructor)
void print(std::ostream &os, bool pr_as_read_syntax=false)
octave_value next_subsref(const std::string &type, const std::list< octave_value_list > &idx, size_t skip=1)
Cell cell_value(void) const
cdef_class get_class(void) const
void mark_as_class_constructor(void)
void set_function(const octave_value &fcn)
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
T::properties & properties(graphics_object obj)