26#if defined (HAVE_CONFIG_H)
34#include "builtin-defun-decls.h"
61static int Vstruct_levels_to_print = 2;
65static bool Vprint_struct_array_contents =
false;
75 c(i).break_closure_cycles (frame);
97 std::string nm = idx(0).string_value ();
107 "structure has no member '%s'", nm.c_str ());
113err_invalid_index_for_assignment ()
115 error (
"invalid index for structure array assignment");
119err_invalid_index_type (
const std::string& nm,
char t)
121 error (
"%s cannot be indexed with %c", nm.c_str (), t);
125maybe_warn_invalid_field_name (
const std::string& key,
const char *who)
127 if (! octave::valid_identifier (key))
131 "%s: invalid structure field name '%s'",
135 "invalid structure field name '%s'",
142 const std::list<octave_value_list>& idx,
153 if (type.length () > 1 && type[1] ==
'.')
188 err_invalid_index_type (
type_name (), type[0]);
192 error (
"unexpected: index not '(', '{', or '.' in octave_struct::subsref - please report this bug");
200 retval = retval(0).next_subsref (nargout, type, idx, skip);
207 const std::list<octave_value_list>& idx,
218 if (type.length () > 1 && type[1] ==
'.')
224 const Cell t = tmp.
index (idx.front (), auto_add);
245 const Cell t =
dotref (idx.front (), auto_add);
256 err_invalid_index_type (
type_name (), type[0]);
260 error (
"unexpected: index not '(', '{', or '.' in octave_struct::subsref - please report this bug");
268 retval = retval.
next_subsref (auto_add, type, idx, skip);
284 const std::string& type)
288 if (type.length () > 0 && type[0] ==
'.' && ! val.
isstruct ())
298 const std::list<octave_value_list>& idx,
307 if (idx.front ().empty ())
308 error (
"subsasgn: missing index in indexed assignment");
310 if (n > 1 && ! (type.length () == 2 && type[0] ==
'(' && type[1] ==
'.'))
316 if (type.length () > 1 && type[1] ==
'.')
320 if (key_idx.
length () != 1)
321 error (
"subsasgn: dynamic structure field names must be strings");
324 = key_idx(0).xstring_value (
"subsasgn: dynamic structure field names must be strings");
326 maybe_warn_invalid_field_name (key,
"subsasgn");
328 std::list<octave_value_list> next_idx (std::next (idx.begin (), 2),
334 std::string next_type = type.substr (2);
346 if (tmpc.
numel () != 1)
363 t_rhs =(orig_undefined
365 : tmp.
subsasgn (next_type, next_idx, rhs));
368 err_invalid_index_for_assignment ();
376 if (key_idx.
length () != 1)
377 error (
"subsasgn: dynamic structure field names must be strings");
380 = key_idx(0).xstring_value (
"subsasgn: dynamic structure field names must be strings");
382 maybe_warn_invalid_field_name (key,
"subsasgn");
384 std::list<octave_value_list> next_idx (std::next (idx.begin ()),
387 std::string next_type = type.substr (1);
399 if (tmpc.
numel () == 1)
415 t_rhs = (orig_undefined
417 : tmp.
subsasgn (next_type, next_idx, rhs));
425 err_invalid_index_type (
type_name (), type[0]);
429 error (
"unexpected: index not '(', '{', or '.' in octave_struct::subsasgn - please report this bug");
437 if (n > 1 && type[1] ==
'.')
442 if (key_idx.
length () != 1)
443 error (
"subsasgn: dynamic structure field names must be strings");
446 = key_idx(0).xstring_value (
"subsasgn: dynamic structure field names must be strings");
448 maybe_warn_invalid_field_name (key,
"subsasgn");
459 didx(k) = idxf(k).numel ();
462 tmp_cell = tmp_cell.
reshape (didx);
500 error (
"invalid structure assignment");
515 if (key_idx.
length () != 1)
516 error (
"subsasgn: dynamic structure field names must be strings");
519 = key_idx(0).xstring_value (
"subsasgn: dynamic structure field names must be strings");
521 maybe_warn_invalid_field_name (key,
"subsasgn");
544 err_invalid_index_type (
type_name (), type[0]);
548 error (
"unexpected: index not '(', '{', or '.' in octave_struct::subsasgn - please report this bug");
588 std::size_t retval = 0;
611 octave::unwind_protect_var<int> restore_var (Vstruct_levels_to_print);
613 if (Vstruct_levels_to_print >= 0)
615 bool max_depth_reached = (Vstruct_levels_to_print-- == 0);
617 bool print_fieldnames_only = (max_depth_reached
618 || ! Vprint_struct_array_contents);
624 os << dv.
str () <<
" struct array containing the fields:";
633 std::string key = key_list[i];
640 if (print_fieldnames_only)
652 if (print_fieldnames_only)
673 if (Vstruct_levels_to_print < 0)
691 return dims.
ndims () == 2 && dims(0) == 1 && dims(1) == 1;
717 std::string dimstr = dv.
str ();
718 return "[" + dimstr +
" " + tname +
"]";
731 os <<
"# ndims: " << dv.
ndims () <<
"\n";
733 for (
int i = 0; i < dv.
ndims (); i++)
737 os <<
"# length: " << nf <<
"\n";
745 std::string key = keys(i);
770 keywords[0] =
"ndims";
771 keywords[1] =
"length";
777 if (kw == keywords[0])
779 int mdims = std::max (
static_cast<int> (
len), 2);
781 for (
int i = 0; i < mdims; i++)
790 if (! success ||
len < 0)
791 error (
"load: failed to extract number of elements in structure");
815 error (
"load: failed to load structure");
822 error (
"unexpected: len < 0 in octave_struct::load_ascii - please report this bug");
839 int32_t di = - dv.
ndims ();
840 os.write (
reinterpret_cast<char *
> (&di), 4);
841 for (
int i = 0; i < dv.
ndims (); i++)
844 os.write (
reinterpret_cast<char *
> (&di), 4);
848 os.write (
reinterpret_cast<char *
> (&
len), 4);
856 std::string key = keys(i);
871 octave::mach_info::float_format fmt)
875 if (! is.read (
reinterpret_cast<char *
> (&
len), 4))
890 for (
int i = 0; i < mdims; i++)
892 if (! is.read (
reinterpret_cast<char *
> (&di), 4))
899 if (! is.read (
reinterpret_cast<char *
> (&
len), 4))
929 error (
"load: failed to load structure");
945#if defined (HAVE_HDF5)
949#if defined (HAVE_HDF5_18)
953 data_hid = H5Gcreate (loc_id, name, 0);
955 if (data_hid < 0)
return false;
968 std::string key = keys(i);
984 octave_unused_parameter (loc_id);
985 octave_unused_parameter (name);
986 octave_unused_parameter (save_as_floats);
999#if defined (HAVE_HDF5)
1005 int current_item = 0;
1006 hsize_t num_obj = 0;
1007#if defined (HAVE_HDF5_18)
1010 hid_t group_id = H5Gopen (loc_id, name);
1012 H5Gget_num_objs (group_id, &num_obj);
1013 H5Gclose (group_id);
1018 while (current_item <
static_cast<int> (num_obj)
1038 octave_unused_parameter (loc_id);
1039 octave_unused_parameter (name);
1055 for (
int i = 0; i < nf; i++)
1056 f[i] = kv[i].c_str ();
1062 mwSize nel =
numel ();
1064 mwSize ntot = nf * nel;
1066 for (
int i = 0; i < nf; i++)
1073 for (mwIndex j = i; j < ntot; j += nf)
1074 elts[j] =
new mxArray (interleaved, p[k++]);
1093 bool retval =
false;
1100 void *here =
reinterpret_cast<void *
> (&sm_ptr);
1101 return (
x.get_rep ().fast_elem_insert_self (here,
btyp_struct)
1125 std::string nm = idx(0).string_value ();
1127 maybe_warn_invalid_field_name (nm,
"subsref");
1133 "structure has no member '%s'", nm.c_str ());
1140 const std::list<octave_value_list>& idx)
1148 retval =
dotref (idx.front ());
1150 if (idx.size () > 1)
1154 retval = to_array ().
subsref (type, idx);
1161 const std::list<octave_value_list>& idx,
1170 retval(0) =
dotref (idx.front ());
1172 if (idx.size () > 1)
1173 retval = retval(0).next_subsref (nargout, type, idx, skip);
1176 retval = to_array ().
subsref (type, idx, nargout);
1183 const std::list<octave_value_list>& idx,
1192 retval =
dotref (idx.front (), auto_add);
1194 if (idx.size () > 1)
1195 retval = retval.
next_subsref (auto_add, type, idx, skip);
1198 retval = to_array ().
subsref (type, idx, auto_add);
1214 const std::string& type)
1218 if (type.length () > 0 && type[0] ==
'.' && ! val.
isstruct ())
1228 const std::list<octave_value_list>& idx,
1233 if (idx.front ().empty ())
1234 error (
"subsasgn: missing index in indexed assignment");
1238 int n = type.length ();
1244 if (key_idx.
length () != 1)
1245 error (
"subsasgn: structure field names must be strings");
1248 = key_idx(0).xstring_value (
"subsasgn: structure field names must be strings");
1250 maybe_warn_invalid_field_name (key,
"subsasgn");
1254 std::list<octave_value_list> next_idx (std::next (idx.begin ()),
1257 std::string next_type = type.substr (1);
1278 t_rhs = (orig_undefined
1280 : tmp.
subsasgn (next_type, next_idx, rhs));
1292 retval = tmp.
subsasgn (type, idx, rhs);
1324 std::size_t retval = 0;
1347 octave::unwind_protect_var<int> restore_var (Vstruct_levels_to_print);
1349 if (Vstruct_levels_to_print >= 0)
1351 bool max_depth_reached = (Vstruct_levels_to_print-- == 0);
1353 bool print_fieldnames_only = max_depth_reached;
1362 std::string key = key_list[i];
1366 if (print_fieldnames_only)
1384 os <<
"<structure>";
1391 const std::string& name)
const
1393 bool retval =
false;
1397 if (Vstruct_levels_to_print < 0)
1398 os << name <<
" = ";
1409 os <<
"scalar structure containing the fields:";
1432 std::string dimstr = dv.
str ();
1433 return "[" + dimstr +
" " + tname +
"]";
1445 os <<
"# ndims: " << dv.
ndims () <<
"\n";
1447 for (
int i = 0; i < dv.
ndims (); i++)
1451 os <<
"# length: " << nf <<
"\n";
1459 std::string key = keys(i);
1466 return ! os.fail ();
1478 error (
"load: failed to extract number of elements in structure");
1500 error (
"load: failed to load structure");
1507 error (
"unexpected: len < 0 in octave_scalar_struct::load_ascii - please report this bug");
1520 os.write (
reinterpret_cast<char *
> (&
len), 4);
1528 std::string key = keys(i);
1535 return ! os.fail ();
1543 octave::mach_info::float_format fmt)
1545 bool success =
true;
1547 if (! is.read (
reinterpret_cast<char *
> (&
len), 4))
1573 error (
"load: failed to load structure");
1587 bool save_as_floats)
1589#if defined (HAVE_HDF5)
1591 hid_t data_hid = -1;
1593#if defined (HAVE_HDF5_18)
1597 data_hid = H5Gcreate (loc_id, name, 0);
1599 if (data_hid < 0)
return false;
1612 std::string key = keys(i);
1616 bool retval2 =
add_hdf5_data (data_hid, val, key,
"",
false,
1623 H5Gclose (data_hid);
1628 octave_unused_parameter (loc_id);
1629 octave_unused_parameter (name);
1630 octave_unused_parameter (save_as_floats);
1641 bool retval =
false;
1643#if defined (HAVE_HDF5)
1649 int current_item = 0;
1650 hsize_t num_obj = 0;
1651#if defined (HAVE_HDF5_18)
1654 hid_t group_id = H5Gopen (loc_id, name);
1656 H5Gget_num_objs (group_id, &num_obj);
1657 H5Gclose (group_id);
1662 while (current_item <
static_cast<int> (num_obj)
1679 octave_unused_parameter (loc_id);
1680 octave_unused_parameter (name);
1696 for (
int i = 0; i < nf; i++)
1697 f[i] = kv[i].c_str ();
1703 mwSize nel =
numel ();
1705 mwSize ntot = nf * nel;
1707 for (
int i = 0; i < nf; i++)
1714 for (mwIndex j = i; j < ntot; j += nf)
1715 elts[j] =
new mxArray (interleaved, p[k++]);
1722octave_scalar_struct::to_array ()
1743DEFUN (
struct, args, ,
1801 int nargin = args.length ();
1811 if (nargin == 1 && args(0).isstruct ())
1812 return ovl (args(0));
1814 if (nargin == 1 && args(0).isobject ())
1815 return ovl (args(0).map_value ());
1817 if ((nargin == 1 || nargin == 2)
1818 && args(0).isempty () && args(0).is_real_matrix ()
1819 && ! args(0).is_char_matrix ())
1823 Array<std::string> cstr = args(1).xcellstr_value (
"struct: second argument should be a cell array of field names");
1833 for (
int i = 0; i < nargin; i += 2)
1835 if (! args(i).is_string () || i + 1 >= nargin)
1836 error (R
"(struct: additional arguments must occur as "field", VALUE pairs)");
1843 int first_dimensioned_value = 0;
1845 for (
int i = 1; i < nargin; i += 2)
1847 if (args(i).iscell ())
1851 if (! scalar (argdims))
1853 if (! first_dimensioned_value)
1856 first_dimensioned_value = i + 1;
1858 else if (dims != argdims)
1860 error (
"struct: dimensions of parameter %d "
1861 "do not match those of parameter %d",
1862 first_dimensioned_value, i+1);
1872 for (
int i = 0; i < nargin; i+= 2)
1876 std::string key (args(i).string_value ());
1878 maybe_warn_invalid_field_name (key,
"struct");
1886 if (args(i+1).iscell ())
1888 const Cell c (args(i+1).cell_value ());
1890 if (scalar (c.
dims ()))
1928DEFUN (isstruct, args, ,
1935 if (args.length () != 1)
1938 return ovl (args(0).isstruct ());
1941DEFUN (__fieldnames__, args, ,
1961 retval =
Cell (0, 1);
1963 retval =
Cell (keys);
1968DEFUN (isfield, args, ,
1980 if (args.length () != 2)
1985 if (args(0).isstruct ())
1991 if (args(1).is_string ())
1993 std::string key = args(1).string_value ();
1997 else if (args(1).iscell ())
1999 Cell c = args(1).cell_value ();
2005 if (c(i).is_string ())
2007 std::string key = c(i).string_value ();
2022DEFUN (numfields, args, ,
2029 if (args.length () != 1)
2032 if (! args(0).isstruct ())
2033 error (
"numfields: argument must be a struct");
2035 return ovl (
static_cast<double> (args(0).nfields ()));
2052invalid_cell2struct_fields_error ()
2054 error (
"cell2struct: FIELDS must be a cell array of strings or a scalar string");
2062 if (arg.
rows () > 1)
2063 invalid_cell2struct_fields_error ();
2079 invalid_cell2struct_fields_error ();
2081 retval(i) = c(i).string_value ();
2087 invalid_cell2struct_fields_error ();
2090DEFUN (cell2struct, args, ,
2118 int nargin = args.length ();
2120 if (nargin < 2 || nargin > 3)
2123 const Cell vals = args(0).xcell_value (
"cell2struct: argument CELL must be of type cell");
2131 if (! args(2).is_real_scalar ())
2132 error (
"cell2struct: DIM must be a real scalar");
2134 dim = args(2).int_value () - 1;
2138 error (
"cell2struct: DIM must be a valid dimension");
2142 if (ext != fields.
numel ())
2143 error (
"cell2struct: number of FIELDS does not match dimension");
2145 int nd = std::max (dim+1, vals.
ndims ());
2152 rdv(0) = rdv(1-dim);
2157 for (
int i = dim + 1; i < nd; i++)
2200DEFUN (rmfield, args, ,
2212 if (args.length () != 2)
2215 octave_map m = args(0).xmap_value (
"rmfield: first argument must be a struct");
2221 for (
int i = 0; i < fcell.
numel (); i++)
2223 std::string key = fcell(i).string_value ();
2226 error (
"rmfield: structure does not contain field %s", key.c_str ());
2249DEFUN (struct_levels_to_print, args, nargout,
2264 "struct_levels_to_print", -1,
2265 std::numeric_limits<int>::max ());
2268DEFUN (print_struct_array_contents, args, nargout,
2288 "print_struct_array_contents");
2291OCTAVE_END_NAMESPACE(octave)
void swap_bytes< 4 >(void *ptr)
N Dimensional Array with copy-on-write semantics.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
int ndims() const
Size of the specified dimension.
const T * data() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
Cell reshape(const dim_vector &new_dims) const
Cell index(const octave_value_list &idx, bool resize_ok=false) 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)
octave_idx_type ndims() const
Number of dimensions.
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
void increment_indent_level() const
void indent(std::ostream &os) const
void newline(std::ostream &os) const
octave::refcount< octave_idx_type > m_count
void warn_load(const char *type) const
virtual bool is_magic_colon() const
void decrement_indent_level() const
friend class octave_value
void warn_save(const char *type) const
const_iterator cbegin() const
void rmfield(const std::string &key)
octave_idx_type nfields() const
const_iterator end() const
octave_idx_type rows() const
octave_scalar_map checkelem(octave_idx_type n) const
string_vector fieldnames() const
octave_fields::const_iterator const_iterator
octave_idx_type columns() const
const Cell & contents(const_iterator p) const
bool isfield(const std::string &name) const
void delete_elements(const octave::idx_vector &i)
void setfield(const std::string &key, const Cell &val)
octave_idx_type numel() const
const_iterator seek(const std::string &k) const
void assign(const std::string &k, const Cell &val)
std::string key(const_iterator p) const
bool fast_elem_insert(octave_idx_type n, const octave_scalar_map &rhs)
const_iterator cend() const
octave_idx_type index(const_iterator p) const
const octave_value & contents(const_iterator p) const
const_iterator cend() const
const_iterator cbegin() const
const_iterator end() const
string_vector fieldnames() const
void setfield(const std::string &key, const octave_value &val)
const_iterator seek(const std::string &k) const
octave_idx_type nfields() const
octave_value getfield(const std::string &key) const
std::string key(const_iterator p) const
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
octave_idx_type nfields() const
bool print_name_tag(std::ostream &os, const std::string &name) const
mxArray * as_mxArray(bool interleaved) const
static octave_value numeric_conv(const octave_value &val, const std::string &type)
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
bool load_ascii(std::istream &is)
void print(std::ostream &os, bool pr_as_read_syntax=false)
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
octave_value dotref(const octave_value_list &idx, bool auto_add=false)
octave_map map_value() const
bool save_binary(std::ostream &os, bool save_as_floats)
bool save_ascii(std::ostream &os)
bool fast_elem_insert_self(void *where, builtin_type_t btyp) const
std::size_t byte_size() const
octave_scalar_map scalar_map_value() const
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
void break_closure_cycles(const std::shared_ptr< octave::stack_frame > &frame)
string_vector map_keys() const
std::string edit_display(const float_display_format &fmt, octave_idx_type i, octave_idx_type j) const
octave_idx_type numel() const
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
string_vector map_keys() const
bool fast_elem_insert(octave_idx_type n, const octave_value &x)
octave_idx_type numel() const
static octave_value numeric_conv(const octave_value &val, const std::string &type)
bool load_ascii(std::istream &is)
std::string edit_display(const float_display_format &fmt, octave_idx_type i, octave_idx_type j) const
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
mxArray * as_mxArray(bool interleaved) const
bool save_ascii(std::ostream &os)
octave_map map_value() const
std::string type_name() const
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
std::size_t byte_size() const
octave_idx_type nfields() const
void break_closure_cycles(const std::shared_ptr< octave::stack_frame > &frame)
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
bool print_name_tag(std::ostream &os, const std::string &name) const
octave_value fast_elem_extract(octave_idx_type n) const
octave_base_value * try_narrowing_conversion()
bool save_binary(std::ostream &os, bool save_as_floats)
Cell dotref(const octave_value_list &idx, bool auto_add=false)
void print(std::ostream &os, bool pr_as_read_syntax=false)
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
octave_idx_type length() const
bool isfield(const std::string &field_name) const
octave_value_list list_value() const
bool is_undefined() const
Cell xcell_value(const char *fmt,...) const
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
octave_map xmap_value(const char *fmt,...) const
void print_with_name(std::ostream &os, const std::string &name) const
octave_idx_type rows() const
octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
static octave_value empty_conv(const std::string &type, const octave_value &rhs=octave_value())
octave_value next_subsref(const std::string &type, const std::list< octave_value_list > &idx, std::size_t skip=1)
void break_closure_cycles(const std::shared_ptr< octave::stack_frame > &)
octave_value storable_value() const
bool is_zero_by_zero() const
octave_map map_value() const
std::string string_value(bool force=false) const
octave_idx_type length() const
std::string type_name() const
std::size_t byte_size() const
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
octave_idx_type numel() const
const octave_hdf5_id octave_H5P_DEFAULT
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error_with_id(const char *id, const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void warn_empty_index(const std::string &type_name)
void err_indexed_cs_list()
void err_nonbraced_cs_list_assignment()
bool add_hdf5_data(octave_hdf5_id loc_id, const octave_value &tc_in, const std::string &name, const std::string &doc, bool mark_global, bool save_as_floats)
octave_hdf5_err hdf5_h5g_iterate(octave_hdf5_id loc_id, const char *name, int *idx, void *operator_data)
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_in, 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)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
octave_value_list Fcellstr(const octave_value_list &args, int)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
#define panic_unless(cond)
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)