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