77 assert (idx.
length () == 1);
79 std::string nm = idx(0).string_value ();
89 "structure has no member '%s'", nm.c_str ());
98 error (
"invalid index for structure array");
105 error (
"invalid index for structure array assignment");
111 error (
"%s cannot be indexed with %c", nm.c_str (), t);
117 error (
"assignment to structure element failed");
127 "%s: invalid structure field name '%s'",
131 "invalid structure field name '%s'",
138 const std::list<octave_value_list>& idx,
149 if (type.length () > 1 && type[1] ==
'.')
151 std::list<octave_value_list>::const_iterator p = idx.begin ();
197 retval = retval(0).next_subsref (nargout, type, idx, skip);
204 const std::list<octave_value_list>& idx,
215 if (type.length () > 1 && type[1] ==
'.')
217 std::list<octave_value_list>::const_iterator p = idx.begin ();
224 const Cell t = tmp.
index (idx.front (), auto_add);
243 const Cell t =
dotref (idx.front (), auto_add);
263 retval = retval.next_subsref (auto_add, type, idx, skip);
279 const std::string& type)
283 if (type.length () > 0 && type[0] ==
'.' && ! val.
is_map ())
293 const std::list<octave_value_list>& idx,
302 if (idx.front ().empty ())
304 error (
"missing index in indexed assignment");
308 if (n > 1 && ! (type.length () == 2 && type[0] ==
'(' && type[1] ==
'.'))
314 if (type.length () > 1 && type[1] ==
'.')
316 std::list<octave_value_list>::const_iterator p = idx.begin ();
321 assert (key_idx.
length () == 1);
323 std::string key = key_idx(0).string_value ();
330 std::list<octave_value_list> next_idx (idx);
335 next_idx.erase (next_idx.begin ());
336 next_idx.erase (next_idx.begin ());
338 std::string next_type = type.substr (2);
352 if (tmpc.
numel () == 1)
372 : tmp.
subsasgn (next_type, next_idx, rhs));
387 assert (key_idx.
length () == 1);
389 std::string key = key_idx(0).string_value ();
396 std::list<octave_value_list> next_idx (idx);
398 next_idx.erase (next_idx.begin ());
400 std::string next_type = type.substr (1);
413 if (tmpc.
numel () == 1)
430 t_rhs = (orig_undefined
432 : tmp.
subsasgn (next_type, next_idx, rhs));
455 if (n > 1 && type[1] ==
'.')
457 std::list<octave_value_list>::const_iterator p = idx.begin ();
461 assert (key_idx.
length () == 1);
463 std::string key = key_idx(0).string_value ();
480 if (! idxf(k).is_magic_colon ())
481 didx(k) = idxf(k).numel ();
483 if (didx.numel () == tmp_cell.
numel ())
484 tmp_cell = tmp_cell.
reshape (didx);
542 error (
"invalid structure assignment");
559 error (
"invalid structure assignment");
569 assert (key_idx.
length () == 1);
571 std::string key = key_idx(0).string_value ();
640 std::string key =
map.
key (p);
663 if (Vstruct_levels_to_print >= 0)
665 bool max_depth_reached = Vstruct_levels_to_print-- == 0;
667 bool print_fieldnames_only
675 os << dv.
str () <<
" struct array containing the fields:";
684 std::string key = key_list[i];
690 if (print_fieldnames_only)
702 if (print_fieldnames_only)
723 if (Vstruct_levels_to_print < 0)
738 return dims.
length () == 2 && dims (0) == 1 && dims (1) == 1;
751 os <<
"# ndims: " << dv.
length () <<
"\n";
753 for (
int i = 0; i < dv.
length (); i++)
757 os <<
"# length: " << nf <<
"\n";
765 std::string key = keys(i);
790 keywords[0] =
"ndims";
791 keywords[1] =
"length";
797 if (kw == keywords[0])
799 int mdims =
std::max (static_cast<int> (len), 2);
801 for (
int i = 0; i < mdims; i++)
810 if (success && len >= 0)
832 error (
"load: internal error loading struct elements");
843 error (
"load: failed to load structure");
854 error (
"load: failed to extract number of elements in structure");
873 int32_t di = - d.
length ();
874 os.write (reinterpret_cast<char *> (&di), 4);
875 for (
int i = 0; i < d.
length (); i++)
878 os.write (reinterpret_cast<char *> (&di), 4);
882 os.write (reinterpret_cast<char *> (&len), 4);
890 std::string key = keys(i);
909 if (! is.read (reinterpret_cast<char *> (&len), 4))
924 for (
int i = 0; i < mdims; i++)
926 if (! is.read (reinterpret_cast<char *> (&di), 4))
933 if (! is.read (reinterpret_cast<char *> (&len), 4))
960 error (
"load: internal error loading struct elements");
971 error (
"load: failed to load structure");
983 #if defined (HAVE_HDF5)
991 data_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
993 data_hid = H5Gcreate (loc_id, name, 0);
995 if (data_hid < 0)
return false;
1008 std::string key = keys(i);
1012 bool retval2 =
add_hdf5_data (data_hid, val, key,
"",
false,
1019 H5Gclose (data_hid);
1027 bool retval =
false;
1033 int current_item = 0;
1034 hsize_t num_obj = 0;
1036 hid_t group_id = H5Gopen (loc_id, name, H5P_DEFAULT);
1038 hid_t group_id = H5Gopen (loc_id, name);
1040 H5Gget_num_objs (group_id, &num_obj);
1041 H5Gclose (group_id);
1046 while (current_item < static_cast<int> (num_obj)
1047 && (retval2 = H5Giterate (loc_id, name, ¤t_item,
1056 error (
"load: internal error loading struct elements");
1083 for (
int i = 0; i < nf; i++)
1084 f[i] = kv[i].c_str ();
1094 for (
int i = 0; i < nf; i++)
1101 for (
mwIndex j = i; j < ntot; j += nf)
1102 elts[j] =
new mxArray (p[k++]);
1121 bool retval =
false;
1128 void *here =
reinterpret_cast<void *
>(&sm_ptr);
1145 assert (idx.
length () == 1);
1147 std::string nm = idx(0).string_value ();
1158 "structure has no member '%s'", nm.c_str ());
1165 const std::list<octave_value_list>& idx)
1173 retval =
dotref (idx.front ());
1175 if (idx.size () > 1)
1186 const std::list<octave_value_list>& idx,
1195 retval(0) =
dotref (idx.front ());
1197 if (idx.size () > 1)
1198 retval = retval(0).next_subsref (nargout, type, idx, skip);
1208 const std::list<octave_value_list>& idx,
1217 retval =
dotref (idx.front (), auto_add);
1219 if (idx.size () > 1)
1220 retval = retval.
next_subsref (auto_add, type, idx, skip);
1239 const std::string& type)
1243 if (type.length () > 0 && type[0] ==
'.' && ! val.
is_map ())
1253 const std::list<octave_value_list>& idx,
1258 if (idx.front ().empty ())
1260 error (
"missing index in indexed assignment");
1272 assert (key_idx.
length () == 1);
1274 std::string key = key_idx(0).string_value ();
1283 std::list<octave_value_list> next_idx (idx);
1285 next_idx.erase (next_idx.begin ());
1287 std::string next_type = type.substr (1);
1311 t_rhs = (orig_undefined
1313 : tmp.
subsasgn (next_type, next_idx, rhs));
1329 retval = tmp.
subsasgn (type, idx, rhs);
1351 std::string key =
map.
key (p);
1374 if (Vstruct_levels_to_print >= 0)
1376 bool max_depth_reached = Vstruct_levels_to_print-- == 0;
1378 bool print_fieldnames_only = max_depth_reached;
1386 os <<
"scalar structure containing the fields:";
1397 std::string key = key_list[i];
1401 if (print_fieldnames_only)
1419 os <<
"<structure>";
1426 const std::string& name)
const
1428 bool retval =
false;
1432 if (Vstruct_levels_to_print < 0)
1433 os << name <<
" = ";
1453 os <<
"# ndims: " << dv.
length () <<
"\n";
1455 for (
int i = 0; i < dv.
length (); i++)
1456 os <<
" " << dv (i);
1459 os <<
"# length: " << nf <<
"\n";
1467 std::string key = keys(i);
1483 bool success =
true;
1506 error (
"load: internal error loading struct elements");
1517 error (
"load: failed to load structure");
1528 error (
"load: failed to extract number of elements in structure");
1543 os.write (reinterpret_cast<char *> (&len), 4);
1551 std::string key = keys(i);
1568 bool success =
true;
1570 if (! is.read (reinterpret_cast<char *> (&len), 4))
1596 error (
"load: internal error loading struct elements");
1607 error (
"load: failed to load structure");
1619 #if defined (HAVE_HDF5)
1623 bool save_as_floats)
1625 hid_t data_hid = -1;
1628 data_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1630 data_hid = H5Gcreate (loc_id, name, 0);
1632 if (data_hid < 0)
return false;
1645 std::string key = keys(i);
1649 bool retval2 =
add_hdf5_data (data_hid, val, key,
"",
false,
1656 H5Gclose (data_hid);
1664 bool retval =
false;
1670 int current_item = 0;
1671 hsize_t num_obj = 0;
1673 hid_t group_id = H5Gopen (loc_id, name, H5P_DEFAULT);
1675 hid_t group_id = H5Gopen (loc_id, name);
1677 H5Gget_num_objs (group_id, &num_obj);
1678 H5Gclose (group_id);
1683 while (current_item < static_cast<int> (num_obj)
1684 && (retval2 = H5Giterate (loc_id, name, ¤t_item,
1691 error (
"load: internal error loading struct elements");
1718 for (
int i = 0; i < nf; i++)
1719 f[i] = kv[i].c_str ();
1729 for (
int i = 0; i < nf; i++)
1736 for (
mwIndex j = i; j < ntot; j += nf)
1737 elts[j] =
new mxArray (p[k++]);
1766 @deftypefn {Built-in Function} {} struct (@var{field1}, @var{value1}, @var{field2}, @var{value2}, @dots{})\n\
1768 Create a scalar or array structure and initialize its values. The\n\
1769 @var{field1}, @var{field2}, @dots{} variables are strings giving the\n\
1770 names of the fields and the @var{value1}, @var{value2}, @dots{}\n\
1771 variables can be any type.\n\
1773 If the values are cell arrays, create a structure array and initialize\n\
1774 its values. The dimensions of each cell array of values must match.\n\
1775 Singleton cells and non-cell values are repeated so that they fill\n\
1776 the entire array. If the cells are empty, create an empty structure\n\
1777 array with the specified field names.\n\
1779 If the argument is an object, return the underlying struct.\n\
1781 Observe that the syntax is optimized for struct @strong{arrays}. Consider\n\
1782 the following examples:\n\
1786 struct (\"foo\", 1)\n\
1787 @result{} scalar structure containing the fields:\n\
1790 struct (\"foo\", @{@})\n\
1791 @result{} 0x0 struct array containing the fields:\n\
1794 struct (\"foo\", @{ @{@} @})\n\
1795 @result{} scalar structure containing the fields:\n\
1798 struct (\"foo\", @{1, 2, 3@})\n\
1799 @result{} 1x3 struct array containing the fields:\n\
1806 The first case is an ordinary scalar struct, one field, one value. The\n\
1807 second produces an empty struct array with one field and no values, since\n\
1808 s being passed an empty cell array of struct array values. When the value is\n\
1809 a cell array containing a single entry, this becomes a scalar struct with\n\
1810 that single entry as the value of the field. That single entry happens\n\
1811 to be an empty cell array.\n\
1813 Finally, if the value is a non-scalar cell array, then @code{struct}\n\
1814 produces a struct @strong{array}.\n\
1819 int nargin = args.
length ();
1829 if (nargin == 1 && args(0).is_map ())
1832 if (nargin == 1 && args(0).is_object ())
1839 if ((nargin == 1 || nargin == 2)
1840 && args(0).is_empty () && args(0).is_real_matrix ())
1846 if (args(1).is_cellstr ())
1847 retval =
octave_map (args(0).dims (), args(1).cellstr_value ());
1849 error (
"struct: expecting cell array of field names as second argument");
1859 for (
int i = 0; i < nargin; i += 2)
1861 if (! args(i).is_string () || i + 1 >= nargin)
1863 error (
"struct: expecting alternating \"field\", VALUE pairs");
1872 int first_dimensioned_value = 0;
1874 for (
int i = 1; i < nargin; i += 2)
1876 if (args(i).is_cell ())
1882 if (! first_dimensioned_value)
1885 first_dimensioned_value = i + 1;
1887 else if (dims != argdims)
1889 error (
"struct: dimensions of parameter %d do not match those of parameter %d",
1890 first_dimensioned_value, i+1);
1901 for (
int i = 0; i < nargin; i+= 2)
1905 std::string key (args(i).string_value ());
1921 if (args(i+1).is_cell ())
1923 const Cell c (args(i+1).cell_value ());
1965 @deftypefn {Built-in Function} {} isstruct (@var{x})\n\
1966 Return true if @var{x} is a structure or a structure array.\n\
1967 @seealso{ismatrix, iscell, isa}\n\
1972 if (args.length () == 1)
1973 retval = args(0).
is_map ();
1982 @deftypefn {Built-in Function} {} __fieldnames__ (@var{struct})\n\
1983 @deftypefnx {Built-in Function} {} __fieldnames__ (@var{obj})\n\
1984 Internal function.\n\
1986 Implements @code{fieldnames()} for structures and Octave objects.\n\
1987 @seealso{fieldnames}\n\
2000 retval =
Cell (0, 1);
2002 retval =
Cell (keys);
2009 @deftypefn {Built-in Function} {} isfield (@var{x}, @var{name})\n\
2010 Return true if the @var{x} is a structure and it\n\
2011 includes an element named @var{name}. If @var{name} is a cell\n\
2012 array of strings then a logical array of equal dimension is returned.\n\
2017 int nargin = args.
length ();
2023 if (args(0).is_map ())
2030 if (args(1).is_string ())
2032 std::string key = args(1).string_value ();
2036 else if (args(1).is_cell ())
2038 Cell c = args(1).cell_value ();
2044 if (c(i).is_string ())
2046 std::string key = c(i).string_value ();
2066 @deftypefn {Built-in Function} {} nfields (@var{s})\n\
2067 Return the number of fields of the structure @var{s}.\n\
2072 int nargin = args.
length ();
2074 if (nargin == 1 && args(0).is_map ())
2076 retval =
static_cast<double> (args(0).nfields ());
2098 @deftypefn {Built-in Function} {} cell2struct (@var{cell}, @var{fields}, @var{dim})\n\
2099 Convert @var{cell} to a structure. The number of fields in @var{fields}\n\
2100 must match the number of elements in @var{cell} along dimension @var{dim},\n\
2101 that is @code{numel (@var{fields}) == size (@var{cell}, @var{dim})}.\n\
2102 If @var{dim} is omitted, a value of 1 is assumed.\n\
2106 A = cell2struct (@{\"Peter\", \"Hannah\", \"Robert\";\n\
2108 @{\"Name\",\"Height\"@}, 1);\n\
2122 int nargin = args.
length ();
2124 if (nargin == 2 || nargin == 3)
2126 if (! args(0).is_cell ())
2128 error (
"cell2struct: argument CELL must be of type cell");
2132 if (! (args(1).is_cellstr () || args(1).is_char_matrix ()))
2134 error (
"cell2struct: FIELDS must be a cell array of strings or a character matrix");
2138 const Cell vals = args(0).cell_value ();
2147 if (args(2).is_real_scalar ())
2149 dim = nargin == 2 ? 0 : args(2).int_value () - 1;
2156 error (
"cell2struct: DIM must be a real scalar");
2163 error (
"cell2struct: DIM must be a valid dimension");
2167 ext = vals.
ndims () > dim ? vals.
dims ()(dim) : 1;
2169 if (ext != fields.
numel ())
2171 error (
"cell2struct: number of FIELDS does not match dimension");
2179 assert (ext == rdv(dim));
2182 rdv(0) = rdv(1-dim);
2187 for (
int i = dim + 1; i < nd; i++)
2232 @deftypefn {Built-in Function} {@var{s} =} rmfield (@var{s}, \"@var{f}\")\n\
2233 @deftypefnx {Built-in Function} {@var{s} =} rmfield (@var{s}, @var{f})\n\
2234 Return a copy of the structure (array) @var{s} with the field @var{f}\n\
2235 removed. If @var{f} is a cell array of strings or a character array, remove\n\
2236 each of the named fields.\n\
2237 @seealso{cellstr, iscellstr, setfield}\n\
2242 int nargin = args.
length ();
2254 for (
int i = 0; i < fcell.
numel (); i++)
2256 std::string key = fcell(i).string_value ();
2262 error (
"rmfield: structure does not contain field %s",
2294 DEFUN (struct_levels_to_print, args, nargout,
2296 @deftypefn {Built-in Function} {@var{val} =} struct_levels_to_print ()\n\
2297 @deftypefnx {Built-in Function} {@var{old_val} =} struct_levels_to_print (@var{new_val})\n\
2298 @deftypefnx {Built-in Function} {} struct_levels_to_print (@var{new_val}, \"local\")\n\
2299 Query or set the internal variable that specifies the number of\n\
2300 structure levels to display.\n\
2302 When called from inside a function with the @qcode{\"local\"} option, the\n\
2303 variable is changed locally for the function and any subroutines it calls. \n\
2304 The original variable value is restored when exiting the function.\n\
2311 DEFUN (print_struct_array_contents, args, nargout,
2313 @deftypefn {Built-in Function} {@var{val} =} print_struct_array_contents ()\n\
2314 @deftypefnx {Built-in Function} {@var{old_val} =} print_struct_array_contents (@var{new_val})\n\
2315 @deftypefnx {Built-in Function} {} print_struct_array_contents (@var{new_val}, \"local\")\n\
2316 Query or set the internal variable that specifies whether to print struct\n\
2317 array contents. If true, values of struct array elements are printed.\n\
2318 This variable does not affect scalar structures. Their elements\n\
2319 are always printed. In both cases, however, printing will be limited to\n\
2320 the number of levels specified by @var{struct_levels_to_print}.\n\
2322 When called from inside a function with the @qcode{\"local\"} option, the\n\
2323 variable is changed locally for the function and any subroutines it calls. \n\
2324 The original variable value is restored when exiting the function.\n\