GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-cell.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1999-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <istream>
31 #include <ostream>
32 #include <sstream>
33 #include <vector>
34 #include <queue>
35 
36 #include "Array-util.h"
37 #include "byte-swap.h"
38 #include "lo-utils.h"
39 #include "quit.h"
40 #include "oct-locbuf.h"
41 
42 #include "builtin-defun-decls.h"
43 #include "defun.h"
44 #include "error.h"
45 #include "mxarray.h"
46 #include "ov-cell.h"
47 #include "ovl.h"
48 #include "oct-hdf5.h"
49 #include "unwind-prot.h"
50 #include "utils.h"
51 #include "ov-base-mat.h"
52 #include "ov-base-mat.cc"
53 #include "ov-re-mat.h"
54 #include "ov-scalar.h"
55 #include "pr-output.h"
56 #include "ov-scalar.h"
57 #include "errwarn.h"
58 
59 #include "ls-oct-text.h"
60 #include "ls-oct-binary.h"
61 #include "ls-hdf5.h"
62 #include "ls-utils.h"
63 
64 // Cell is able to handle octave_value indexing by itself, so just forward
65 // everything.
66 
67 template <>
70  bool resize_ok)
71 {
72  return matrix.index (idx, resize_ok);
73 }
74 
75 template <>
76 void
78 {
79  matrix.assign (idx, rhs);
80 }
81 
82 template <>
83 void
85  octave_value rhs)
86 {
87  // FIXME: Really?
88  if (rhs.iscell ())
89  matrix.assign (idx, rhs.cell_value ());
90  else
91  matrix.assign (idx, Cell (rhs));
92 }
93 
94 template <>
95 void
97 {
98  matrix.delete_elements (idx);
99 }
100 
101 // FIXME: this list of specializations is becoming so long that we should
102 // really ask whether octave_cell should inherit from octave_base_matrix at all.
103 
104 template <>
105 std::string
107  octave_idx_type i,
108  octave_idx_type j) const
109 {
110  octave_value val = matrix(i,j);
111 
112  std::string tname = val.type_name ();
113  dim_vector dv = val.dims ();
114  std::string dimstr = dv.str ();
115  return "[" + dimstr + " " + tname + "]";
116 }
117 
118 template <>
121 {
122  if (n < matrix.numel ())
123  return Cell (matrix(n));
124  else
125  return octave_value ();
126 }
127 
128 template <>
129 bool
131  const octave_value& x)
132 {
133  const octave_cell *xrep = dynamic_cast<const octave_cell *> (&x.get_rep ());
134 
135  bool retval = xrep && xrep->matrix.numel () == 1 && n < matrix.numel ();
136  if (retval)
137  matrix(n) = xrep->matrix(0);
138 
139  return retval;
140 }
141 
142 template class octave_base_matrix<Cell>;
143 
145 
147 octave_cell::subsref (const std::string& type,
148  const std::list<octave_value_list>& idx,
149  int nargout)
150 {
152 
153  switch (type[0])
154  {
155  case '(':
156  retval(0) = do_index_op (idx.front ());
157  break;
158 
159  case '{':
160  {
161  if (idx.front ().empty ())
162  error ("invalid empty index expression");
163 
164  octave_value tmp = do_index_op (idx.front ());
165 
166  Cell tcell = tmp.cell_value ();
167 
168  if (tcell.numel () == 1)
169  retval(0) = tcell(0,0);
170  else
171  {
172  // Return a comma-separated list.
174  }
175  }
176  break;
177 
178  case '.':
179  {
180  std::string nm = type_name ();
181  error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
182  }
183  break;
184 
185  default:
186  panic_impossible ();
187  }
188 
189  // FIXME: perhaps there should be an
190  // octave_value_list::next_subsref member function? See also
191  // octave_user_function::subsref.
192 
193  if (idx.size () > 1)
194  retval = retval(0).next_subsref (nargout, type, idx);
195 
196  return retval;
197 }
198 
200 octave_cell::subsref (const std::string& type,
201  const std::list<octave_value_list>& idx,
202  bool auto_add)
203 {
205 
206  switch (type[0])
207  {
208  case '(':
209  retval = do_index_op (idx.front (), auto_add);
210  break;
211 
212  case '{':
213  {
214  octave_value tmp = do_index_op (idx.front (), auto_add);
215 
216  const Cell tcell = tmp.cell_value ();
217 
218  if (tcell.numel () == 1)
219  retval = tcell(0,0);
220  else
221  {
222  // Return a comma-separated list.
224  }
225  }
226  break;
227 
228  case '.':
229  {
230  std::string nm = type_name ();
231  error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
232  }
233  break;
234 
235  default:
236  panic_impossible ();
237  }
238 
239  // FIXME: perhaps there should be an
240  // octave_value_list::next_subsref member function? See also
241  // octave_user_function::subsref.
242 
243  if (idx.size () > 1)
244  retval = retval.next_subsref (auto_add, type, idx);
245 
246  return retval;
247 }
248 
250 octave_cell::subsasgn (const std::string& type,
251  const std::list<octave_value_list>& idx,
252  const octave_value& rhs)
253 {
255 
256  int n = type.length ();
257 
258  octave_value t_rhs = rhs;
259 
261 
262  if (idx.front ().empty ())
263  error ("missing index in indexed assignment");
264 
265  if (n > 1)
266  {
267  switch (type[0])
268  {
269  case '(':
270  {
271  if (isempty () && type[1] == '.')
272  {
273  // Allow conversion of empty cell array to some other
274  // type in cases like
275  //
276  // x = {}; x(i).f = rhs
277 
279 
280  return tmp.subsasgn (type, idx, rhs);
281  }
282  else
283  {
284  octave_value tmp = do_index_op (idx.front (), true);
285 
286  if (! tmp.is_defined ())
287  tmp = octave_value::empty_conv (type.substr (1), rhs);
288 
289  std::list<octave_value_list> next_idx (idx);
290 
291  next_idx.erase (next_idx.begin ());
292 
293  tmp.make_unique ();
294 
295  t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs);
296  }
297  }
298  break;
299 
300  case '{':
301  {
302  matrix.make_unique ();
303  Cell tmpc = matrix.index (idx.front (), true);
304 
305  std::list<octave_value_list> next_idx (idx);
306 
307  next_idx.erase (next_idx.begin ());
308 
309  std::string next_type = type.substr (1);
310 
311  if (tmpc.numel () != 1)
313 
314  octave_value tmp = tmpc(0);
315  tmpc = Cell ();
316 
317  if (! tmp.is_defined () || tmp.is_zero_by_zero ())
318  {
319  tmp = octave_value::empty_conv (type.substr (1), rhs);
320  tmp.make_unique (); // probably a no-op.
321  }
322  else
323  // optimization: ignore copy still stored inside array.
324  tmp.make_unique (1);
325 
326  t_rhs = tmp.subsasgn (next_type, next_idx, rhs);
327  }
328  break;
329 
330  case '.':
331  {
332  if (! isempty ())
333  {
334  std::string nm = type_name ();
335  error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
336  }
337 
338  // Do nothing; the next branch will handle it.
339  }
340  break;
341 
342  default:
343  panic_impossible ();
344  }
345  }
346 
347  switch (type[0])
348  {
349  case '(':
350  {
351  octave_value_list i = idx.front ();
352 
353  if (t_rhs.iscell ())
355  else if (t_rhs.isnull ())
357  else
359 
360  count++;
361  retval = octave_value (this);
362  }
363  break;
364 
365  case '{':
366  {
367  octave_value_list idxf = idx.front ();
368 
369  if (t_rhs.is_cs_list ())
370  {
371  Cell tmp_cell = Cell (t_rhs.list_value ());
372 
373  // Inquire the proper shape of the RHS.
374 
375  dim_vector didx = dims ().redim (idxf.length ());
376  for (octave_idx_type k = 0; k < idxf.length (); k++)
377  if (! idxf(k).is_magic_colon ()) didx(k) = idxf(k).numel ();
378 
379  if (didx.numel () == tmp_cell.numel ())
380  tmp_cell = tmp_cell.reshape (didx);
381 
382  octave_base_matrix<Cell>::assign (idxf, tmp_cell);
383  }
384  else if (idxf.all_scalars ()
385  || do_index_op (idxf, true).numel () == 1)
386  // Regularize a null matrix if stored into a cell.
388  Cell (t_rhs.storable_value ()));
389  else
391 
392  count++;
393  retval = octave_value (this);
394  }
395  break;
396 
397  case '.':
398  {
399  if (! isempty ())
400  {
401  std::string nm = type_name ();
402  error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
403  }
404 
405  // Allow conversion of empty cell array to some other
406  // type in cases like
407  //
408  // x = {}; x.f = rhs
409 
411 
412  return tmp.subsasgn (type, idx, rhs);
413  }
414  break;
415 
416  default:
417  panic_impossible ();
418  }
419 
420  return retval;
421 }
422 
423 bool
425 {
426  bool retval;
427  if (cellstr_cache.get ())
428  retval = true;
429  else
430  {
431  retval = matrix.iscellstr ();
432  // Allocate empty cache to mark that this is indeed a cellstr.
433  if (retval)
434  cellstr_cache.reset (new Array<std::string> ());
435  }
436 
437  return retval;
438 }
439 
440 void
442 {
445 }
446 
447 void
449 {
452 }
453 
454 void
456 {
459 }
460 
461 size_t
463 {
464  size_t retval = 0;
465 
466  for (octave_idx_type i = 0; i < numel (); i++)
467  retval += matrix(i).byte_size ();
468 
469  return retval;
470 }
471 
474 {
476 
477  if (! iscellstr ())
478  error ("sort: only cell arrays of character strings may be sorted");
479 
481 
482  tmp = tmp.sort (dim, mode);
483 
484  // We already have the cache.
485  retval = new octave_cell (tmp);
486 
487  return retval;
488 }
489 
492  sortmode mode) const
493 {
495 
496  if (! iscellstr ())
497  error ("sort: only cell arrays of character strings may be sorted");
498 
500 
501  tmp = tmp.sort (sidx, dim, mode);
502 
503  // We already have the cache.
504  retval = new octave_cell (tmp);
505 
506  return retval;
507 }
508 
509 sortmode
511 {
513 
514  if (! iscellstr ())
515  error ("issorted: A is not a cell array of strings");
516 
518 
519  retval = tmp.issorted (mode);
520 
521  return retval;
522 }
523 
526 {
528 
529  if (! iscellstr ())
530  error ("sortrows: only cell arrays of character strings may be sorted");
531 
533 
534  retval = tmp.sort_rows_idx (mode);
535 
536  return retval;
537 }
538 
539 sortmode
541 {
543 
544  if (! iscellstr ())
545  error ("issorted: A is not a cell array of strings");
546 
548 
549  retval = tmp.is_sorted_rows (mode);
550 
551  return retval;
552 }
553 
554 bool
556 {
557  error ("invalid conversion from cell array to logical value");
558 }
559 
562 {
563  return octave_value_list (matrix);
564 }
565 
568 {
570 
571  octave_idx_type nel = numel ();
572 
573  int n_elts = 0;
574 
575  octave_idx_type max_len = 0;
576 
577  std::queue<string_vector> strvec_queue;
578 
579  for (octave_idx_type i = 0; i < nel; i++)
580  {
582 
583  octave_idx_type s_len = s.numel ();
584 
585  n_elts += s_len ? s_len : 1;
586 
587  octave_idx_type s_max_len = s.max_length ();
588 
589  if (s_max_len > max_len)
590  max_len = s_max_len;
591 
592  strvec_queue.push (s);
593  }
594 
595  retval = string_vector (n_elts);
596 
597  octave_idx_type k = 0;
598 
599  for (octave_idx_type i = 0; i < nel; i++)
600  {
601  const string_vector s = strvec_queue.front ();
602  strvec_queue.pop ();
603 
604  octave_idx_type s_len = s.numel ();
605 
606  if (s_len)
607  {
608  for (octave_idx_type j = 0; j < s_len; j++)
609  {
610  std::string t = s[j];
611  int t_len = t.length ();
612 
613  if (pad && max_len > t_len)
614  t += std::string (max_len - t_len, ' ');
615 
616  retval[k++] = t;
617  }
618  }
619  else if (pad)
620  retval[k++] = std::string (max_len, ' ');
621  else
622  retval[k++] = "";
623  }
624 
625  return retval;
626 }
627 
630 {
631  if (! iscellstr ())
632  error ("invalid conversion from cell array to array of strings");
633 
634  if (cellstr_cache->isempty ())
636 
637  return *cellstr_cache;
638 }
639 
640 bool
642 {
643  return true;
644 }
645 
646 void
647 octave_cell::print (std::ostream& os, bool)
648 {
649  print_raw (os);
650 }
651 
652 void
653 octave_cell::print_raw (std::ostream& os, bool) const
654 {
655  int nd = matrix.ndims ();
656 
657  if (nd == 2)
658  {
659  octave_idx_type nr = rows ();
660  octave_idx_type nc = columns ();
661 
662  if (nr > 0 && nc > 0)
663  {
664  indent (os);
665  os << '{';
666  newline (os);
667 
669 
670  for (octave_idx_type j = 0; j < nc; j++)
671  {
672  for (octave_idx_type i = 0; i < nr; i++)
673  {
674  octave_quit ();
675 
676  std::ostringstream buf;
677  buf << '[' << i+1 << ',' << j+1 << ']';
678 
679  octave_value val = matrix(i,j);
680 
681  val.print_with_name (os, buf.str ());
682  }
683  }
684 
686 
687  indent (os);
688  os << '}';
689  newline (os);
690  }
691  else
692  {
693  indent (os);
694  os << "{}";
696  os << '(' << nr << 'x' << nc << ')';
697  newline (os);
698  }
699  }
700  else
701  {
702  indent (os);
703  dim_vector dv = matrix.dims ();
704  os << '{' << dv.str () << " Cell Array}";
705  newline (os);
706  }
707 }
708 
709 bool
710 octave_cell::print_name_tag (std::ostream& os, const std::string& name) const
711 {
712  bool retval = false;
713 
714  indent (os);
715 
716  if (isempty () || ndims () > 2)
717  os << name << " = ";
718  else
719  {
720  os << name << " =";
721  newline (os);
722  retval = true;
723  }
724 
725  return retval;
726 }
727 
728 void
729 octave_cell::short_disp (std::ostream& os) const
730 {
731  os << (matrix.isempty () ? "{}" : "...");
732 }
733 
734 #define CELL_ELT_TAG "<cell-element>"
735 
736 bool
737 octave_cell::save_ascii (std::ostream& os)
738 {
739  dim_vector dv = dims ();
740  if (dv.ndims () > 2)
741  {
742  os << "# ndims: " << dv.ndims () << "\n";
743 
744  for (int i = 0; i < dv.ndims (); i++)
745  os << ' ' << dv(i);
746  os << "\n";
747 
748  Cell tmp = cell_value ();
749 
750  for (octave_idx_type i = 0; i < dv.numel (); i++)
751  {
752  octave_value o_val = tmp.elem (i);
753 
754  // Recurse to save sub-value.
755  bool b = save_text_data (os, o_val, CELL_ELT_TAG, false, 0);
756 
757  if (! b)
758  return ! os.fail ();
759  }
760  }
761  else
762  {
763  // Keep this case, rather than use generic code above for backward
764  // compatibility. Makes load_ascii much more complex!!
765  os << "# rows: " << rows () << "\n"
766  << "# columns: " << columns () << "\n";
767 
768  Cell tmp = cell_value ();
769 
770  for (octave_idx_type j = 0; j < tmp.cols (); j++)
771  {
772  for (octave_idx_type i = 0; i < tmp.rows (); i++)
773  {
774  octave_value o_val = tmp.elem (i, j);
775 
776  // Recurse to save sub-value.
777  bool b = save_text_data (os, o_val, CELL_ELT_TAG, false, 0);
778 
779  if (! b)
780  return ! os.fail ();
781  }
782 
783  os << "\n";
784  }
785  }
786 
787  return true;
788 }
789 
790 bool
791 octave_cell::load_ascii (std::istream& is)
792 {
794 
795  string_vector keywords(2);
796 
797  keywords[0] = "ndims";
798  keywords[1] = "rows";
799 
800  std::string kw;
801  octave_idx_type val = 0;
802 
803  if (! extract_keyword (is, keywords, kw, val, true))
804  error ("load: failed to extract number of rows and columns");
805 
806  if (kw == "ndims")
807  {
808  int mdims = static_cast<int> (val);
809 
810  if (mdims < 0)
811  error ("load: failed to extract number of rows and columns");
812 
813  dim_vector dv;
814  dv.resize (mdims);
815 
816  for (int i = 0; i < mdims; i++)
817  is >> dv(i);
818 
819  Cell tmp(dv);
820 
821  for (octave_idx_type i = 0; i < dv.numel (); i++)
822  {
823  octave_value t2;
824  bool dummy;
825 
826  // recurse to read cell elements
827  std::string nm = read_text_data (is, "",
828  dummy, t2, i);
829 
830  if (nm != CELL_ELT_TAG)
831  error ("load: cell array element had unexpected name");
832 
833  if (is)
834  tmp.elem (i) = t2;
835  }
836 
837  if (! is)
838  error ("load: failed to load matrix constant");
839 
840  matrix = tmp;
841  }
842  else if (kw == "rows")
843  {
844  octave_idx_type nr = val;
845  octave_idx_type nc = 0;
846 
847  if (nr < 0 || ! extract_keyword (is, "columns", nc) || nc < 0)
848  error ("load: failed to extract number of rows and columns for cell array");
849 
850  if (nr > 0 && nc > 0)
851  {
852  Cell tmp (nr, nc);
853 
854  for (octave_idx_type j = 0; j < nc; j++)
855  {
856  for (octave_idx_type i = 0; i < nr; i++)
857  {
858  octave_value t2;
859  bool dummy;
860 
861  // recurse to read cell elements
862  std::string nm = read_text_data (is, "",
863  dummy, t2, i);
864 
865  if (nm != CELL_ELT_TAG)
866  error ("load: cell array element had unexpected name");
867 
868  if (is)
869  tmp.elem (i, j) = t2;
870  }
871  }
872 
873  if (! is)
874  error ("load: failed to load cell element");
875 
876  matrix = tmp;
877  }
878  else if (nr == 0 || nc == 0)
879  matrix = Cell (nr, nc);
880  else
881  panic_impossible ();
882  }
883  else
884  panic_impossible ();
885 
886  return true;
887 }
888 
889 bool
890 octave_cell::save_binary (std::ostream& os, bool save_as_floats)
891 {
892  dim_vector dv = dims ();
893  if (dv.ndims () < 1)
894  return false;
895 
896  // Use negative value for ndims
897  int32_t di = - dv.ndims ();
898  os.write (reinterpret_cast<char *> (&di), 4);
899  for (int i = 0; i < dv.ndims (); i++)
900  {
901  di = dv(i);
902  os.write (reinterpret_cast<char *> (&di), 4);
903  }
904 
905  Cell tmp = cell_value ();
906 
907  for (octave_idx_type i = 0; i < dv.numel (); i++)
908  {
909  octave_value o_val = tmp.elem (i);
910 
911  // Recurse to save sub-value.
912  bool b = save_binary_data (os, o_val, CELL_ELT_TAG, "", 0,
913  save_as_floats);
914 
915  if (! b)
916  return false;
917  }
918 
919  return true;
920 }
921 
922 bool
923 octave_cell::load_binary (std::istream& is, bool swap,
925 {
927 
928  int32_t mdims;
929  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
930  return false;
931  if (swap)
932  swap_bytes<4> (&mdims);
933  if (mdims >= 0)
934  return false;
935 
936  mdims = -mdims;
937  int32_t di;
938  dim_vector dv;
939  dv.resize (mdims);
940 
941  for (int i = 0; i < mdims; i++)
942  {
943  if (! is.read (reinterpret_cast<char *> (&di), 4))
944  return false;
945  if (swap)
946  swap_bytes<4> (&di);
947  dv(i) = di;
948  }
949 
950  // Convert an array with a single dimension to be a row vector.
951  // Octave should never write files like this, other software
952  // might.
953 
954  if (mdims == 1)
955  {
956  mdims = 2;
957  dv.resize (mdims);
958  dv(1) = dv(0);
959  dv(0) = 1;
960  }
961 
962  octave_idx_type nel = dv.numel ();
963  Cell tmp(dv);
964 
965  for (octave_idx_type i = 0; i < nel; i++)
966  {
967  octave_value t2;
968  bool dummy;
969  std::string doc;
970 
971  // recurse to read cell elements
972  std::string nm = read_binary_data (is, swap, fmt, "",
973  dummy, t2, doc);
974 
975  if (nm != CELL_ELT_TAG)
976  error ("load: cell array element had unexpected name");
977 
978  if (is)
979  tmp.elem (i) = t2;
980  }
981 
982  if (! is)
983  error ("load: failed to load matrix constant");
984 
985  matrix = tmp;
986 
987  return true;
988 }
989 
990 void *
992 {
994  return matrix.mex_get_data ();
995 }
996 
997 bool
999  bool save_as_floats)
1000 {
1001 #if defined (HAVE_HDF5)
1002 
1003  dim_vector dv = dims ();
1004  int empty = save_hdf5_empty (loc_id, name, dv);
1005  if (empty)
1006  return (empty > 0);
1007 
1008  hsize_t rank = dv.ndims ();
1009  hid_t space_hid, data_hid, size_hid;
1010  space_hid = data_hid = size_hid = -1;
1011 
1012 #if defined (HAVE_HDF5_18)
1013  data_hid = H5Gcreate (loc_id, name, octave_H5P_DEFAULT, octave_H5P_DEFAULT,
1015 #else
1016  data_hid = H5Gcreate (loc_id, name, 0);
1017 #endif
1018 
1019  if (data_hid < 0)
1020  return false;
1021 
1022  // Have to save cell array shape, since can't have a
1023  // dataset of groups....
1024 
1025  space_hid = H5Screate_simple (1, &rank, nullptr);
1026 
1027  if (space_hid < 0)
1028  {
1029  H5Gclose (data_hid);
1030  return false;
1031  }
1032 
1033  OCTAVE_LOCAL_BUFFER (octave_idx_type, hdims, rank);
1034 
1035  // Octave uses column-major, while HDF5 uses row-major ordering
1036  for (hsize_t i = 0; i < rank; i++)
1037  hdims[i] = dv(rank-i-1);
1038 
1039 #if defined (HAVE_HDF5_18)
1040  size_hid = H5Dcreate (data_hid, "dims", H5T_NATIVE_IDX, space_hid,
1042 #else
1043  size_hid = H5Dcreate (data_hid, "dims", H5T_NATIVE_IDX, space_hid,
1045 #endif
1046  if (size_hid < 0)
1047  {
1048  H5Sclose (space_hid);
1049  H5Gclose (data_hid);
1050  return false;
1051  }
1052 
1053  if (H5Dwrite (size_hid, H5T_NATIVE_IDX, octave_H5S_ALL, octave_H5S_ALL,
1054  octave_H5P_DEFAULT, hdims) < 0)
1055  {
1056  H5Dclose (size_hid);
1057  H5Sclose (space_hid);
1058  H5Gclose (data_hid);
1059  return false;
1060  }
1061 
1062  H5Dclose (size_hid);
1063  H5Sclose (space_hid);
1064 
1065  // Recursively add each element of the cell to this group.
1066 
1067  Cell tmp = cell_value ();
1068 
1069  octave_idx_type nel = dv.numel ();
1070 
1071  for (octave_idx_type i = 0; i < nel; i++)
1072  {
1073  std::ostringstream buf;
1074  int digits = static_cast<int> (std::floor (::log10 (static_cast<double>
1075  (nel)) + 1.0));
1076  buf << '_' << std::setw (digits) << std::setfill ('0') << i;
1077  std::string s = buf.str ();
1078 
1079  if (! add_hdf5_data (data_hid, tmp.elem (i), s.c_str (), "", false,
1080  save_as_floats))
1081  {
1082  H5Gclose (data_hid);
1083  return false;
1084  }
1085  }
1086 
1087  H5Gclose (data_hid);
1088 
1089  return true;
1090 
1091 #else
1092  octave_unused_parameter (loc_id);
1093  octave_unused_parameter (name);
1094  octave_unused_parameter (save_as_floats);
1095 
1096  warn_save ("hdf5");
1097 
1098  return false;
1099 #endif
1100 }
1101 
1102 bool
1104 {
1105  bool retval = false;
1106 
1107 #if defined (HAVE_HDF5)
1108 
1110 
1111  dim_vector dv;
1112  int empty = load_hdf5_empty (loc_id, name, dv);
1113  if (empty > 0)
1114  matrix.resize (dv);
1115  if (empty)
1116  return (empty > 0);
1117 
1118 #if defined (HAVE_HDF5_18)
1119  hid_t group_id = H5Gopen (loc_id, name, octave_H5P_DEFAULT);
1120 #else
1121  hid_t group_id = H5Gopen (loc_id, name);
1122 #endif
1123 
1124  if (group_id < 0)
1125  return false;
1126 
1127 #if defined (HAVE_HDF5_18)
1128  hid_t data_hid = H5Dopen (group_id, "dims", octave_H5P_DEFAULT);
1129 #else
1130  hid_t data_hid = H5Dopen (group_id, "dims");
1131 #endif
1132  hid_t space_hid = H5Dget_space (data_hid);
1133  hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
1134  if (rank != 1)
1135  {
1136  H5Dclose (data_hid);
1137  H5Gclose (group_id);
1138  return false;
1139  }
1140 
1141  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
1142  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
1143 
1144  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
1145 
1146  // Octave uses column-major, while HDF5 uses row-major ordering.
1147 
1148  dv.resize (hdims[0]);
1149 
1150  OCTAVE_LOCAL_BUFFER (octave_idx_type, tmp, hdims[0]);
1151 
1152  if (H5Dread (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL, octave_H5S_ALL,
1153  octave_H5P_DEFAULT, tmp) < 0)
1154  {
1155  H5Dclose (data_hid);
1156  H5Gclose (group_id);
1157  return false;
1158  }
1159 
1160  H5Dclose (data_hid);
1161  H5Gclose (group_id);
1162 
1163  for (hsize_t i = 0, j = hdims[0] - 1; i < hdims[0]; i++, j--)
1164  dv(j) = tmp[i];
1165 
1166  hdf5_callback_data dsub;
1167 
1168  herr_t retval2 = -1;
1169 
1170  Cell m (dv);
1171 
1172  int current_item = 0;
1173 
1174  hsize_t num_obj = 0;
1175 #if defined (HAVE_HDF5_18)
1176  group_id = H5Gopen (loc_id, name, octave_H5P_DEFAULT);
1177 #else
1178  group_id = H5Gopen (loc_id, name);
1179 #endif
1180  H5Gget_num_objs (group_id, &num_obj);
1181  H5Gclose (group_id);
1182 
1183  for (octave_idx_type i = 0; i < dv.numel (); i++)
1184  {
1185 
1186  if (current_item >= static_cast<int> (num_obj))
1187  retval2 = -1;
1188  else
1189  retval2 = hdf5_h5g_iterate (loc_id, name, &current_item,&dsub);
1190 
1191  if (retval2 <= 0)
1192  break;
1193 
1194  octave_value ov = dsub.tc;
1195  m.elem (i) = ov;
1196 
1197  }
1198 
1199  if (retval2 >= 0)
1200  {
1201  matrix = m;
1202  retval = true;
1203  }
1204 
1205 #else
1206  octave_unused_parameter (loc_id);
1207  octave_unused_parameter (name);
1208 
1209  warn_load ("hdf5");
1210 #endif
1211 
1212  return retval;
1213 }
1214 
1215 DEFUN (iscell, args, ,
1216  doc: /* -*- texinfo -*-
1217 @deftypefn {} {} iscell (@var{x})
1218 Return true if @var{x} is a cell array object.
1219 @seealso{ismatrix, isstruct, iscellstr, isa}
1220 @end deftypefn */)
1221 {
1222  if (args.length () != 1)
1223  print_usage ();
1224 
1225  return ovl (args(0).iscell ());
1226 }
1227 
1228 DEFUN (cell, args, ,
1229  doc: /* -*- texinfo -*-
1230 @deftypefn {} {} cell (@var{n})
1231 @deftypefnx {} {} cell (@var{m}, @var{n})
1232 @deftypefnx {} {} cell (@var{m}, @var{n}, @var{k}, @dots{})
1233 @deftypefnx {} {} cell ([@var{m} @var{n} @dots{}])
1234 Create a new cell array object.
1235 
1236 If invoked with a single scalar integer argument, return a square
1237 @nospell{NxN} cell array. If invoked with two or more scalar integer
1238 arguments, or a vector of integer values, return an array with the given
1239 dimensions.
1240 @seealso{cellstr, mat2cell, num2cell, struct2cell}
1241 @end deftypefn */)
1242 {
1243  int nargin = args.length ();
1244 
1245  dim_vector dims;
1246 
1247  switch (nargin)
1248  {
1249  case 0:
1250  dims = dim_vector (0, 0);
1251  break;
1252 
1253  case 1:
1254  octave::get_dimensions (args(0), "cell", dims);
1255  break;
1256 
1257  default:
1258  {
1259  dims.resize (nargin);
1260 
1261  for (int i = 0; i < nargin; i++)
1262  dims(i) = (args(i).isempty ()
1263  ? 0 : args(i).xidx_type_value ("cell: dimension must be a scalar integer"));
1264  }
1265  break;
1266  }
1267 
1268  dims.chop_trailing_singletons ();
1269 
1270  octave::check_dimensions (dims, "cell");
1271 
1272  return ovl (Cell (dims));
1273 }
1274 
1275 /*
1276 ## This might work on some system someday, but for now, who has a system
1277 ## where a 16 yottabyte array can be allocated? See bug #50934.
1278 %!error <out of memory> cell (1e24, 1);
1279 */
1280 
1281 DEFUN (iscellstr, args, ,
1282  doc: /* -*- texinfo -*-
1283 @deftypefn {} {} iscellstr (@var{cell})
1284 Return true if every element of the cell array @var{cell} is a character
1285 string.
1286 @seealso{ischar, isstring}
1287 @end deftypefn */)
1288 {
1289  if (args.length () != 1)
1290  print_usage ();
1291 
1292  return ovl (args(0).iscellstr ());
1293 }
1294 
1295 DEFUN (cellstr, args, ,
1296  doc: /* -*- texinfo -*-
1297 @deftypefn {} {@var{cstr} =} cellstr (@var{strmat})
1298 Create a new cell array object from the elements of the string array
1299 @var{strmat}.
1300 
1301 Each row of @var{strmat} becomes an element of @var{cstr}. Any trailing
1302 spaces in a row are deleted before conversion.
1303 
1304 To convert back from a cellstr to a character array use @code{char}.
1305 @seealso{cell, char}
1306 @end deftypefn */)
1307 {
1308  if (args.length () != 1)
1309  print_usage ();
1310 
1311  octave_value_list tmp = Fiscellstr (args, 1);
1312 
1313  if (tmp(0).is_true ())
1314  return ovl (args(0));
1315  else
1316  {
1317  string_vector s = args(0).xstring_vector_value ("cellstr: argument STRING must be a 2-D character array");
1318 
1319  return ovl (s.isempty () ? Cell (octave_value (""))
1320  : Cell (s, true));
1321  }
1322 }
1323 
1324 DEFUN (struct2cell, args, ,
1325  doc: /* -*- texinfo -*-
1326 @deftypefn {} {@var{c} =} struct2cell (@var{s})
1327 Create a new cell array from the objects stored in the struct object.
1328 
1329 If @var{f} is the number of fields in the structure, the resulting cell
1330 array will have a dimension vector corresponding to
1331 @code{[@var{f} size(@var{s})]}. For example:
1332 
1333 @example
1334 @group
1335 s = struct ("name", @{"Peter", "Hannah", "Robert"@},
1336  "age", @{23, 16, 3@});
1337 c = struct2cell (s)
1338  @result{} c = @{2x1x3 Cell Array@}
1339 c(1,1,:)(:)
1340  @result{}
1341  @{
1342  [1,1] = Peter
1343  [2,1] = Hannah
1344  [3,1] = Robert
1345  @}
1346 c(2,1,:)(:)
1347  @result{}
1348  @{
1349  [1,1] = 23
1350  [2,1] = 16
1351  [3,1] = 3
1352  @}
1353 @end group
1354 @end example
1355 
1356 @seealso{cell2struct, namedargs2cell, fieldnames}
1357 @end deftypefn */)
1358 {
1359  if (args.length () != 1)
1360  print_usage ();
1361 
1362  const octave_map m = args(0).xmap_value ("struct2cell: argument S must be a structure");
1363 
1364  const dim_vector m_dv = m.dims ();
1365 
1366  octave_idx_type num_fields = m.nfields ();
1367 
1368  // The resulting dim_vector should have dimensions:
1369  // [numel(fields) size(struct)]
1370  // except if the struct is a column vector.
1371 
1372  dim_vector result_dv;
1373  if (m_dv(m_dv.ndims () - 1) == 1)
1374  result_dv.resize (m_dv.ndims ());
1375  else
1376  result_dv.resize (m_dv.ndims () + 1); // Add 1 for the fields.
1377 
1378  result_dv(0) = num_fields;
1379 
1380  for (int i = 1; i < result_dv.ndims (); i++)
1381  result_dv(i) = m_dv(i-1);
1382 
1383  Cell c (result_dv);
1384 
1385  octave_idx_type n_elts = m.numel ();
1386 
1387  // Fill c in one sweep. Note that thanks to octave_map structure,
1388  // we don't need a key lookup at all.
1389  for (octave_idx_type j = 0; j < n_elts; j++)
1390  for (octave_idx_type i = 0; i < num_fields; i++)
1391  c.xelem (i,j) = m.contents(i)(j);
1392 
1393  return ovl (c);
1394 }
1395 
1396 /*
1397 %!test
1398 %! keys = cellstr (char (floor (rand (11,10)*24+65)))';
1399 %! vals = cellfun (@(x) mat2cell (rand (19,1), ones (19,1), 1), ...
1400 %! mat2cell ([1:11]', ones (11,1), 1), "uniformoutput", false)';
1401 %! s = struct ([keys; vals]{:});
1402 %! t = cell2struct ([vals{:}], keys, 2);
1403 %! assert (s, t);
1404 %! assert (struct2cell (s), [vals{:}]');
1405 %! assert (fieldnames (s), keys');
1406 */
1407 
1408 mxArray *
1410 {
1411  mxArray *retval = new mxArray (dims ());
1412 
1413  mxArray **elts = static_cast<mxArray **> (retval->get_data ());
1414 
1415  mwSize nel = numel ();
1416 
1417  const octave_value *p = matrix.data ();
1418 
1419  for (mwIndex i = 0; i < nel; i++)
1420  elts[i] = new mxArray (p[i]);
1421 
1422  return retval;
1423 }
1424 
1427 {
1428  switch (umap)
1429  {
1430 #define FORWARD_MAPPER(UMAP) \
1431  case umap_ ## UMAP: \
1432  return matrix.UMAP ()
1433 
1434  FORWARD_MAPPER (xisalnum);
1435  FORWARD_MAPPER (xisalpha);
1437  FORWARD_MAPPER (xiscntrl);
1438  FORWARD_MAPPER (xisdigit);
1439  FORWARD_MAPPER (xisgraph);
1440  FORWARD_MAPPER (xislower);
1441  FORWARD_MAPPER (xisprint);
1442  FORWARD_MAPPER (xispunct);
1443  FORWARD_MAPPER (xisspace);
1444  FORWARD_MAPPER (xisupper);
1445  FORWARD_MAPPER (xisxdigit);
1446  FORWARD_MAPPER (xtolower);
1447  FORWARD_MAPPER (xtoupper);
1448 
1449  default:
1450  return octave_base_value::map (umap);
1451  }
1452 }
void swap_bytes< 4 >(void *ptr)
Definition: byte-swap.h:63
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Sort by rows returns only indices.
Definition: Array.cc:2066
Array< T > sort(int dim=0, sortmode mode=ASCENDING) const
Size of the specified dimension.
Definition: Array.cc:1757
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array.cc:1011
sortmode issorted(sortmode mode=UNSORTED) const
Ordering is auto-detected or can be specified.
Definition: Array.cc:2034
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:469
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
T & elem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:499
void make_unique(void)
Definition: Array.h:188
size_t byte_size(void) const
Size of the specified dimension.
Definition: Array.h:449
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:581
octave_idx_type cols(void) const
Definition: Array.h:423
octave_idx_type rows(void) const
Definition: Array.h:415
sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Ordering is auto-detected or can be specified.
Definition: Array.cc:2084
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:453
int ndims(void) const
Size of the specified dimension.
Definition: Array.h:589
void * mex_get_data(void) const
Give a pointer to the data in mex format.
Definition: Array.h:705
bool isempty(void) const
Size of the specified dimension.
Definition: Array.h:572
Definition: Cell.h:43
bool iscellstr(void) const
Definition: Cell.cc:126
Cell reshape(const dim_vector &new_dims) const
Definition: Cell.h:119
Array< std::string > cellstr_value(void) const
Definition: Cell.cc:145
Cell index(const octave_value_list &idx, bool resize_ok=false) const
Definition: Cell.cc:171
string_vector string_vector_value(void) const
Definition: Cell.cc:158
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
std::string str(char sep='x') const
Definition: dim-vector.cc:85
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:401
void resize(int n, int fill_value=0)
Definition: dim-vector.h:349
void chop_trailing_singletons(void)
Definition: dim-vector.h:241
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:334
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:245
virtual octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov-base.cc:201
bool fast_elem_insert(octave_idx_type n, const octave_value &x)
Definition: ov-base-mat.cc:554
octave_idx_type numel(void) const
Definition: ov-base-mat.h:114
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov-base-mat.cc:133
virtual void assign(const std::string &, const octave_value &)
Definition: ov-base.h:302
void delete_elements(const octave_value_list &idx)
Definition: ov-base-mat.cc:393
octave_value fast_elem_extract(octave_idx_type n) const
Definition: ov-base-mat.cc:544
std::string edit_display(const float_display_format &fmt, octave_idx_type i, octave_idx_type j) const
Definition: ov-base-mat.cc:533
dim_vector dims(void) const
Definition: ov-base-mat.h:112
octave_idx_type columns(void) const
Definition: ov-base.h:325
octave::refcount< octave_idx_type > count
Definition: ov-base.h:860
void decrement_indent_level(void) const
Definition: ov-base.h:844
void increment_indent_level(void) const
Definition: ov-base.h:841
void indent(std::ostream &os) const
Definition: ov-base.cc:1302
void newline(std::ostream &os) const
Definition: ov-base.cc:1321
virtual octave_value map(unary_mapper_t) const
Definition: ov-base.cc:1114
void warn_load(const char *type) const
Definition: ov-base.cc:1090
octave_idx_type rows(void) const
Definition: ov-base.h:318
virtual bool is_magic_colon(void) const
Definition: ov-base.h:405
friend class octave_value
Definition: ov-base.h:228
void warn_save(const char *type) const
Definition: ov-base.cc:1099
bool isempty(void) const
Definition: ov-base.h:357
mxArray * as_mxArray(void) const
Definition: ov-cell.cc:1409
Cell cell_value(void) const
Definition: ov-cell.h:137
bool print_as_scalar(void) const
Definition: ov-cell.cc:641
size_t byte_size(void) const
Definition: ov-cell.cc:462
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: ov-cell.cc:250
void short_disp(std::ostream &os) const
Definition: ov-cell.cc:729
octave_value map(unary_mapper_t umap) const
Definition: ov-cell.cc:1426
sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Definition: ov-cell.cc:540
void print(std::ostream &os, bool pr_as_read_syntax=false)
Definition: ov-cell.cc:647
octave_value sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
Definition: ov-cell.cc:473
std::unique_ptr< Array< std::string > > cellstr_cache
Definition: ov-cell.h:186
bool save_binary(std::ostream &os, bool save_as_floats)
Definition: ov-cell.cc:890
bool print_name_tag(std::ostream &os, const std::string &name) const
Definition: ov-cell.cc:710
virtual void assign(const std::string &, const octave_value &)
Definition: ov-base.h:302
bool save_ascii(std::ostream &os)
Definition: ov-cell.cc:737
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
Definition: ov-cell.cc:1103
void * mex_get_data(void) const
Definition: ov-cell.cc:991
void delete_elements(const octave_value_list &idx)
Definition: ov-cell.cc:455
bool load_ascii(std::istream &is)
Definition: ov-cell.cc:791
string_vector string_vector_value(bool pad=false) const
Definition: ov-cell.cc:567
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Definition: ov-cell.cc:525
void clear_cellstr_cache(void) const
Definition: ov-cell.h:183
sortmode issorted(sortmode mode=UNSORTED) const
Definition: ov-cell.cc:510
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition: ov-cell.cc:653
Array< std::string > cellstr_value(void) const
Definition: ov-cell.cc:629
octave_cell(void)
Definition: ov-cell.h:54
octave_value_list list_value(void) const
Definition: ov-cell.cc:561
bool is_true(void) const
Definition: ov-cell.cc:555
std::string type_name(void) const
Definition: ov-cell.h:188
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
Definition: ov-cell.cc:998
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
Definition: ov-cell.cc:923
bool iscellstr(void) const
Definition: ov-cell.cc:424
octave_idx_type length(void) const
Definition: ovl.h:113
bool all_scalars(void) const
Definition: ovl.cc:188
bool iscell(void) const
Definition: ov.h:560
void print_with_name(std::ostream &os, const std::string &name) const
Definition: ov.h:1239
static octave_value empty_conv(const std::string &type, const octave_value &rhs=octave_value())
Definition: ov.cc:2887
bool is_cs_list(void) const
Definition: ov.h:626
bool is_defined(void) const
Definition: ov.h:551
Cell cell_value(void) const
bool isnull(void) const
Definition: ov.h:632
bool is_zero_by_zero(void) const
Definition: ov.h:515
octave_value storable_value(void) const
void make_unique(void)
Definition: ov.h:336
octave_value_list list_value(void) const
std::string type_name(void) const
Definition: ov.h:1254
dim_vector dims(void) const
Definition: ov.h:500
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
bool isempty(void) const
Definition: str-vec.h:102
octave_idx_type max_length(void) const
Definition: str-vec.h:79
octave_idx_type numel(void) const
Definition: str-vec.h:100
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5S_ALL
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void error(const char *fmt,...)
Definition: error.cc:968
#define panic_impossible()
Definition: error.h:380
void err_nonbraced_cs_list_assignment(void)
Definition: errwarn.cc:89
void err_indexed_cs_list(void)
Definition: errwarn.cc:65
QString name
F77_RET_T const F77_DBLE * x
int save_hdf5_empty(octave_hdf5_id loc_id, const char *name, const dim_vector &d)
Definition: ls-hdf5.cc:1224
int load_hdf5_empty(octave_hdf5_id loc_id, const char *name, dim_vector &d)
Definition: ls-hdf5.cc:1280
octave_hdf5_err hdf5_h5g_iterate(octave_hdf5_id loc_id, const char *name, int *idx, void *operator_data)
Definition: ls-hdf5.cc:1034
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)
Definition: ls-hdf5.cc:1380
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)
Definition: ls-oct-text.cc:287
std::string extract_keyword(std::istream &is, const char *keyword, const bool next_only)
Definition: ls-oct-text.cc:84
bool save_text_data(std::ostream &os, const octave_value &val_arg, const std::string &name, bool mark_global, int precision)
Definition: ls-oct-text.cc:363
void mxArray
Definition: mex.h:58
bool is_true(const std::string &s)
T octave_idx_type m
Definition: mx-inlines.cc:773
octave_idx_type n
Definition: mx-inlines.cc:753
OCTAVE_IDX_TYPE mwSize
Definition: mxarray.in.h:97
OCTAVE_IDX_TYPE mwIndex
Definition: mxarray.in.h:98
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:130
void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)
Definition: utils.cc:1197
static void check_dimensions(octave_idx_type &nr, octave_idx_type &nc, const char *warnfor)
Definition: utils.cc:1166
int64_t octave_hdf5_id
#define H5T_NATIVE_IDX
Definition: oct-hdf5.h:42
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
sortmode
Definition: oct-sort.h:95
@ UNSORTED
Definition: oct-sort.h:95
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:180
OCTAVE_EXPORT octave_value_list Fiscellstr(const octave_value_list &args, int)
Definition: ov-cell.cc:1287
#define CELL_ELT_TAG
Definition: ov-cell.cc:734
#define FORWARD_MAPPER(UMAP)
static int xisascii(int c)
Definition: ov-ch-mat.cc:246
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
bool Vprint_empty_dimensions
Definition: pr-output.cc:71
octave_value tc
Definition: ls-hdf5.h:114