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");
276 assert (idx.
length () == 1);
287 error (
"malformed class");
293 std::string nm = idx(0).string_value ();
299 if (p != my_map.
end ())
302 error (
"class has no member '%s'", nm.c_str ());
316 Matrix retval (1, 2, 1.0);
326 && lv(0).is_matrix_type () && lv(0).dims ().is_vector ())
327 retval = lv(0).matrix_value ();
339 for (
int i = 0; i < nd; i++)
368 if (lv.
length () == 1 && lv(0).is_scalar_type ())
369 retval = lv(0).idx_type_value (
true);
371 error (
"@%s/numel: invalid return value", cn.c_str ());
381 const std::list<octave_value_list>& idx,
398 if (type.length () > 1 && type[1] ==
'.')
400 std::list<octave_value_list>::const_iterator p = idx.begin ();
409 retval(0) = (t.
length () == 1) ? t(0)
448 retval = retval(0).next_subsref (nargout, type, idx, skip);
471 bool maybe_cs_list_query = (type[0] ==
'.' || type[0] ==
'{'
472 || (type.length () > 1 && type[0] ==
'('
475 int true_nargout = nargout;
477 if (maybe_cs_list_query)
481 if (type[0] !=
'.') tmp = idx.front ();
482 true_nargout =
numel (tmp);
495 if (type.length () == 1 && type[0] ==
'(')
515 if (type.length () > 0 && type[0] ==
'.' && ! retval.
is_map ())
526 const std::list<octave_value_list>& idx,
535 const std::list<octave_value_list>& idx,
547 const std::string&
type,
548 const std::list<octave_value_list>& idx,
609 error (
"expecting single return value from @%s/subsasgn",
640 error (
"malformed class");
653 if (n > 1 && ! (type.length () == 2 && type[0] ==
'(' && type[1] ==
'.'))
659 if (type.length () > 1 && type[1] ==
'.')
661 std::list<octave_value_list>::const_iterator p = idx.begin ();
666 assert (key_idx.
length () == 1);
668 std::string key = key_idx(0).string_value ();
680 Cell map_elt = map_val.
index (idx.front (),
true);
687 std::list<octave_value_list> next_idx (idx);
692 next_idx.erase (next_idx.begin ());
693 next_idx.erase (next_idx.begin ());
697 t_rhs = u.
subsasgn (type.substr (2), next_idx, rhs);
712 assert (key_idx.
length () == 1);
714 std::string key = key_idx(0).string_value ();
716 std::list<octave_value_list> next_idx (idx);
718 next_idx.erase (next_idx.begin ());
720 std::string next_type = type.substr (1);
733 if (tmpc.
numel () == 1)
747 t_rhs = tmp.
subsasgn (next_type, next_idx, rhs);
770 if (n > 1 && type[1] ==
'.')
772 std::list<octave_value_list>::const_iterator p = idx.begin ();
775 assert (key_idx.
length () == 1);
777 std::string key = key_idx(0).string_value ();
813 error (
"invalid class assignment");
830 error (
"invalid class assignment");
840 assert (key_idx.
length () == 1);
842 std::string key = key_idx(0).string_value ();
904 if (tmp(0).is_object ())
905 error (
"subsindex function must return a valid index vector");
916 error (
"no subsindex method defined for class %s",
931 std::string key =
map.
key (p);
958 for (std::list<std::string>::iterator pit =
parent_list.begin ();
989 for (std::list<std::string>::iterator pit =
parent_list.begin ();
1021 bool retval =
false;
1027 for (std::list<std::string>::const_iterator pit =
parent_list.begin ();
1063 if (tmp(0).is_string ())
1064 retval = tmp(0).all_strings (pad);
1066 error (
"cname/char method did not return a string");
1070 error (
"no char method defined for class %s",
class_name ().c_str ());
1095 bool retval =
false;
1121 arg_names[0] = name;
1130 os << name <<
" = <class " <<
class_name () <<
">";
1141 bool retval =
false;
1152 bool have_ctor =
false;
1207 bool might_have_inheritance =
false;
1208 std::string dbgstr =
"dork";
1213 std::string key =
map.
key (p);
1220 might_have_inheritance =
true;
1227 if (might_have_inheritance)
1238 for (std::list<std::string>::iterator pit =
parent_list.begin ();
1259 os <<
"# classname: " <<
class_name () <<
"\n";
1266 m = tmp(0).map_value ();
1273 os <<
"# length: " << m.
nfields () <<
"\n";
1276 while (i != m.
end ())
1283 return ! os.fail ();
1295 std::string classname;
1296 bool success =
true;
1322 error (
"load: internal error loading class elements");
1337 warning (
"load: unable to reconstruct object inheritance");
1346 map = tmp(0).map_value ();
1353 error (
"load: failed to load class");
1367 error (
"load: failed to extract number of elements in class");
1373 error (
"load: failed to extract name of class");
1383 int32_t classname_len =
class_name ().length ();
1385 os.write (reinterpret_cast<char *> (&classname_len), 4);
1394 m = tmp(0).map_value ();
1402 os.write (reinterpret_cast<char *> (&len), 4);
1405 while (i != m.
end ())
1412 return ! os.fail ();
1424 bool success =
true;
1426 int32_t classname_len;
1428 is.read (reinterpret_cast<char *> (&classname_len), 4);
1436 classname[classname_len] =
'\0';
1437 if (! is.read (reinterpret_cast<char *> (classname), classname_len))
1444 if (! is.read (reinterpret_cast<char *> (&len), 4))
1470 error (
"load: internal error loading class elements");
1482 warning (
"load: unable to reconstruct object inheritance");
1490 map = tmp(0).map_value ();
1497 warning (
"load: failed to load class");
1512 #if defined (HAVE_HDF5)
1515 hid_t group_hid = -1;
1516 hid_t type_hid = -1;
1517 hid_t space_hid = -1;
1518 hid_t class_hid = -1;
1519 hid_t data_hid = -1;
1524 group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1526 group_hid = H5Gcreate (loc_id, name, 0);
1532 type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid,
c_name.length () + 1);
1537 space_hid = H5Screate_simple (0 , hdims, 0);
1541 class_hid = H5Dcreate (group_hid,
"classname", type_hid, space_hid,
1542 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1544 class_hid = H5Dcreate (group_hid,
"classname", type_hid, space_hid,
1547 if (class_hid < 0 || H5Dwrite (class_hid, type_hid, H5S_ALL, H5S_ALL,
1548 H5P_DEFAULT,
c_name.c_str ()) < 0)
1552 data_hid = H5Gcreate (group_hid,
"value", H5P_DEFAULT, H5P_DEFAULT,
1555 data_hid = H5Gcreate (group_hid,
"value", 0);
1565 m = tmp(0).map_value ();
1574 while (i != m.
end ())
1590 H5Gclose (data_hid);
1593 H5Dclose (class_hid);
1596 H5Sclose (space_hid);
1599 H5Tclose (type_hid);
1602 H5Gclose (group_hid);
1615 bool retval =
false;
1617 #if defined (HAVE_HDF5)
1619 hid_t group_hid = -1;
1620 hid_t data_hid = -1;
1621 hid_t type_hid = -1;
1622 hid_t type_class_hid = -1;
1623 hid_t space_hid = -1;
1624 hid_t subgroup_hid = -1;
1631 int current_item = 0;
1632 hsize_t num_obj = 0;
1637 group_hid = H5Gopen (loc_id, name, H5P_DEFAULT);
1639 group_hid = H5Gopen (loc_id, name);
1645 data_hid = H5Dopen (group_hid,
"classname", H5P_DEFAULT);
1647 data_hid = H5Dopen (group_hid,
"classname");
1653 type_hid = H5Dget_type (data_hid);
1655 type_class_hid = H5Tget_class (type_hid);
1657 if (type_class_hid != H5T_STRING)
1660 space_hid = H5Dget_space (data_hid);
1661 rank = H5Sget_simple_extent_ndims (space_hid);
1666 slen = H5Tget_size (type_hid);
1676 st_id = H5Tcopy (H5T_C_S1);
1677 H5Tset_size (st_id, slen);
1679 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT,
1683 H5Dclose (data_hid);
1684 H5Gclose (group_hid);
1689 H5Dclose (data_hid);
1698 subgroup_hid = H5Gopen (group_hid, name, H5P_DEFAULT);
1700 subgroup_hid = H5Gopen (group_hid, name);
1702 H5Gget_num_objs (subgroup_hid, &num_obj);
1703 H5Gclose (subgroup_hid);
1705 while (current_item < static_cast<int> (num_obj)
1706 && (retval2 = H5Giterate (group_hid, name, ¤t_item,
1715 error (
"load: internal error loading class elements");
1728 warning (
"load: unable to reconstruct object inheritance");
1737 map = tmp(0).map_value ();
1747 H5Dclose (data_hid);
1750 H5Gclose (group_hid);
1781 : field_names (), parent_class_names ()
1791 error (
"invalid call to exemplar_info constructor");
1813 if (obj_fnames[i] != fnames[i])
1816 error (
"mismatch in field names");
1823 std::list<std::string> obj_parents
1825 std::list<std::string> pnames = parents ();
1827 std::list<std::string>::const_iterator p = obj_parents.begin ();
1828 std::list<std::string>::const_iterator q = pnames.begin ();
1830 while (p != obj_parents.end ())
1835 error (
"mismatch in parent classes");
1843 error (
"mismatch in number of parent classes");
1849 error (
"mismatch in number of fields");
1855 error (
"invalid comparison of class exemplar to non-class object");
1861 DEFUN (
class, args, ,
1863 @deftypefn {Function File} {@var{classname} =} class (@var{obj})\n\
1864 @deftypefnx {Function File} {} class (@var{s}, @var{id})\n\
1865 @deftypefnx {Function File} {} class (@var{s}, @var{id}, @var{p}, @dots{})\n\
1866 Return the class of the object @var{obj}, or create a class with\n\
1867 fields from structure @var{s} and name (string) @var{id}.\n\
1869 Additional arguments name a list of parent classes from which the new class\n\
1871 @seealso{typeinfo, isa}\n\
1876 int nargin = args.
length ();
1880 else if (nargin == 1)
1890 std::string
id = args(1).string_value ();
1903 (m,
id, std::list<std::string> ()));
1915 = octave_class::exemplar_map.find (
id);
1917 if (it == octave_class::exemplar_map.end ())
1918 octave_class::exemplar_map[id]
1920 else if (! it->second.compare (retval))
1921 error (
"class: object of class '%s' does not match previously constructed objects",
1926 error (
"class: expecting structure S as first argument");
1929 error (
"class: '%s' is invalid as a class name in this context",
1933 error (
"class: invalid call from outside class constructor or method");
1936 error (
"class: ID (class name) must be a string");
1956 @deftypefn {Function File} {} isa (@var{obj}, @var{classname})\n\
1957 Return true if @var{obj} is an object from the class @var{classname}.\n\
1959 @var{classname} may also be one of the following class categories:\n\
1962 @item @qcode{\"float\"}\n\
1963 Floating point value comprising classes @qcode{\"double\"} and\n\
1964 @qcode{\"single\"}.\n\
1966 @item @qcode{\"integer\"}\n\
1967 Integer value comprising classes (u)int8, (u)int16, (u)int32, (u)int64.\n\
1969 @item @qcode{\"numeric\"}\n\
1970 Numeric value comprising either a floating point or integer value.\n\
1973 If @var{classname} is a cell array of string, a logical array of the same\n\
1974 size is returned, containing true for each class to which @var{obj}\n\
1977 @seealso{class, typeinfo}\n\
1982 if (args.length () != 2)
1992 error (
"isa: CLASSNAME must be a string or cell array of strings");
2000 const std::string cl = cls(idx);
2005 matches(idx) =
true;
2070 DEFUN (__parent_classes__, args, ,
2072 @deftypefn {Built-in Function} {} __parent_classes__ (@var{x})\n\
2073 Undocumented internal function.\n\
2078 if (args.length () == 1)
2091 DEFUN (isobject, args, ,
2093 @deftypefn {Built-in Function} {} isobject (@var{x})\n\
2094 Return true if @var{x} is a class object.\n\
2095 @seealso{class, typeinfo, isa, ismethod, isprop}\n\
2100 if (args.length () == 1)
2108 DEFUN (ismethod, args, ,
2110 @deftypefn {Built-in Function} {} ismethod (@var{obj}, @var{method})\n\
2111 Return true if @var{obj} is a class object and the string @var{method}\n\
2112 is a method of this class.\n\
2113 @seealso{isprop, isobject}\n\
2118 if (args.length () == 2)
2129 error (
"ismethod: expecting object or class name as first argument");
2133 std::string method = args(1).string_value ();
2150 DEFUN (__methods__, args, ,
2152 @deftypefn {Built-in Function} {} __methods__ (@var{x})\n\
2153 @deftypefnx {Built-in Function} {} __methods__ (\"classname\")\n\
2154 Internal function.\n\
2156 Implements @code{methods} for Octave class objects and classnames.\n\
2157 @seealso{methods}\n\
2184 static std::set<std::string> built_in_class_names;
2186 if (built_in_class_names.empty ())
2188 built_in_class_names.insert (
"double");
2189 built_in_class_names.insert (
"single");
2190 built_in_class_names.insert (
"cell");
2191 built_in_class_names.insert (
"struct");
2192 built_in_class_names.insert (
"logical");
2193 built_in_class_names.insert (
"char");
2194 built_in_class_names.insert (
"function handle");
2195 built_in_class_names.insert (
"int8");
2196 built_in_class_names.insert (
"uint8");
2197 built_in_class_names.insert (
"int16");
2198 built_in_class_names.insert (
"uint16");
2199 built_in_class_names.insert (
"int32");
2200 built_in_class_names.insert (
"uint32");
2201 built_in_class_names.insert (
"int64");
2202 built_in_class_names.insert (
"uint64");
2205 return built_in_class_names.find (cn) != built_in_class_names.end ();
2208 DEFUN (superiorto, args, ,
2210 @deftypefn {Built-in Function} {} superiorto (@var{class_name}, @dots{})\n\
2211 When called from a class constructor, mark the object currently\n\
2212 constructed as having a higher precedence than @var{class_name}.\n\
2214 More that one such class can be specified in a single call.\n\
2215 This function may only be called from a class constructor.\n\
2216 @seealso{inferiorto}\n\
2224 error (
"superiorto: invalid call from outside class constructor");
2228 for (
int i = 0; i < args.length (); i++)
2233 error (
"superiorto: expecting argument to be class name");
2242 std::string sup_class = fcn->
name ();
2245 error (
"superiorto: opposite precedence already set for %s and %s",
2246 sup_class.c_str (), inf_class.c_str ());
2254 DEFUN (inferiorto, args, ,
2256 @deftypefn {Built-in Function} {} inferiorto (@var{class_name}, @dots{})\n\
2257 When called from a class constructor, mark the object currently\n\
2258 constructed as having a lower precedence than @var{class_name}.\n\
2260 More that one such class can be specified in a single call.\n\
2261 This function may only be called from a class constructor.\n\
2262 @seealso{superiorto}\n\
2270 error (
"inferiorto: invalid call from outside class constructor");
2274 for (
int i = 0; i < args.length (); i++)
2279 error (
"inferiorto: expecting argument to be class name");
2285 error (
"inferiorto: cannot give user-defined class lower "
2286 "precedence than built-in class");
2290 std::string inf_class = fcn->
name ();
2293 error (
"inferiorto: opposite precedence already set for %s and %s",
2294 inf_class.c_str (), sup_class.c_str ());
static octave_value numeric_conv(const Cell &val, const std::string &type)
bool called_from_builtin(void)
virtual octave_base_value * unique_parent_class(const std::string &)
string_vector keys(void) const
bool is_object(void) const
bool in_class_method(void)
idx_vector index_vector(bool require_integers=false) const
const Cell & contents(const_iterator p) const
size_t nparents(void) const
static bool is_built_in_class(const std::string &cn)
octave_refcount< octave_idx_type > count
void gripe_wrong_type_arg(const char *name, const char *s, bool is_error)
std::list< std::string > parents(void) const
void delete_elements(const idx_vector &i)
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
void assign(const std::string &k, const Cell &val)
octave_base_value * clone(void) const
Cell reshape(const dim_vector &new_dims) const
virtual octave_map map_value(void) const
static octave_value find_method(const std::string &name, const std::string &dispatch_type)
OCTINTERP_API void print_usage(void)
bool save_binary(std::ostream &os, bool &save_as_floats)
bool is_function(void) const
octave_idx_type numel(void) const
Number of elements in the array.
void gripe_load(const char *type) const
bool is_instance_of(const std::string &) const
octave_idx_type length(void) const
dim_vector dims(void) const
octave_idx_type nfields(void) const
std::list< std::string > parent_class_name_list(void) const
octave_map map_value(void) const
std::string type_name(void) const
bool contains(const std::string &name) const
bool is_numeric_type(void) const
bool is_defined(void) const
#define DEFUN(name, args_name, nargout_name, doc)
static void add_to_parent_map(const std::string &classname, const std::list< std::string > &parent_list)
void error(const char *fmt,...)
std::string name(void) const
void indent(std::ostream &os) const
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
octave_value_list feval(const std::string &name, const octave_value_list &args, int nargout)
static const std::string t_name
virtual bool is_anonymous_function_of_class(const std::string &=std::string()) const
static octave_function * current(void)
void gripe_save(const char *type) const
static void gripe_failed_assignment(void)
void interpreter_try(unwind_protect &frame)
octave_idx_type numel(void) const
herr_t hdf5_read_next_data(hid_t group_id, const char *name, void *dv)
Cell dotref(const octave_value_list &idx)
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
void newline(std::ostream &os) const
const_iterator end(void) const
bool is_private_function_of_class(const std::string &nm) const
virtual octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
std::string dispatch_class(void) const
void print_with_name(std::ostream &os, const std::string &name, bool print_padding=true)
bool is_instance_of(const std::string &cls_name) const
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
virtual octave_idx_type numel(void) const
string_vector field_names
void gripe_indexed_cs_list(void)
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Cell cell_value(void) const
virtual bool is_class_method(const std::string &=std::string()) const
idx_vector index_vector(bool require_integers=false) const
bool is_float_type(void) const
octave_map map_value(void) const
std::map< std::string, exemplar_info >::const_iterator exemplar_const_iterator
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
octave_value_list do_multi_index_op(int nargout, const octave_value_list &idx)
bool load_binary(std::istream &is, bool swap, oct_mach_info::float_format fmt)
octave_value subsasgn_common(const octave_value &obj, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
std::string extract_keyword(std::istream &is, const char *keyword, const bool next_only)
static std::map< std::string, exemplar_info > exemplar_map
virtual octave_base_value * find_parent_class(const std::string &)
void swap_bytes< 4 >(void *ptr)
static octave_function * caller(void)
bool reconstruct_parents(void)
octave_idx_type nfields(void) const
octave_idx_type numel(const octave_value_list &idx)
void print(std::ostream &os, bool pr_as_read_syntax=false)
std::string string_value(bool force=false) const
static void register_type(void)
bool is_string(void) const
bool add_hdf5_data(hid_t loc_id, const octave_value &tc, const std::string &name, const std::string &doc, bool mark_as_global, bool save_as_floats)
bool save_ascii_data(std::ostream &os, const octave_value &val_arg, const std::string &name, bool mark_as_global, int precision)
octave_user_function * user_function_value(bool silent=false) const
mxArray * as_mxArray(void) const
dim_vector dims(void) const
#define panic_impossible()
bool compare(const octave_value &obj) const
static std::string find_method(const std::string &class_name, const std::string &meth, std::string &dir_name, const std::string &pack_name=std::string())
std::string read_binary_data(std::istream &is, bool swap, oct_mach_info::float_format fmt, const std::string &filename, bool &global, octave_value &tc, std::string &doc)
std::string key(const_iterator p) const
octave_idx_type length(void) const
string_vector all_strings(bool pad) const
std::list< std::string > parent_class_names
string_vector parent_class_names(void) const
const_iterator begin(void) const
virtual Matrix size(void)
static void gripe_invalid_index_for_assignment(void)
dim_vector dims(void) const
static void gripe_invalid_index_type(const std::string &nm, char t)
string_vector map_keys(void) const
bool print_name_tag(std::ostream &os, const std::string &name) const
friend class octave_value
void setfield(const std::string &key, const Cell &val)
octave_function * function_value(bool silent=false) const
static std::list< std::string > methods(const std::string &class_name, const std::string &pack_name=std::string())
static bool set_class_relationship(const std::string &sup_class, const std::string &inf_class)
void warning(const char *fmt,...)
octave_idx_type length(void) const
Number of elements in the array.
octave_base_value * unique_clone(void)
bool is_empty(void) const
octave_value make_idx_args(const std::string &type, const std::list< octave_value_list > &idx, const std::string &who)
bool subsasgn_optimization_ok(void)
octave_base_value * find_parent_class(const std::string &)
static void clear_exemplar_map(void)
size_t nparents(void) const
octave_idx_type nfields(void) const
static void gripe_invalid_index1(void)
bool save_binary_data(std::ostream &os, const octave_value &tc, const std::string &name, const std::string &doc, bool mark_as_global, bool save_as_floats)
virtual bool is_string(void) const
static int register_type(const std::string &, const std::string &, const octave_value &)
std::list< std::string > parent_list
bool is_cs_list(void) const
octave_idx_type numel(void) const
std::string class_name(void) const
Cell index(const octave_value_list &idx, bool resize_ok=false) const
bool is_object(void) const
size_t byte_size(void) const
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
const_iterator seek(const std::string &k) const
bool is_user_function(void) const
virtual bool is_class_constructor(const std::string &=std::string()) const
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
octave_value_list list_value(void) const
octave_idx_type index(const_iterator p) const
void resize(const dim_vector &dv, bool fill=false)
octave_base_value * unique_parent_class(const std::string &)
bool load_ascii(std::istream &is)
octave_fields::const_iterator const_iterator
bool reconstruct_exemplar(void)
octave_base_value * internal_rep(void) const
bool save_ascii(std::ostream &os)
octave_value storable_value(void) const
bool is_zero_by_zero(void) const
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
std::string get_current_method_class(void)
static octave_value empty_conv(const std::string &type, const octave_value &rhs=octave_value())
octave_value do_binary_op(octave_value::binary_op op, const octave_value &v1, const octave_value &v2)
std::string read_ascii_data(std::istream &is, const std::string &filename, bool &global, octave_value &tc, octave_idx_type count)
size_t byte_size(void) const
std::string class_name(void) const
bool is_integer_type(void) const
void stash_name_tags(const string_vector &nm)