85 error (
"parents must be objects");
91 error (
"duplicate class in parent tree");
142 Cell c (parent_dims);
146 std::list<std::string> plist
155 error (
"class: parent class dimension mismatch");
157 else if (nel == 1 && p_nel == 1)
175 else if (nel == p_nel)
191 std::list<std::string> plist
200 error (
"class: parent class dimension mismatch");
250 error (
"invalid index for class");
256 error (
"invalid index for class assignment");
262 error (
"%s cannot be indexed with %c", nm.c_str (), t);
268 error (
"assignment to class element failed");
278 if (retval(i).is_magic_colon ())
287 const std::list<octave_value_list>& idx,
288 const std::string& who)
292 size_t len = type.
length ();
294 if (len == idx.size ())
296 Cell type_field (1, len);
297 Cell subs_field (1, len);
299 std::list<octave_value_list>::const_iterator p = idx.begin ();
301 for (
size_t i = 0; i < len; i++)
308 type_field(i) =
"()";
313 type_field(i) =
"{}";
331 error (
"expecting character string argument for '.' index");
337 error (
"expecting single argument for '.' index");
351 m.
assign (
"type", type_field);
352 m.
assign (
"subs", subs_field);
357 error (
"invalid index for %s", who.c_str ());
367 assert (idx.
length () == 1);
378 error (
"malformed class");
384 std::string nm = idx(0).string_value ();
390 if (p != my_map.
end ())
393 error (
"class has no member '%s'", nm.c_str ());
412 return (fcn && fcn->
name () ==
"builtin");
421 Matrix retval (1, 2, 1.0);
431 && lv(0).is_matrix_type () && lv(0).dims ().is_vector ())
432 retval = lv(0).matrix_value ();
444 for (
int i = 0; i < nd; i++)
473 if (lv.
length () == 1 && lv(0).is_scalar_type ())
474 retval = lv(0).idx_type_value (
true);
476 error (
"@%s/numel: invalid return value", cn.c_str ());
486 const std::list<octave_value_list>& idx,
503 if (type.length () > 1 && type[1] ==
'.')
505 std::list<octave_value_list>::const_iterator p = idx.begin ();
514 retval(0) = (t.
length () == 1) ? t(0)
553 retval = retval(0).next_subsref (nargout, type, idx, skip);
576 bool maybe_cs_list_query = (type[0] ==
'.' || type[0] ==
'{'
577 || (type.length () > 1 && type[0] ==
'('
580 int true_nargout = nargout;
582 if (maybe_cs_list_query)
586 if (type[0] !=
'.') tmp = idx.front ();
587 true_nargout =
numel (tmp);
600 if (type.length () == 1 && type[0] ==
'(')
620 if (type.length () > 0 && type[0] ==
'.' && ! retval.
is_map ())
631 const std::list<octave_value_list>& idx,
640 const std::list<octave_value_list>& idx,
652 const std::string&
type,
653 const std::list<octave_value_list>& idx,
714 error (
"expecting single return value from @%s/subsasgn",
745 error (
"malformed class");
758 if (n > 1 && ! (type.length () == 2 && type[0] ==
'(' && type[1] ==
'.'))
764 if (type.length () > 1 && type[1] ==
'.')
766 std::list<octave_value_list>::const_iterator p = idx.begin ();
771 assert (key_idx.
length () == 1);
773 std::string key = key_idx(0).string_value ();
785 Cell map_elt = map_val.
index (idx.front (),
true);
792 std::list<octave_value_list> next_idx (idx);
797 next_idx.erase (next_idx.begin ());
798 next_idx.erase (next_idx.begin ());
802 t_rhs = u.
subsasgn (type.substr (2), next_idx, rhs);
817 assert (key_idx.
length () == 1);
819 std::string key = key_idx(0).string_value ();
821 std::list<octave_value_list> next_idx (idx);
823 next_idx.erase (next_idx.begin ());
825 std::string next_type = type.substr (1);
838 if (tmpc.
numel () == 1)
852 t_rhs = tmp.
subsasgn (next_type, next_idx, rhs);
875 if (n > 1 && type[1] ==
'.')
877 std::list<octave_value_list>::const_iterator p = idx.begin ();
880 assert (key_idx.
length () == 1);
882 std::string key = key_idx(0).string_value ();
918 error (
"invalid class assignment");
935 error (
"invalid class assignment");
945 assert (key_idx.
length () == 1);
947 std::string key = key_idx(0).string_value ();
1009 if (tmp(0).is_object ())
1010 error (
"subsindex function must return a valid index vector");
1021 error (
"no subsindex method defined for class %s",
1036 std::string key =
map.
key (p);
1063 for (std::list<std::string>::iterator pit =
parent_list.begin ();
1094 for (std::list<std::string>::iterator pit =
parent_list.begin ();
1139 if (tmp(0).is_string ())
1140 retval = tmp(0).all_strings (pad);
1142 error (
"cname/char method did not return a character string");
1146 error (
"no char method defined for class %s",
class_name ().c_str ());
1171 bool retval =
false;
1197 arg_names[0] = name;
1206 os << name <<
" = <class " <<
class_name () <<
">";
1217 bool retval =
false;
1228 bool have_ctor =
false;
1282 bool retval =
true, might_have_inheritance =
false;
1283 std::string dbgstr =
"dork";
1288 std::string key =
map.
key (p);
1295 might_have_inheritance =
true;
1302 if (might_have_inheritance)
1313 for (std::list<std::string>::iterator pit =
parent_list.begin ();
1334 os <<
"# classname: " <<
class_name () <<
"\n";
1341 m = tmp(0).map_value ();
1348 os <<
"# length: " << m.
nfields () <<
"\n";
1351 while (i != m.
end ())
1370 std::string classname;
1371 bool success =
true;
1397 error (
"load: internal error loading class elements");
1412 warning (
"load: unable to reconstruct object inheritance");
1421 map = tmp(0).map_value ();
1428 error (
"load: failed to load class");
1442 error (
"load: failed to extract number of elements in class");
1448 error (
"load: failed to extract name of class");
1458 int32_t classname_len =
class_name ().length ();
1460 os.write (reinterpret_cast<char *> (&classname_len), 4);
1469 m = tmp(0).map_value ();
1477 os.write (reinterpret_cast<char *> (&len), 4);
1480 while (i != m.
end ())
1499 bool success =
true;
1501 int32_t classname_len;
1503 is.read (reinterpret_cast<char *> (&classname_len), 4);
1511 classname[classname_len] =
'\0';
1512 if (! is.read (reinterpret_cast<char *> (classname), classname_len))
1519 if (! is.read (reinterpret_cast<char *> (&len), 4))
1545 error (
"load: internal error loading class elements");
1557 warning (
"load: unable to reconstruct object inheritance");
1565 map = tmp(0).map_value ();
1572 warning (
"load: failed to load class");
1584 #if defined (HAVE_HDF5)
1590 hid_t group_hid = -1;
1591 hid_t type_hid = -1;
1592 hid_t space_hid = -1;
1593 hid_t class_hid = -1;
1594 hid_t data_hid = -1;
1599 group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1601 group_hid = H5Gcreate (loc_id, name, 0);
1607 type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid,
c_name.length () + 1);
1612 space_hid = H5Screate_simple (0 , hdims, 0);
1616 class_hid = H5Dcreate (group_hid,
"classname", type_hid, space_hid,
1617 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1619 class_hid = H5Dcreate (group_hid,
"classname", type_hid, space_hid,
1622 if (class_hid < 0 || H5Dwrite (class_hid, type_hid, H5S_ALL, H5S_ALL,
1623 H5P_DEFAULT,
c_name.c_str ()) < 0)
1627 data_hid = H5Gcreate (group_hid,
"value", H5P_DEFAULT, H5P_DEFAULT,
1630 data_hid = H5Gcreate (group_hid,
"value", 0);
1640 m = tmp(0).map_value ();
1649 while (i != m.
end ())
1665 H5Gclose (data_hid);
1668 H5Dclose (class_hid);
1671 H5Sclose (space_hid);
1674 H5Tclose (type_hid);
1677 H5Gclose (group_hid);
1685 bool retval =
false;
1687 hid_t group_hid = -1;
1688 hid_t data_hid = -1;
1689 hid_t type_hid = -1;
1690 hid_t type_class_hid = -1;
1691 hid_t space_hid = -1;
1692 hid_t subgroup_hid = -1;
1699 int current_item = 0;
1700 hsize_t num_obj = 0;
1705 group_hid = H5Gopen (loc_id, name, H5P_DEFAULT);
1707 group_hid = H5Gopen (loc_id, name);
1713 data_hid = H5Dopen (group_hid,
"classname", H5P_DEFAULT);
1715 data_hid = H5Dopen (group_hid,
"classname");
1721 type_hid = H5Dget_type (data_hid);
1723 type_class_hid = H5Tget_class (type_hid);
1725 if (type_class_hid != H5T_STRING)
1728 space_hid = H5Dget_space (data_hid);
1729 rank = H5Sget_simple_extent_ndims (space_hid);
1734 slen = H5Tget_size (type_hid);
1744 st_id = H5Tcopy (H5T_C_S1);
1745 H5Tset_size (st_id, slen);
1747 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT,
1751 H5Dclose (data_hid);
1752 H5Gclose (group_hid);
1757 H5Dclose (data_hid);
1766 subgroup_hid = H5Gopen (group_hid, name, H5P_DEFAULT);
1768 subgroup_hid = H5Gopen (group_hid, name);
1770 H5Gget_num_objs (subgroup_hid, &num_obj);
1771 H5Gclose (subgroup_hid);
1773 while (current_item < static_cast<int> (num_obj)
1774 && (retval2 = H5Giterate (group_hid, name, ¤t_item,
1783 error (
"load: internal error loading class elements");
1796 warning (
"load: unable to reconstruct object inheritance");
1805 map = tmp(0).map_value ();
1815 H5Dclose (data_hid);
1818 H5Gclose (group_hid);
1847 : field_names (), parent_class_names ()
1857 error (
"invalid call to exemplar_info constructor");
1879 if (obj_fnames[i] != fnames[i])
1882 error (
"mismatch in field names");
1889 std::list<std::string> obj_parents
1891 std::list<std::string> pnames = parents ();
1893 std::list<std::string>::const_iterator p = obj_parents.begin ();
1894 std::list<std::string>::const_iterator q = pnames.begin ();
1896 while (p != obj_parents.end ())
1901 error (
"mismatch in parent classes");
1909 error (
"mismatch in number of parent classes");
1915 error (
"mismatch in number of fields");
1921 error (
"invalid comparison of class exemplar to non-class object");
1929 @deftypefn {Function File} {@var{classname} =} class (@var{obj})\n\
1930 @deftypefnx {Function File} {} class (@var{s}, @var{id})\n\
1931 @deftypefnx {Function File} {} class (@var{s}, @var{id}, @var{p}, @dots{})\n\
1932 Return the class of the object @var{obj} or create a class with\n\
1933 fields from structure @var{s} and name (string) @var{id}. Additional\n\
1934 arguments name a list of parent classes from which the new class is\n\
1936 @seealso{typeinfo, isa}\n\
1941 int nargin = args.
length ();
1945 else if (nargin == 1)
1953 std::string
id = args(1).string_value ();
1968 (m,
id, std::list<std::string> ()));
1980 = octave_class::exemplar_map.find (
id);
1982 if (it == octave_class::exemplar_map.end ())
1983 octave_class::exemplar_map[id]
1985 else if (! it->second.compare (retval))
1986 error (
"class: object of class '%s' does not match previously constructed objects",
1991 error (
"class: expecting structure S as first argument");
1994 error (
"class: '%s' is invalid as a class name in this context",
1998 error (
"class: invalid call from outside class constructor or method");
2001 error (
"class: ID (class name) must be a character string");
2021 @deftypefn {Built-in Function} {} __isa_parent__ (@var{class}, @var{name})\n\
2022 Undocumented internal function.\n\
2027 if (args.length () == 2)
2038 error (
"__isa_parent__: expecting arguments to be character strings");
2048 @deftypefn {Built-in Function} {} __parent_classes__ (@var{x})\n\
2049 Undocumented internal function.\n\
2054 if (args.length () == 1)
2069 @deftypefn {Built-in Function} {} isobject (@var{x})\n\
2070 Return true if @var{x} is a class object.\n\
2071 @seealso{class, typeinfo, isa, ismethod}\n\
2076 if (args.length () == 1)
2086 @deftypefn {Built-in Function} {} ismethod (@var{x}, @var{method})\n\
2087 Return true if @var{x} is a class object and the string @var{method}\n\
2088 is a method of this class.\n\
2089 @seealso{isobject}\n\
2094 if (args.length () == 2)
2105 error (
"ismethod: expecting object or class name as first argument");
2109 std::string method = args(1).string_value ();
2128 @deftypefn {Built-in Function} {} __methods__ (@var{x})\n\
2129 @deftypefnx {Built-in Function} {} __methods__ (\"classname\")\n\
2130 Internal function.\n\
2132 Implements @code{methods} for Octave class objects and classnames.\n\
2133 @seealso{methods}\n\
2160 static std::set<std::string> built_in_class_names;
2162 if (built_in_class_names.empty ())
2164 built_in_class_names.insert (
"double");
2165 built_in_class_names.insert (
"single");
2166 built_in_class_names.insert (
"cell");
2167 built_in_class_names.insert (
"struct");
2168 built_in_class_names.insert (
"logical");
2169 built_in_class_names.insert (
"char");
2170 built_in_class_names.insert (
"function handle");
2171 built_in_class_names.insert (
"int8");
2172 built_in_class_names.insert (
"uint8");
2173 built_in_class_names.insert (
"int16");
2174 built_in_class_names.insert (
"uint16");
2175 built_in_class_names.insert (
"int32");
2176 built_in_class_names.insert (
"uint32");
2177 built_in_class_names.insert (
"int64");
2178 built_in_class_names.insert (
"uint64");
2181 return built_in_class_names.find (cn) != built_in_class_names.end ();
2186 @deftypefn {Built-in Function} {} superiorto (@var{class_name}, @dots{})\n\
2187 When called from a class constructor, mark the object currently\n\
2188 constructed as having a higher precedence than @var{class_name}.\n\
2189 More that one such class can be specified in a single call.\n\
2190 This function may only be called from a class constructor.\n\
2198 error (
"superiorto: invalid call from outside class constructor");
2202 for (
int i = 0; i < args.length (); i++)
2207 error (
"superiorto: expecting argument to be class name");
2216 std::string sup_class = fcn->
name ();
2219 error (
"superiorto: opposite precedence already set for %s and %s",
2220 sup_class.c_str (), inf_class.c_str ());
2230 @deftypefn {Built-in Function} {} inferiorto (@var{class_name}, @dots{})\n\
2231 When called from a class constructor, mark the object currently\n\
2232 constructed as having a lower precedence than @var{class_name}.\n\
2233 More that one such class can be specified in a single call.\n\
2234 This function may only be called from a class constructor.\n\
2242 error (
"inferiorto: invalid call from outside class constructor");
2246 for (
int i = 0; i < args.length (); i++)
2251 error (
"inferiorto: expecting argument to be class name");
2257 error (
"inferiorto: cannot give user-defined class lower "
2258 "precedence than built-in class");
2262 std::string inf_class = fcn->
name ();
2265 error (
"inferiorto: opposite precedence already set for %s and %s",
2266 inf_class.c_str (), sup_class.c_str ());