26#if defined (HAVE_CONFIG_H)
87 error (
"parents must be objects");
92 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)
174 else if (nel == p_nel)
190 std::list<std::string> plist
199 error (
"class: parent class dimension mismatch");
234 octave::tree_evaluator& tw
248OCTAVE_NORETURN
static
252 error (
"invalid index for class");
255OCTAVE_NORETURN
static
259 error (
"invalid index for class assignment");
262OCTAVE_NORETURN
static
266 error (
"%s cannot be indexed with %c", nm.c_str (), t);
277 c(i).break_closure_cycles (frame);
284 assert (idx.
length () == 1);
294 error (
"malformed class");
298 std::string nm = idx(0).xstring_value (
"invalid index for class");
302 if (p == my_map.
end ())
303 error (
"class has no member '%s'", nm.c_str ());
314 Matrix retval (1, 2, 1.0);
316 octave::symbol_table& symtab
331 retval = lv(0).matrix_value ();
337 int nd = dv.
ndims ();
341 for (
int i = 0; i < nd; i++)
357 octave::symbol_table& symtab
374 error (
"@%s/numel: invalid return value", cn.c_str ());
376 retval = lv(0).idx_type_value (
true);
386 const std::list<octave_value_list>& idx,
403 if (type.length () > 1 && type[1] ==
'.')
405 auto p = idx.begin ();
412 retval(0) = (t.
numel () == 1 ? t(0)
449 retval = retval(0).next_subsref (nargout, type, idx, skip);
453 octave::symbol_table& symtab
472 bool maybe_cs_list_query = (type[0] ==
'.' || type[0] ==
'{'
473 || (type.length () > 1 && type[0] ==
'('
476 int true_nargout = nargout;
478 if (maybe_cs_list_query)
482 if (type[0] !=
'.') tmp = idx.front ();
483 true_nargout =
xnumel (tmp);
496 if (type.length () == 1 && type[0] ==
'(')
512 if (val.
numel () != 1)
517 if (type.length () > 0 && type[0] ==
'.' && ! retval.
isstruct ())
525 const std::list<octave_value_list>& idx,
534 const std::list<octave_value_list>& idx,
546 const std::string& type,
547 const std::list<octave_value_list>& idx,
554 octave::symbol_table& symtab
606 error (
"@%s/subsasgn returned more than one value",
626 error (
"malformed class");
644 if (n > 1 && ! (type.length () == 2 && type[0] ==
'(' && type[1] ==
'.'))
650 if (type.length () > 1 && type[1] ==
'.')
652 auto p = idx.begin ();
657 assert (key_idx.
length () == 1);
659 std::string key = key_idx(0).xstring_value (
"invalid index for class assignment");
669 Cell map_elt = map_val.
index (idx.front (),
true);
674 std::list<octave_value_list> next_idx (idx);
679 next_idx.erase (next_idx.begin ());
680 next_idx.erase (next_idx.begin ());
684 t_rhs = u.
subsasgn (type.substr (2), next_idx, rhs);
695 assert (key_idx.
length () == 1);
697 std::string key = key_idx(0).string_value ();
699 std::list<octave_value_list> next_idx (idx);
701 next_idx.erase (next_idx.begin ());
703 std::string next_type = type.substr (1);
714 if (tmpc.
numel () != 1)
728 t_rhs = tmp.
subsasgn (next_type, next_idx, rhs);
745 if (n > 1 && type[1] ==
'.')
747 auto p = idx.begin ();
750 assert (key_idx.
length () == 1);
752 std::string key = key_idx(0).xstring_value (
"assignment to class element failed");
773 error (
"invalid class assignment");
788 assert (key_idx.
length () == 1);
790 std::string key = key_idx(0).string_value ();
831 octave::symbol_table& symtab
837 error (
"no subsindex method defined for class %s",
846 error (
"subsindex function must return a valid index vector");
861 std::size_t retval = 0;
880 octave::symbol_table& symtab
890 retval = tmp(0).is_true ();
999 octave::symbol_table& symtab
1005 error (
"no char method defined for class %s",
class_name ().c_str ());
1015 error (
"cname/char method did not return a string");
1017 retval = tmp(0).string_vector_value (pad);
1043 bool retval =
false;
1052 octave::interpreter& interp
1055 octave::symbol_table& symtab = interp.get_symbol_table ();
1059 bool have_ctor =
false;
1082 bool execution_error =
false;
1090 catch (
const octave::execution_exception&)
1092 interp.recover_from_exception ();
1094 execution_error =
true;
1097 if (! execution_error && result.
length () == 1)
1124 bool might_have_inheritance =
false;
1125 std::string dbgstr =
"dork";
1137 might_have_inheritance =
true;
1144 if (might_have_inheritance)
1174 os <<
"# classname: " <<
class_name () <<
"\n";
1179 if (lp.find_method (
class_name (),
"saveobj") !=
"")
1184 m = tmp(0).map_value ();
1189 os <<
"# length: " << m.
nfields () <<
"\n";
1191 auto i = m.
begin ();
1192 while (i != m.
end ())
1199 return ! os.fail ();
1211 std::string classname;
1213 if (!
extract_keyword (is,
"classname", classname) || classname.empty ())
1214 error (
"load: failed to extract name of class");
1217 error (
"load: failed to extract number of elements in class");
1241 error (
"load: failed to load class");
1249 warning (
"load: unable to reconstruct object inheritance");
1253 if (lp.find_method (classname,
"loadobj") !=
"")
1258 m_map = tmp(0).map_value ();
1275 int32_t classname_len =
class_name ().length ();
1277 os.write (
reinterpret_cast<char *
> (&classname_len), 4);
1284 if (lp.find_method (
class_name (),
"saveobj") !=
"")
1289 m = tmp(0).map_value ();
1295 os.write (
reinterpret_cast<char *
> (&
len), 4);
1297 auto i = m.
begin ();
1298 while (i != m.
end ())
1305 return ! os.fail ();
1317 bool success =
true;
1319 int32_t classname_len;
1321 is.read (
reinterpret_cast<char *
> (&classname_len), 4);
1329 classname[classname_len] =
'\0';
1330 if (! is.read (
reinterpret_cast<char *
> (classname), classname_len))
1337 if (! is.read (
reinterpret_cast<char *
> (&
len), 4))
1369 warning (
"load: unable to reconstruct object inheritance");
1373 if (lp.find_method (
c_name,
"loadobj") !=
"")
1378 m_map = tmp(0).map_value ();
1383 warning (
"load: failed to load class");
1397 bool save_as_floats)
1399#if defined (HAVE_HDF5)
1402 hid_t group_hid = -1;
1403 hid_t type_hid = -1;
1404 hid_t space_hid = -1;
1405 hid_t class_hid = -1;
1406 hid_t data_hid = -1;
1412#if defined (HAVE_HDF5_18)
1416 group_hid = H5Gcreate (loc_id,
name, 0);
1422 type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid,
c_name.length () + 1);
1427 space_hid = H5Screate_simple (0, hdims,
nullptr);
1430#if defined (HAVE_HDF5_18)
1431 class_hid = H5Dcreate (group_hid,
"classname", type_hid, space_hid,
1435 class_hid = H5Dcreate (group_hid,
"classname", type_hid, space_hid,
1438 if (class_hid < 0 || H5Dwrite (class_hid, type_hid,
octave_H5S_ALL,
1443#if defined (HAVE_HDF5_18)
1447 data_hid = H5Gcreate (group_hid,
"value", 0);
1452 if (lp.find_method (
class_name (),
"saveobj") !=
"")
1457 m = tmp(0).map_value ();
1464 while (i != m.
end ())
1480 H5Gclose (data_hid);
1483 H5Dclose (class_hid);
1486 H5Sclose (space_hid);
1489 H5Tclose (type_hid);
1492 H5Gclose (group_hid);
1497 octave_unused_parameter (loc_id);
1498 octave_unused_parameter (
name);
1499 octave_unused_parameter (save_as_floats);
1510 bool retval =
false;
1512#if defined (HAVE_HDF5)
1514 hid_t group_hid = -1;
1515 hid_t data_hid = -1;
1516 hid_t type_hid = -1;
1517 hid_t type_class_hid = -1;
1518 hid_t space_hid = -1;
1519 hid_t subgroup_hid = -1;
1526 int current_item = 0;
1527 hsize_t num_obj = 0;
1531#if defined (HAVE_HDF5_18)
1534 group_hid = H5Gopen (loc_id,
name);
1539#if defined (HAVE_HDF5_18)
1542 data_hid = H5Dopen (group_hid,
"classname");
1548 type_hid = H5Dget_type (data_hid);
1550 type_class_hid = H5Tget_class (type_hid);
1552 if (type_class_hid != H5T_STRING)
1555 space_hid = H5Dget_space (data_hid);
1556 rank = H5Sget_simple_extent_ndims (space_hid);
1561 slen = H5Tget_size (type_hid);
1571 st_id = H5Tcopy (H5T_C_S1);
1572 H5Tset_size (st_id, slen);
1579 H5Dclose (data_hid);
1580 H5Gclose (group_hid);
1585 H5Dclose (data_hid);
1593#if defined (HAVE_HDF5_18)
1596 subgroup_hid = H5Gopen (group_hid,
name);
1598 H5Gget_num_objs (subgroup_hid, &num_obj);
1599 H5Gclose (subgroup_hid);
1601 while (current_item <
static_cast<int> (num_obj)
1618 warning (
"load: unable to reconstruct object inheritance");
1622 if (lp.find_method (
c_name,
"loadobj") !=
"")
1627 m_map = tmp(0).map_value ();
1634 H5Dclose (data_hid);
1637 H5Gclose (group_hid);
1640 octave_unused_parameter (loc_id);
1641 octave_unused_parameter (
name);
1658 octave::tree_evaluator& tw
1672 : m_field_names (), m_parent_class_names ()
1675 error (
"invalid call to exemplar_info constructor");
1691 error (
"invalid comparison of class exemplar to non-class object");
1694 error (
"mismatch in number of fields");
1702 if (obj_fnames[i] != fnames[i])
1703 error (
"mismatch in field names");
1707 error (
"mismatch in number of parent classes");
1709 const std::list<std::string> obj_parents
1711 const std::list<std::string> pnames = parents ();
1713 auto p = obj_parents.begin ();
1714 auto q = pnames.begin ();
1716 while (p != obj_parents.end ())
1719 error (
"mismatch in parent classes");
1725OCTAVE_NAMESPACE_BEGIN
1740 int nargin = args.length ();
1753 std::string
id = args(1).xstring_value (
"class: ID (class name) must be a string");
1760 error (
"class: invalid call from outside class constructor or method");
1763 error (
"class: '%s' is invalid as a class name in this context",
1766 octave_map m = args(0).xmap_value (
"class: S must be a valid structure");
1783 else if (! it->second.compare (retval))
1784 error (
"class: object of class '%s' does not match previously constructed objects",
1829 if (args.length () != 2)
1834 Array<std::string> clsnames = args(1).xcellstr_value (
"isa: CLASSNAME must be a string or cell array of strings");
1840 std::string cls = clsnames(idx);
1842 || (cls ==
"float" && obj.
isfloat ())
1843 || (cls ==
"integer" && obj.
isinteger ())
1844 || (cls ==
"numeric" && obj.
isnumeric ())
1846 matches(idx) =
true;
1849 return ovl (matches);
1912DEFUN (__parent_classes__, args, ,
1918 if (args.length () != 1)
1936 if (args.length () != 1)
1945 static std::set<std::string> built_in_class_names;
1947 if (built_in_class_names.empty ())
1949 built_in_class_names.insert (
"double");
1950 built_in_class_names.insert (
"single");
1951 built_in_class_names.insert (
"cell");
1952 built_in_class_names.insert (
"struct");
1953 built_in_class_names.insert (
"logical");
1954 built_in_class_names.insert (
"char");
1955 built_in_class_names.insert (
"function handle");
1956 built_in_class_names.insert (
"int8");
1957 built_in_class_names.insert (
"uint8");
1958 built_in_class_names.insert (
"int16");
1959 built_in_class_names.insert (
"uint16");
1960 built_in_class_names.insert (
"int32");
1961 built_in_class_names.insert (
"uint32");
1962 built_in_class_names.insert (
"int64");
1963 built_in_class_names.insert (
"uint64");
1966 return built_in_class_names.find (cn) != built_in_class_names.end ();
1985 error (
"superiorto: invalid call from outside class constructor");
1987 for (
int i = 0; i < args.length (); i++)
1989 std::string inf_class = args(i).xstring_value (
"superiorto: CLASS_NAME must be a string");
1998 std::string sup_class = fcn->
name ();
2000 error (
"superiorto: opposite precedence already set for %s and %s",
2001 sup_class.c_str (), inf_class.c_str ());
2023 error (
"inferiorto: invalid call from outside class constructor");
2025 for (
int i = 0; i < args.length (); i++)
2027 std::string sup_class = args(i).xstring_value (
"inferiorto: CLASS_NAME must be a string");
2030 error (
"inferiorto: cannot give user-defined class lower "
2031 "precedence than built-in class");
2035 std::string inf_class = fcn->
name ();
2037 error (
"inferiorto: opposite precedence already set for %s and %s",
2038 inf_class.c_str (), sup_class.c_str ());
2086 return execute (tw, nargout, args);
2149DEFUN (__inline_ctor__, args, ,
bool isvector(const dim_vector &dim)
void swap_bytes< 4 >(void *ptr)
octave_idx_type numel(void) const
Number of elements in the array.
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Cell reshape(const dim_vector &new_dims) const
Cell index(const octave_value_list &idx, bool resize_ok=false) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
Vector representing the dimensions (size) of an Array.
octave_idx_type ndims(void) const
Number of dimensions.
octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
octave::refcount< octave_idx_type > count
virtual bool is_string(void) const
virtual octave_map map_value(void) const
OCTINTERP_API void indent(std::ostream &os) const
OCTINTERP_API void newline(std::ostream &os) const
virtual octave_base_value * unique_parent_class(const std::string &)
virtual octave_base_value * find_parent_class(const std::string &)
virtual Matrix size(void)
virtual bool is_matrix_type(void) const
OCTINTERP_API void warn_load(const char *type) const
virtual bool is_scalar_type(void) const
virtual octave_idx_type xnumel(const octave_value_list &)
virtual octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
static void register_type(void)
friend class octave_value
OCTINTERP_API void warn_save(const char *type) const
OCTINTERP_API bool compare(const octave_value &obj) const
std::list< std::string > parents(void) const
string_vector m_field_names
std::list< std::string > m_parent_class_names
OCTINTERP_API void print(std::ostream &os, bool pr_as_read_syntax=false)
std::string type_name(void) const
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
OCTINTERP_API string_vector map_keys(void) const
OCTINTERP_API octave_base_value * unique_parent_class(const std::string &)
OCTINTERP_API octave_base_value * unique_clone(void)
OCTINTERP_API octave_idx_type xnumel(const octave_value_list &)
OCTINTERP_API octave_base_value * find_parent_class(const std::string &)
std::map< std::string, exemplar_info >::const_iterator exemplar_const_iterator
OCTINTERP_API bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
OCTINTERP_API void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
OCTINTERP_API std::size_t byte_size(void) const
OCTINTERP_API Cell dotref(const octave_value_list &idx)
OCTINTERP_API octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
std::list< std::string > m_parent_list
OCTINTERP_API bool load_hdf5(octave_hdf5_id loc_id, const char *name)
static std::map< std::string, exemplar_info > exemplar_map
octave_idx_type numel(void) const
std::string class_name(void) const
OCTINTERP_API octave_value subsasgn_common(const octave_value &obj, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
OCTINTERP_API mxArray * as_mxArray(bool interleaved) const
static const std::string t_name
octave_map map_value(void) const
OCTINTERP_API bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
OCTINTERP_API bool in_class_method(void)
OCTINTERP_API octave::idx_vector index_vector(bool require_integers=false) const
OCTINTERP_API bool save_ascii(std::ostream &os)
void break_closure_cycles(const std::shared_ptr< octave::stack_frame > &frame)
std::size_t nparents(void) const
OCTINTERP_API bool is_instance_of(const std::string &) const
OCTINTERP_API string_vector string_vector_value(bool pad) const
octave_idx_type nfields(void) const
dim_vector dims(void) const
OCTINTERP_API bool reconstruct_parents(void)
OCTINTERP_API bool load_ascii(std::istream &is)
OCTINTERP_API Matrix size(void)
OCTINTERP_API std::string get_current_method_class(void)
octave_base_value * clone(void) const
bool isobject(void) const
static OCTINTERP_API void clear_exemplar_map(void)
OCTINTERP_API bool is_true(void) const
OCTINTERP_API bool save_binary(std::ostream &os, bool save_as_floats)
OCTINTERP_API bool reconstruct_exemplar(void)
static OCTINTERP_API octave_value numeric_conv(const Cell &val, const std::string &type)
OCTINTERP_API octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
std::string dispatch_class(void) const
virtual bool is_anonymous_function_of_class(const std::string &="") const
bool is_class_method(const std::string &cname="") const
bool is_class_constructor(const std::string &cname="") const
bool is_private_function_of_class(const std::string &nm) const
std::string name(void) const
octave_value_list execute(tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
octave_inline_fcn(const octave_inline_fcn &ob)=delete
octave_inline_fcn(octave_inline *obj)
octave_value_list call(tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
octave_inline * m_inline_obj
~octave_inline_fcn(void)=default
octave_inline(const octave_inline &)=default
octave_inline(const octave_map &m)
octave_function * function_value(bool)
octave_base_value * clone(void) const
~octave_inline(void)=default
bool is_inline_function(void) const
octave_base_value * empty_clone(void) const
std::shared_ptr< octave_inline_fcn > m_fcn_obj
void resize(const dim_vector &dv, bool fill=false)
octave_idx_type nfields(void) const
const_iterator cend(void) const
octave_fields::const_iterator const_iterator
const Cell & contents(const_iterator p) const
void delete_elements(const octave::idx_vector &i)
void setfield(const std::string &key, const Cell &val)
octave_idx_type numel(void) const
const_iterator seek(const std::string &k) const
bool contains(const std::string &name) const
void assign(const std::string &k, const Cell &val)
std::string key(const_iterator p) const
const_iterator begin(void) const
const_iterator end(void) const
string_vector keys(void) const
const_iterator cbegin(void) const
dim_vector dims(void) const
octave_idx_type index(const_iterator p) const
bool subsasgn_optimization_ok(void)
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
octave_idx_type length(void) const
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
bool is_function(void) const
OCTINTERP_API octave_value_list list_value(void) const
OCTINTERP_API octave_function * function_value(bool silent=false) const
bool is_instance_of(const std::string &cls_name) const
octave::idx_vector index_vector(bool require_integers=false) const
std::list< std::string > parent_class_name_list(void) const
OCTINTERP_API octave_user_function * user_function_value(bool silent=false) const
OCTINTERP_API octave_map xmap_value(const char *fmt,...) const
static OCTINTERP_API octave_value empty_conv(const std::string &type, const octave_value &rhs=octave_value())
bool isnumeric(void) const
OCTINTERP_API Cell xcell_value(const char *fmt,...) const
octave_idx_type numel(void) const
bool is_cs_list(void) const
OCTINTERP_API octave_value storable_value(void) const
bool is_defined(void) const
bool isinteger(void) const
std::string class_name(void) const
bool isstruct(void) const
bool is_zero_by_zero(void) const
std::size_t byte_size(void) const
octave_idx_type nfields(void) const
string_vector parent_class_names(void) const
octave_base_value * internal_rep(void) const
OCTINTERP_API octave_map map_value(void) const
bool isobject(void) const
std::size_t nparents(void) const
OCTINTERP_API octave_idx_type length(void) const
bool is_user_function(void) const
OCTINTERP_API octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
dim_vector dims(void) const
bool set_class_relationship(const std::string &sup_class, const std::string &inf_class)
interpreter & get_interpreter(void)
octave_function * caller_function(void) const
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5S_ALL
OCTINTERP_API void print_usage(void)
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void interpreter_try(unwind_protect &frame)
void warning(const char *fmt,...)
void error(const char *fmt,...)
#define panic_impossible()
void err_wrong_type_arg(const char *name, const char *s)
void err_indexed_cs_list(void)
octave_hdf5_err hdf5_h5g_iterate(octave_hdf5_id loc_id, const char *name, int *idx, void *operator_data)
bool add_hdf5_data(octave_hdf5_id loc_id, const octave_value &tc, const std::string &name, const std::string &doc, bool mark_global, bool save_as_floats)
std::string read_binary_data(std::istream &is, bool swap, octave::mach_info::float_format fmt, const std::string &filename, bool &global, octave_value &tc, std::string &doc)
bool save_binary_data(std::ostream &os, const octave_value &tc, const std::string &name, const std::string &doc, bool mark_global, bool save_as_floats)
std::string read_text_data(std::istream &is, const std::string &filename, bool &global, octave_value &tc, octave_idx_type count, const bool do_name_validation)
std::string extract_keyword(std::istream &is, const char *keyword, const bool next_only)
bool save_text_data(std::ostream &os, const octave_value &val_arg, const std::string &name, bool mark_global, int precision)
OCTINTERP_API octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
interpreter & __get_interpreter__(const std::string &who)
tree_evaluator & __get_evaluator__(const std::string &who)
load_path & __get_load_path__(const std::string &who)
symbol_table & __get_symbol_table__(const std::string &who)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
octave_value make_idx_args(const std::string &type, const std::list< octave_value_list > &idx, const std::string &who)
bool called_from_builtin(void)
static OCTAVE_NORETURN void err_invalid_index_type(const std::string &nm, char t)
static OCTAVE_NORETURN void err_invalid_index1(void)
static OCTAVE_NORETURN void err_invalid_index_for_assignment(void)
static bool is_built_in_class(const std::string &cn)
OCTINTERP_API octave_value binary_op(type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.