26#if defined (HAVE_CONFIG_H)
53std::vector<std::tuple<octave_map, uint32_t, bool>>
56 octave::cdef_class cls = m_object.get_class ();
57 octave::cdef_method meth = cls.find_method (
"saveobj");
61 std::vector<std::tuple<octave_map, uint32_t, bool>> m (
numel ());
63 octave::load_save_system& lss = octave::__get_load_save_system__ ();
72 std::list<octave_value_list> idx_tmp;
74 idx_tmp.push_back (ovl_idx);
82 std::get<uint32_t> (m[n])
83 = lss.get_mcos_object_cache_id (co.get_rep (), is_new_elem);
84 is_new[n] = is_new_elem;
90 if (! meth.ok () || meth.is_static ())
92 std::get<octave_map> (m[n])
100 std::get<bool> (m[n]) =
false;
104 warning (
"save: saveobj method does not return a value");
114 std::get<octave_map> (m[n]).setfield (
"any", retval);
115 std::get<bool> (m[n]) =
true;
119 std::get<octave_map> (m[n])
122 std::get<octave_map> (m[n]) = retval.
map_value ();
134 octave::cdef_object scalar_obj = m_object.copy ();
135 octave::cdef_class cls = m_object.get_class ();
136 octave::cdef_method meth = cls.find_method (
"loadobj");
138 octave::load_save_system& lss = octave::__get_load_save_system__ ();
147 uint32_t
id = std::get<uint32_t> (m[n]);
148 bool in_obj_cache = lss.is_mcos_object_cache_entry (
id);
150 ovc = lss.get_mcos_object_cache_entry (
id);
152 octave_map& prop_map = std::get<octave_map> (m[n]);
154 if (! in_obj_cache || prop_map.
nfields () > 0)
157 if (meth.ok () && meth.is_static () && prop_map.
nfields () > 0)
160 if (std::get<bool> (m[n]))
168 octave::cdef_object new_object;
172 new_object = scalar_obj.copy ();
174 bool props_changed =
false;
180 for (j = 0; j < sv.
numel (); j++)
182 if (sv[j] == fnames(i))
184 new_object.set_property (0, sv[j], prop_map.
contents (fnames(i)).xelem (0));
188 if (j == sv.
numel ())
191 props_changed =
true;
203 ovc = octave::to_ov (new_object);
212 warning (
"load: loadobj method does not return a value");
223 warning (
"load: loadobj method does not return correct type "
224 "'%s'. This is currently not supported.",
231 warning (
"load: loadobj method does not return classdef object "
232 "of correct class '%s'. This is currently not supported.",
246 if (std::get<bool> (m[n]))
253 if (! prop_map.
isfield (
"any") || prop_map.
numel () != 1)
255 warning (
"load: expected scalar value for custom type when loading object");
264 warning (
"load: cannot restore value of object that was saved as a different type (%s)",
272 warning (
"load: cannot restore value of object that was saved as a different class (%s)",
283 octave::cdef_object new_object;
287 new_object = scalar_obj.copy ();
293 if (sv[j] == fnames(i))
295 new_object.set_property (0, sv[j], prop_map.
contents (fnames(i)).xelem (0));
300 ovc = octave::to_ov (new_object);
303 lss.set_mcos_object_cache_entry (
id, ovc);
311 std::list<octave_value_list> idx_tmp;
313 idx_tmp.push_back (ovl_idx);
332 os <<
"# classname: " <<
class_name () <<
"\n";
335 os <<
"# ndims: " << dv.
ndims () <<
"\n";
337 for (
int i = 0; i < dv.
ndims (); i++)
341 std::vector<bool> is_new (
numel ());
342 std::vector<std::tuple<octave_map, uint32_t, bool>> m
347 os <<
"# id: " << std::get<uint32_t> (m[n]) <<
"\n";
352 os <<
"# length: 0\n";
358 os <<
"# length: " << nf <<
"\n";
360 os <<
"# metadata: ";
361 if (std::get<bool> (m[n]))
362 os <<
"saveobj_defined";
365 string_vector keys = std::get<octave_map> (m[n]).fieldnames ();
369 std::string key = keys(i);
372 octave_value val = (std::get<octave_map> (m[n]).contents (key))(0);
392 int mdims = std::max (
static_cast<int> (
len), 2);
394 for (
int i = 0; i < mdims; i++)
398 error (
"load: failed to extract keyword 'ndims' for classdef object");
404 std::vector<std::tuple<octave_map, uint32_t, bool>> m (dv.
numel ());
409 error (
"load: failed to extract keyword 'id' for classdef object");
412 error (
"load: failed to extract keyword 'length' for classdef object");
415 error (
"load: failed to extract number of properties for classdef object");
420 std::string metadata;
422 error (
"load: failed to extract keyword 'metadata' for classdef object");
424 size_t pos = metadata.find (
"saveobj_defined");
425 std::get<bool> (m[i]) = (pos != std::string::npos);
438 std::get<octave_map> (m[i]).setfield (nm, t2);
442 error (
"load: failed to load classdef object");
451in_class_method (
const octave::cdef_class& cls)
453 octave::cdef_class ctx = octave::get_class_context ();
455 return (ctx.ok () && octave::is_superclass (ctx, cls));
458int octave_classdef::s_t_id (-1);
460const std::string octave_classdef::s_t_name (
"object");
465 s_t_id = ti.register_type (octave_classdef::s_t_name,
"<unknown>",
471 const std::list<octave_value_list>& idx,
474 std::size_t skip = 0;
477 octave::cdef_class cls = m_object.get_class ();
481 octave::cdef_method meth = cls.find_method (
"subsref");
496 if (type.back () !=
'(')
499 octave::cdef_method meth_nargout
500 = cls.find_method (
"numArgumentsFromSubscript");
502 if (meth_nargout.ok ())
506 args_nargout(0) = args(0);
507 args_nargout(1) = args(1);
511 retval = meth_nargout.execute (args_nargout, 1,
true,
512 "numArgumentsFromSubscript");
514 nargout = retval(0).strict_int_value
515 (
"subsref: return value of 'numArgumentsFromSubscript' must be integer");
533 if (type[0] !=
'.' || nout != 1 || nargout < 0)
537 else if (nargout < 0)
541 retval = meth.execute (args, nargout,
true,
"subsref");
547 if (retval.
length () > 1 && (nargout < 0 || nargout > 1))
549 if (nargout <= 0 || nargout >= retval.
length ())
563 retval = m_object.subsref (type, idx, nargout, skip, octave::cdef_class ());
565 if (type.length () > skip && idx.size () > skip)
566 retval = retval(0).next_subsref (nargout, type, idx, skip);
573 const std::list<octave_value_list>& idx,
576 std::size_t skip = 0;
583 octave::cdef_class cls = m_object.get_class ();
585 if (! in_class_method (cls))
587 octave::cdef_method meth = cls.find_method (
"subsref");
598 retval = meth.execute (args, 1,
true,
"subsref");
604 retval = m_object.subsref (type, idx, 1, skip,
605 octave::cdef_class (), auto_add);
607 if (type.length () > skip && idx.size () > skip)
608 retval = retval(0).next_subsref (1, type, idx, skip);
615 const std::list<octave_value_list>& idx,
620 octave::cdef_class cls = m_object.get_class ();
624 octave::cdef_method meth = cls.find_method (
"subsasgn");
638 retlist = meth.execute (args, 1,
true,
"subsasgn");
640 if (retlist.
empty ())
641 error (
"overloaded method 'subsasgn' did not return any value");
648 retval = m_object.subsasgn (type, idx, rhs);
655 const std::list<octave_value_list>& idx,
658 if (type.length () == 1 && type[0] ==
'(')
660 m_object = m_object.make_array ();
673 octave::cdef_class cls = m_object.get_class ();
677 octave::cdef_method meth = cls.find_method (
"size");
689 return lv(0).matrix_value ();
710 octave::cdef_class cls = m_object.get_class ();
714 octave::cdef_method meth = cls.find_method (
"numel");
728 octave::interpreter& interp = octave::__get_interpreter__ ();
729 octave::tree_evaluator& tw = interp.get_evaluator();
731 octave::unwind_action act ([&tw] (
const std::list<octave::octave_lvalue> *lvl)
733 tw.set_lvalue_list (lvl);
734 }, tw.lvalue_list ());
735 tw.set_lvalue_list (
nullptr);
739 error (
"@%s/numel: invalid return value", cls.get_name ().c_str ());
741 retval = lv(0).idx_type_value (
true);
757 octave::cdef_class cls = m_object.get_class ();
761 octave::cdef_method meth = cls.find_method (
"reshape");
767 args(0) = octave::to_ov (m_object.clone ());
772 retlist = meth.execute (args, 1,
true,
"reshape");
774 if (retlist.
empty ())
775 error (
"overloaded method 'reshape' did not return any value");
782 retval = m_object.reshape (new_dims);
796 octave::cdef_class cls = m_object.get_class ();
800 bool is_array = m_object.is_array ();
808 os << dv.
ndims () <<
"-D";
815 os <<
" with properties:";
822 std::map<octave::property_key, octave::cdef_property> property_map
823 = cls.get_property_map ();
825 std::size_t max_len = 0;
826 for (
const auto& pname_prop : property_map)
831 const octave::cdef_property& prop = pname_prop.second;
833 const std::string nm = prop.get_name ();
845 std::size_t sz = nm.
size ();
851 for (
auto& pname_prop : property_map)
853 const octave::cdef_property& prop = pname_prop.second;
855 const std::string nm = prop.get_name ();
873 os << std::setw (max_len+2) << nm <<
": ";
891 octave::cdef_class cls = octave::lookup_class (cls_name,
false,
false);
901 const std::string& cls)
909 return octave::to_ov (octave::lookup_class (cls));
917 if (m_object.is_method ())
923 octave::cdef_method meth (m_object);
925 return meth.is_defined_in_class (cname);
937 if (m_object.is_class ())
943 octave::cdef_class cls (m_object);
945 if (cls.get_name () == cname)
949 else if (m_object.is_method ())
951 octave::cdef_method meth (m_object);
953 if (meth.is_constructor ())
955 std::string meth_name = meth.get_name ();
961 if (cname == meth_name)
965 octave::cdef_class meth_cls = octave::lookup_class (meth_name,
false,
false);
966 octave::cdef_class dispatch_cls = octave::lookup_class (cname,
false,
false);
968 retval = octave::is_superclass (meth_cls, dispatch_cls);
979 if (m_object.is_class ())
981 octave::cdef_class cls (m_object);
983 if (meth_name.empty ())
984 return cls.doc_string ();
986 octave::cdef_method cdef_meth = cls.find_method (meth_name);
989 return cdef_meth.get_doc_string ();
998 if (m_object.is_class ())
1000 octave::cdef_class cls (m_object);
1002 return cls.file_name ();
1015 std::string meth_name;
1016 bool in_constructor;
1017 octave::cdef_class ctx;
1019 ctx = octave::get_class_context (meth_name, in_constructor);
1022 error (
"superclass calls can only occur in methods or constructors");
1024 std::string mname = m_method_name;
1025 std::string cname = m_class_name;
1030 octave::cdef_class cls = octave::lookup_class (cname);
1035 error (
"'%s' is not a direct superclass of '%s'",
1036 cname.c_str (), ctx.get_name ().c_str ());
1038 if (! is_constructed_object (tw, mname))
1039 error (
"cannot call superclass constructor with variable '%s'",
1044 cls.run_constructor (octave::to_cdef_ref (sym), idx);
1050 std::size_t pos = mname.find (
'.');
1052 octave::cdef_object obj;
1054 if (pos != std::string::npos)
1058 std::string oname = m_method_name.substr (0, pos);
1059 mname = mname.substr (pos + 1);
1082 if (mname != meth_name)
1083 error (
"method name mismatch ('%s' != '%s')",
1084 mname.c_str (), meth_name.c_str ());
1087 error (
"'%s' is not a superclass of '%s'",
1088 cname.c_str (), ctx.get_name ().c_str ());
1101 octave::cdef_method meth = cls.find_method (meth_name,
false);
1104 error (
"no method '%s' found in superclass '%s'",
1105 meth_name.c_str (), cname.c_str ());
1108 ? meth.execute (obj, idx, nargout,
true, meth_name)
1109 : meth.execute (idx, nargout,
true, meth_name));
1116octave_classdef_superclass_ref::is_constructed_object (octave::tree_evaluator& tw,
1117 const std::string& nm)
1127 octave::tree_parameter_list *ret_list = uf->
return_list ();
1129 if (ret_list && ret_list->size () == 1)
1130 return (ret_list->front ()->name () == nm);
1139DEFUN (__meta_get_package__, args, ,
1145 if (args.length () != 1)
1148 std::string cname = args(0).xstring_value (
"PKG_NAME must be a string");
1153DEFUN (metaclass, args, ,
1159 if (args.length () != 1)
1172DEFUN (properties, args, nargout,
1188 if (args.length () != 1)
1193 std::string class_name;
1207 error (
"invalid class: %s", class_name.c_str ());
1209 std::map<octave::property_key, cdef_property> property_map =
1212 std::list<std::string> property_names;
1214 for (
const auto& pname_prop : property_map)
1230 property_names.push_back (pname_prop.second.get_name ());
1236 octave_stdout <<
"properties for class " << class_name <<
":\n\n";
1238 for (
const auto& nm : property_names)
1266 std::string class_name;
1283 std::map<std::string, cdef_method> method_map
1286 std::list<std::string> method_names;
1288 for (
const auto& nm_mthd : method_map)
1302 method_names.push_back (nm_mthd.first);
1311 load_path& lp = interp.get_load_path ();
1314 found = ! sv.
empty ();
1317 return ovl (
Cell (sv), found);
1325OCTAVE_END_NAMESPACE(octave)
bool isvector(const dim_vector &dim)
bool is_superclass(const cdef_class &clsa, const cdef_class &clsb, bool allow_equal, int max_depth)
bool is_strict_superclass(const cdef_class &clsa, const cdef_class &clsb)
cdef_object to_cdef(const octave_value &val)
cdef_class lookup_class(const std::string &name, bool error_if_not_found, bool load_if_not_found)
octave_value to_ov(const cdef_object &obj)
cdef_package lookup_package(const std::string &name, bool error_if_not_found, bool load_if_not_found)
bool is_direct_superclass(const cdef_class &clsa, const cdef_class &clsb)
T & elem(octave_idx_type n)
Size of the specified dimension.
std::map< property_key, cdef_property > get_property_map(int mode=property_normal)
std::map< std::string, cdef_method > get_method_map(bool only_inherited=false, bool include_ctor=false)
cdef_class get_class() const
octave_value get(const std::string &pname) const
Vector representing the dimensions (size) of an Array.
std::string str(char sep='x') const
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
void resize(int n, int fill_value=0)
Array< octave_idx_type > as_array() const
octave_idx_type ndims() const
Number of dimensions.
std::list< std::string > methods(const std::string &class_name, const std::string &pack_name="")
virtual octave_idx_type numel() const
virtual bool is_scalar_type() const
void increment_indent_level() const
void indent(std::ostream &os) const
void newline(std::ostream &os) const
static void register_type()
octave::refcount< octave_idx_type > m_count
virtual octave_idx_type xnumel(const octave_value_list &)
void decrement_indent_level() const
virtual octave_user_function * user_function_value(bool silent=false)
virtual octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
friend class octave_value
virtual octave_value any(int=0) const
virtual bool is_matrix_type() const
octave_value_list execute(octave::tree_evaluator &tw, int nargout, const octave_value_list &idx)
void print(std::ostream &os, bool pr_as_read_syntax=false)
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
octave_map map_value() const
octave_value_list subsref(const std::string &type, const std::list< octave_value_list > &idx, int nargout)
octave_value reshape(const dim_vector &new_dims) const
octave::cdef_object & get_object_ref()
bool save_ascii(std::ostream &os)
bool is_instance_of(const std::string &cls_name) const
octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
octave::cdef_object get_object() const
static octave_value metaclass_query(const std::string &cls)
octave_idx_type xnumel(const octave_value_list &)
static octave_value superclass_ref(const std::string &meth, const std::string &cls)
std::string type_name() const
std::string class_name() const
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
bool load_ascii(std::istream &is)
string_vector map_keys() const
void loadobj(std::vector< std::tuple< octave_map, uint32_t, bool > > &m, dim_vector &dv)
std::vector< std::tuple< octave_map, uint32_t, bool > > saveobj(std::vector< bool > &is_new)
virtual bool is_classdef_constructor(const std::string &="") const
Cell getfield(const std::string &key) const
octave_idx_type nfields() const
string_vector fieldnames() const
const Cell & contents(const_iterator p) const
bool isfield(const std::string &name) const
octave_idx_type numel() const
octave::tree_parameter_list * return_list()
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
octave_idx_type length() const
bool is_classdef_object() const
std::string class_name() const
bool bool_value(bool warn=false) const
octave_classdef * classdef_object_value(bool silent=false) const
void short_disp(std::ostream &os) const
octave_map map_value() const
std::string string_value(bool force=false) const
std::string type_name() const
octave_idx_type numel() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#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 warning(const char *fmt,...)
void error(const char *fmt,...)
void err_wrong_type_arg(const char *name, const char *s)
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)
octave_value make_idx_args(const std::string &type, const std::list< octave_value_list > &idx, const std::string &who)
bool called_from_builtin()
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.