3Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
6This file is part of Octave.
8Octave is free software; you can redistribute it and/or modify it
9under the terms of the GNU General Public License as published by the
10Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
13Octave is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18You should have received a copy of the GNU General Public License
19along with Octave; see the file COPYING. If not, see
20<http://www.gnu.org/licenses/>.
34#include "Array-util.h"
38#include "oct-locbuf.h"
44#include "unwind-prot.h"
46#include "ov-base-mat.h"
47#include "ov-base-mat.cc"
54#include "ls-oct-ascii.h"
55#include "ls-oct-binary.h"
59// Cell is able to handle octave_value indexing by itself, so just forward
64octave_base_matrix<Cell>::do_index_op (const octave_value_list& idx,
67 return matrix.index (idx, resize_ok);
72octave_base_matrix<Cell>::assign (const octave_value_list& idx, const Cell& rhs)
74 matrix.assign (idx, rhs);
79octave_base_matrix<Cell>::assign (const octave_value_list& idx, octave_value rhs)
83 matrix.assign (idx, rhs.cell_value ());
85 matrix.assign (idx, Cell (rhs));
90octave_base_matrix<Cell>::delete_elements (const octave_value_list& idx)
92 matrix.delete_elements (idx);
95template class octave_base_matrix<Cell>;
97DEFINE_OCTAVE_ALLOCATOR (octave_cell);
99DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cell, "cell", "cell");
102gripe_failed_assignment (void)
104 error ("assignment to cell array failed");
108octave_cell::subsref (const std::string& type,
109 const std::list<octave_value_list>& idx,
112 octave_value_list retval;
117 retval(0) = do_index_op (idx.front ());
122 octave_value tmp = do_index_op (idx.front ());
126 Cell tcell = tmp.cell_value ();
128 if (tcell.length () == 1)
129 retval(0) = tcell(0,0);
131 retval = octave_value (octave_value_list (tcell), true);
138 std::string nm = type_name ();
139 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
147 // FIXME -- perhaps there should be an
148 // octave_value_list::next_subsref member function? See also
149 // octave_user_function::subsref.
152 retval = retval(0).next_subsref (nargout, type, idx);
158octave_cell::subsref (const std::string& type,
159 const std::list<octave_value_list>& idx,
167 retval = do_index_op (idx.front (), auto_add);
172 octave_value tmp = do_index_op (idx.front (), auto_add);
176 const Cell tcell = tmp.cell_value ();
178 if (tcell.length () == 1)
181 retval = octave_value (octave_value_list (tcell), true);
188 std::string nm = type_name ();
189 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
197 // FIXME -- perhaps there should be an
198 // octave_value_list::next_subsref member function? See also
199 // octave_user_function::subsref.
202 retval = retval.next_subsref (auto_add, type, idx);
208octave_cell::subsasgn (const std::string& type,
209 const std::list<octave_value_list>& idx,
210 const octave_value& rhs)
214 int n = type.length ();
216 octave_value t_rhs = rhs;
218 clear_cellstr_cache ();
220 if (idx.front ().empty ())
222 error ("missing index in indexed assignment");
232 if (is_empty () && type[1] == '.')
234 // Allow conversion of empty cell array to some other
235 // type in cases like
237 // x = []; x(i).f = rhs
239 octave_value tmp = octave_value::empty_conv (type, rhs);
241 return tmp.subsasgn (type, idx, rhs);
245 octave_value tmp = do_index_op (idx.front (), true);
247 if (! tmp.is_defined ())
248 tmp = octave_value::empty_conv (type.substr (1), rhs);
252 std::list<octave_value_list> next_idx (idx);
254 next_idx.erase (next_idx.begin ());
258 t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs);
266 matrix.make_unique ();
267 Cell tmpc = matrix.index (idx.front (), true);
271 std::list<octave_value_list> next_idx (idx);
273 next_idx.erase (next_idx.begin ());
275 std::string next_type = type.substr (1);
277 if (tmpc.numel () == 1)
279 octave_value tmp = tmpc(0);
282 if (! tmp.is_defined () || tmp.is_zero_by_zero ())
284 tmp = octave_value::empty_conv (type.substr (1), rhs);
285 tmp.make_unique (); // probably a no-op.
288 // optimization: ignore the copy still stored inside our array.
292 t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
295 gripe_indexed_cs_list ();
302 std::string nm = type_name ();
303 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
318 octave_value_list i = idx.front ();
320 if (t_rhs.is_cell ())
321 octave_base_matrix<Cell>::assign (i, t_rhs.cell_value ());
323 if (t_rhs.is_null_value ())
324 octave_base_matrix<Cell>::delete_elements (i);
326 octave_base_matrix<Cell>::assign (i, Cell (t_rhs));
331 retval = octave_value (this);
334 gripe_failed_assignment ();
340 octave_value_list idxf = idx.front ();
342 if (t_rhs.is_cs_list ())
344 Cell tmp_cell = Cell (t_rhs.list_value ());
346 // Inquire the proper shape of the RHS.
348 dim_vector didx = dims ().redim (idxf.length ());
349 for (octave_idx_type k = 0; k < idxf.length (); k++)
350 if (! idxf(k).is_magic_colon ()) didx(k) = idxf(k).numel ();
352 if (didx.numel () == tmp_cell.numel ())
353 tmp_cell = tmp_cell.reshape (didx);
356 octave_base_matrix<Cell>::assign (idxf, tmp_cell);
358 else if (idxf.all_scalars () || do_index_op (idxf, true).numel () == 1)
359 // Regularize a null matrix if stored into a cell.
360 octave_base_matrix<Cell>::assign (idxf, Cell (t_rhs.storable_value ()));
361 else if (! error_state)
362 error ("invalid assignment to cs-list outside multiple assignment.");
367 retval = octave_value (this);
370 gripe_failed_assignment ();
376 std::string nm = type_name ();
377 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
390octave_cell::clear_cellstr_cache (void) const
392 cellstr_cache = Array<std::string> ();
396octave_cell::make_cellstr_cache (void) const
398 cellstr_cache = Array<std::string> (matrix.dims ());
400 octave_idx_type n = numel ();
402 std::string *dst = cellstr_cache.fortran_vec ();
403 const octave_value *src = matrix.data ();
405 for (octave_idx_type i = 0; i < n; i++)
406 dst[i] = src[i].string_value ();
410octave_cell::is_cellstr (void) const
413 if (! cellstr_cache.is_empty ())
417 retval = matrix.is_cellstr ();
418 // force cache to be created here
420 make_cellstr_cache ();
427octave_cell::assign (const octave_value_list& idx, const Cell& rhs)
429 clear_cellstr_cache ();
430 octave_base_matrix<Cell>::assign (idx, rhs);
434octave_cell::assign (const octave_value_list& idx, const octave_value& rhs)
436 clear_cellstr_cache ();
437 octave_base_matrix<Cell>::assign (idx, rhs);
442octave_cell::delete_elements (const octave_value_list& idx)
444 clear_cellstr_cache ();
445 octave_base_matrix<Cell>::delete_elements (idx);
449octave_cell::byte_size (void) const
453 for (octave_idx_type i = 0; i < numel (); i++)
454 retval += matrix(i).byte_size ();
460octave_cell::sort (octave_idx_type dim, sortmode mode) const
466 Array<std::string> tmp = cellstr_value ();
468 tmp = tmp.sort (dim, mode);
470 // We already have the cache.
471 retval = new octave_cell (tmp);
474 error ("sort: only cell arrays of character strings may be sorted");
480octave_cell::sort (Array<octave_idx_type> &sidx, octave_idx_type dim,
487 Array<std::string> tmp = cellstr_value ();
489 tmp = tmp.sort (sidx, dim, mode);
491 // We already have the cache.
492 retval = new octave_cell (tmp);
495 error ("sort: only cell arrays of character strings may be sorted");
501octave_cell::is_sorted (sortmode mode) const
503 sortmode retval = UNSORTED;
507 Array<std::string> tmp = cellstr_value ();
509 retval = tmp.is_sorted (mode);
512 error ("issorted: not a cell array of strings");
518Array<octave_idx_type>
519octave_cell::sort_rows_idx (sortmode mode) const
521 Array<octave_idx_type> retval;
525 Array<std::string> tmp = cellstr_value ();
527 retval = tmp.sort_rows_idx (mode);
530 error ("sortrows: only cell arrays of character strings may be sorted");
536octave_cell::is_sorted_rows (sortmode mode) const
538 sortmode retval = UNSORTED;
542 Array<std::string> tmp = cellstr_value ();
544 retval = tmp.is_sorted_rows (mode);
547 error ("issorted: not a cell array of strings");
553octave_cell::is_true (void) const
555 error ("invalid conversion from cell array to logical value");
560octave_cell::list_value (void) const
562 return octave_value_list (matrix);
566octave_cell::all_strings (bool pad) const
568 string_vector retval;
570 octave_idx_type nel = numel ();
574 octave_idx_type max_len = 0;
576 std::queue<string_vector> strvec_queue;
578 for (octave_idx_type i = 0; i < nel; i++)
580 string_vector s = matrix(i).all_strings ();
585 octave_idx_type s_len = s.length ();
587 n_elts += s_len ? s_len : 1;
589 octave_idx_type s_max_len = s.max_length ();
591 if (s_max_len > max_len)
594 strvec_queue.push (s);
597 retval = string_vector (n_elts);
599 octave_idx_type k = 0;
601 for (octave_idx_type i = 0; i < nel; i++)
603 const string_vector s = strvec_queue.front ();
606 octave_idx_type s_len = s.length ();
610 for (octave_idx_type j = 0; j < s_len; j++)
612 std::string t = s[j];
613 int t_len = t.length ();
615 if (pad && max_len > t_len)
616 t += std::string (max_len - t_len, ' ');
622 retval[k++] = std::string (max_len, ' ');
624 retval[k++] = std::string ();
631octave_cell::cellstr_value (void) const
633 Array<std::string> retval;
637 retval = cellstr_cache;
640 error ("invalid conversion from cell array to array of strings");
646octave_cell::print_as_scalar (void) const
648 return (ndims () > 2 || numel () == 0);
652octave_cell::print (std::ostream& os, bool) const
658octave_cell::print_raw (std::ostream& os, bool) const
660 int nd = matrix.ndims ();
664 octave_idx_type nr = rows ();
665 octave_idx_type nc = columns ();
667 if (nr > 0 && nc > 0)
673 increment_indent_level ();
675 for (octave_idx_type j = 0; j < nc; j++)
677 for (octave_idx_type i = 0; i < nr; i++)
681 std::ostringstream buf;
682 buf << "[" << i+1 << "," << j+1 << "]";
684 octave_value val = matrix(i,j);
686 val.print_with_name (os, buf.str ());
690 decrement_indent_level ();
700 if (Vprint_empty_dimensions)
701 os << "(" << nr << "x" << nc << ")";
708 dim_vector dv = matrix.dims ();
709 os << "{" << dv.str () << " Cell Array}";
714#define CELL_ELT_TAG "<cell-element>"
717octave_cell::save_ascii (std::ostream& os)
719 dim_vector d = dims ();
722 os << "# ndims: " << d.length () << "\n";
724 for (int i = 0; i < d.length (); i++)
728 Cell tmp = cell_value ();
730 for (octave_idx_type i = 0; i < d.numel (); i++)
732 octave_value o_val = tmp.elem (i);
734 // Recurse to print sub-value.
735 bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, false, 0);
743 // Keep this case, rather than use generic code above for backward
744 // compatiability. Makes load_ascii much more complex!!
745 os << "# rows: " << rows () << "\n"
746 << "# columns: " << columns () << "\n";
748 Cell tmp = cell_value ();
750 for (octave_idx_type j = 0; j < tmp.cols (); j++)
752 for (octave_idx_type i = 0; i < tmp.rows (); i++)
754 octave_value o_val = tmp.elem (i, j);
756 // Recurse to print sub-value.
757 bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, false, 0);
771octave_cell::load_ascii (std::istream& is)
775 clear_cellstr_cache ();
777 string_vector keywords(2);
779 keywords[0] = "ndims";
780 keywords[1] = "rows";
783 octave_idx_type val = 0;
785 if (extract_keyword (is, keywords, kw, val, true))
789 int mdims = static_cast<int> (val);
796 for (int i = 0; i < mdims; i++)
801 for (octave_idx_type i = 0; i < dv.numel (); i++)
806 // recurse to read cell elements
807 std::string nm = read_ascii_data (is, std::string (),
810 if (nm == CELL_ELT_TAG)
817 error ("load: cell array element had unexpected name");
827 error ("load: failed to load matrix constant");
833 error ("load: failed to extract number of rows and columns");
837 else if (kw == "rows")
839 octave_idx_type nr = val;
840 octave_idx_type nc = 0;
842 if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
844 if (nr > 0 && nc > 0)
848 for (octave_idx_type j = 0; j < nc; j++)
850 for (octave_idx_type i = 0; i < nr; i++)
855 // recurse to read cell elements
856 std::string nm = read_ascii_data (is, std::string (),
859 if (nm == CELL_ELT_TAG)
862 tmp.elem (i, j) = t2;
866 error ("load: cell array element had unexpected name");
868 goto cell_read_error;
879 error ("load: failed to load cell element");
883 else if (nr == 0 || nc == 0)
884 matrix = Cell (nr, nc);
890 error ("load: failed to extract number of rows and columns for cell array");
899 error ("load: failed to extract number of rows and columns");
907octave_cell::save_binary (std::ostream& os, bool& save_as_floats)
909 dim_vector d = dims ();
913 // Use negative value for ndims
914 int32_t di = - d.length();
915 os.write (reinterpret_cast<char *> (&di), 4);
916 for (int i = 0; i < d.length (); i++)
919 os.write (reinterpret_cast<char *> (&di), 4);
922 Cell tmp = cell_value ();
924 for (octave_idx_type i = 0; i < d.numel (); i++)
926 octave_value o_val = tmp.elem (i);
928 // Recurse to print sub-value.
929 bool b = save_binary_data (os, o_val, CELL_ELT_TAG, "", 0,
940octave_cell::load_binary (std::istream& is, bool swap,
941 oct_mach_info::float_format fmt)
943 clear_cellstr_cache ();
947 if (! is.read (reinterpret_cast<char *> (&mdims), 4))
950 swap_bytes<4> (&mdims);
959 for (int i = 0; i < mdims; i++)
961 if (! is.read (reinterpret_cast<char *> (&di), 4))
968 // Convert an array with a single dimension to be a row vector.
969 // Octave should never write files like this, other software
980 octave_idx_type nel = dv.numel ();
983 for (octave_idx_type i = 0; i < nel; i++)
989 // recurse to read cell elements
990 std::string nm = read_binary_data (is, swap, fmt, std::string (),
993 if (nm == CELL_ELT_TAG)
1000 error ("load: cell array element had unexpected name");
1010 error ("load: failed to load matrix constant");
1018octave_cell::mex_get_data (void) const
1020 clear_cellstr_cache ();
1021 return matrix.mex_get_data ();
1024#if defined (HAVE_HDF5)
1027octave_cell::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
1029 dim_vector dv = dims ();
1030 int empty = save_hdf5_empty (loc_id, name, dv);
1034 hsize_t rank = dv.length ();
1035 hid_t space_hid = -1, data_hid = -1, size_hid = -1;
1037 data_hid = H5Gcreate (loc_id, name, 0);
1042 // Have to save cell array shape, since can't have a
1043 // dataset of groups....
1045 space_hid = H5Screate_simple (1, &rank, 0);
1049 H5Gclose (data_hid);
1053 OCTAVE_LOCAL_BUFFER (octave_idx_type, hdims, rank);
1055 // Octave uses column-major, while HDF5 uses row-major ordering
1056 for (hsize_t i = 0; i < rank; i++)
1057 hdims[i] = dv(rank-i-1);
1059 size_hid = H5Dcreate (data_hid, "dims", H5T_NATIVE_IDX, space_hid,
1063 H5Sclose (space_hid);
1064 H5Gclose (data_hid);
1068 if (H5Dwrite (size_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
1069 H5P_DEFAULT, hdims) < 0)
1071 H5Dclose (size_hid);
1072 H5Sclose (space_hid);
1073 H5Gclose (data_hid);
1077 H5Dclose (size_hid);
1078 H5Sclose (space_hid);
1080 // Recursively add each element of the cell to this group.
1082 Cell tmp = cell_value ();
1084 octave_idx_type nel = dv.numel ();
1086 for (octave_idx_type i = 0; i < nel; i++)
1088 std::ostringstream buf;
1089 int digits = static_cast<int> (::floor (::log10 (static_cast<double> (nel)) + 1.0));
1090 buf << "_" << std::setw (digits) << std::setfill ('0') << i;
1091 std::string s = buf.str ();
1093 if (! add_hdf5_data (data_hid, tmp.elem (i), s.c_str (), "", false,
1096 H5Gclose (data_hid);
1101 H5Gclose (data_hid);
1107octave_cell::load_hdf5 (hid_t loc_id, const char *name,
1108 bool have_h5giterate_bug)
1110 clear_cellstr_cache ();
1112 bool retval = false;
1115 int empty = load_hdf5_empty (loc_id, name, dv);
1121 hid_t group_id = H5Gopen (loc_id, name);
1126 hid_t data_hid = H5Dopen (group_id, "dims");
1127 hid_t space_hid = H5Dget_space (data_hid);
1128 hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
1131 H5Dclose (data_hid);
1132 H5Gclose (group_id);
1136 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
1137 OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
1139 H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
1141 // Octave uses column-major, while HDF5 uses row-major ordering.
1143 dv.resize (hdims[0]);
1145 OCTAVE_LOCAL_BUFFER (octave_idx_type, tmp, hdims[0]);
1147 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
1148 H5P_DEFAULT, tmp) < 0)
1150 H5Dclose (data_hid);
1151 H5Gclose (group_id);
1155 H5Dclose (data_hid);
1156 H5Gclose (group_id);
1158 for (hsize_t i = 0, j = hdims[0] - 1; i < hdims[0]; i++, j--)
1161 hdf5_callback_data dsub;
1163 herr_t retval2 = -1;
1167 int current_item = 0;
1169 if (have_h5giterate_bug)
1170 current_item = 1; // Skip dims items in group.
1172#ifdef HAVE_H5GGET_NUM_OBJS
1173 hsize_t num_obj = 0;
1174 group_id = H5Gopen (loc_id, name);
1175 H5Gget_num_objs (group_id, &num_obj);
1176 H5Gclose (group_id);
1179 for (octave_idx_type i = 0; i < dv.numel (); i++)
1182#ifdef HAVE_H5GGET_NUM_OBJS
1183 if (current_item >= static_cast<int> (num_obj))
1187 retval2 = H5Giterate (loc_id, name, ¤t_item,
1188 hdf5_read_next_data, &dsub);
1193 octave_value ov = dsub.tc;
1196 if (have_h5giterate_bug)
1197 current_item++; // H5Giterate returned the last index processed.
1212DEFUN (iscell, args, ,
1214@deftypefn {Built-in Function} {} iscell (@var{x})\n\
1215Return true if @var{x} is a cell array object. Otherwise, return\n\
1219 octave_value retval;
1221 if (args.length () == 1)
1222 retval = args(0).is_cell ();
1231@deftypefn {Built-in Function} {} cell (@var{x})\n\
1232@deftypefnx {Built-in Function} {} cell (@var{n}, @var{m})\n\
1233Create a new cell array object. If invoked with a single scalar\n\
1234argument, @code{cell} returns a square cell array with the dimension\n\
1235specified. If you supply two scalar arguments, @code{cell} takes\n\
1236them to be the number of rows and columns. If given a vector with two\n\
1237elements, @code{cell} uses the values of the elements as the number of\n\
1238rows and columns, respectively.\n\
1241 octave_value retval;
1243 int nargin = args.length ();
1250 dims = dim_vector (0, 0);
1254 get_dimensions (args(0), "cell", dims);
1259 dims.resize (nargin);
1261 for (int i = 0; i < nargin; i++)
1263 dims(i) = args(i).is_empty () ? 0 : args(i).nint_value ();
1267 error ("cell: expecting scalar arguments");
1277 dims.chop_trailing_singletons ();
1279 check_dimensions (dims, "cell");
1282 retval = Cell (dims, Matrix ());
1288DEFUN (iscellstr, args, ,
1290@deftypefn {Built-in Function} {} iscellstr (@var{cell})\n\
1291Return true if every element of the cell array @var{cell} is a\n\
1295 octave_value retval;
1297 if (args.length () == 1)
1298 retval = args(0).is_cellstr ();
1305// Note that since Fcellstr calls Fiscellstr, we need to have
1306// Fiscellstr defined first (to provide a declaration) and also we
1307// should keep it in the same file (so we don't have to provide a
1308// declaration) and so we don't have to use feval to call it.
1310DEFUN (cellstr, args, ,
1312@deftypefn {Built-in Function} {} cellstr (@var{string})\n\
1313Create a new cell array object from the elements of the string\n\
1314array @var{string}.\n\
1317 octave_value retval;
1319 if (args.length () == 1)
1321 octave_value_list tmp = Fiscellstr (args, 1);
1323 if (tmp(0).is_true ())
1327 string_vector s = args(0).all_strings ();
1330 retval = (s.is_empty ()
1331 ? Cell (octave_value (std::string ()))
1334 error ("cellstr: expecting argument to be a 2-d character array");
1343DEFUN (struct2cell, args, ,
1345@deftypefn {Built-in Function} {} struct2cell (@var{S})\n\
1346Create a new cell array from the objects stored in the struct object.\n\
1347If @var{f} is the number of fields in the structure, the resulting\n\
1348cell array will have a dimension vector corresponding to\n\
1349@code{[@var{F} size(@var{S})]}.\n\
1350@seealso{cell2struct, fieldnames}\n\
1353 octave_value retval;
1355 int nargin = args.length ();
1359 Octave_map m = args(0).map_value ();
1363 dim_vector m_dv = m.dims ();
1365 string_vector keys = m.keys ();
1367 octave_idx_type num_fields = keys.length ();
1369 // The resulting dim_vector should have dimensions:
1370 // [numel(fields) size(struct)]
1371 // except if the struct is a column vector.
1373 dim_vector result_dv;
1374 if (m_dv (m_dv.length () - 1) == 1)
1375 result_dv.resize (m_dv.length ());
1377 result_dv.resize (m_dv.length () + 1); // Add 1 for the fields.
1379 result_dv(0) = num_fields;
1381 for (int i = 1; i < result_dv.length (); i++)
1382 result_dv(i) = m_dv(i-1);
1386 octave_idx_type n_elts = m.numel ();
1388 for (octave_idx_type j = 0; j < num_fields; j++)
1390 octave_idx_type k = j;
1392 const Cell vals = m.contents (keys(j));
1394 for (octave_idx_type i = 0; i < n_elts; i++)
1404 error ("struct2cell: expecting argument to be a cell array");
1413octave_cell::as_mxArray (void) const
1415 mxArray *retval = new mxArray (dims ());
1417 mxArray **elts = static_cast<mxArray **> (retval->get_data ());
1419 mwSize nel = numel ();
1421 const octave_value *p = matrix.data ();
1423 for (mwIndex i = 0; i < nel; i++)
1424 elts[i] = new mxArray (p[i]);
1430octave_cell::map (unary_mapper_t umap) const
1434#define FORWARD_MAPPER(UMAP) \
1435 case umap_ ## UMAP: \
1436 return matrix.UMAP ()
1437 FORWARD_MAPPER (xisalnum);
1438 FORWARD_MAPPER (xisalpha);
1439 FORWARD_MAPPER (xisascii);
1440 FORWARD_MAPPER (xiscntrl);
1441 FORWARD_MAPPER (xisdigit);
1442 FORWARD_MAPPER (xisgraph);
1443 FORWARD_MAPPER (xislower);
1444 FORWARD_MAPPER (xisprint);
1445 FORWARD_MAPPER (xispunct);
1446 FORWARD_MAPPER (xisspace);
1447 FORWARD_MAPPER (xisupper);
1448 FORWARD_MAPPER (xisxdigit);
1449 FORWARD_MAPPER (xtoascii);
1450 FORWARD_MAPPER (xtolower);
1451 FORWARD_MAPPER (xtoupper);
1454 return octave_base_value::map (umap);
1459;;; Local Variables: ***