Mercurial > octave
annotate src/ov-cell.cc @ 8551:906f976d35a8
further improve struct&cell indexing & indexed assignment
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 21 Jan 2009 13:02:49 +0100 |
parents | 3d8a914c580e |
children | 7e0f36dfefbe |
rev | line source |
---|---|
3353 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007 |
4 John W. Eaton | |
3353 | 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 | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
3353 | 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 | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
3353 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
5850 | 28 #include <iomanip> |
3503 | 29 #include <iostream> |
5765 | 30 #include <sstream> |
5164 | 31 #include <vector> |
3353 | 32 |
5360 | 33 #include "Array-util.h" |
34 #include "byte-swap.h" | |
3353 | 35 #include "lo-utils.h" |
4153 | 36 #include "quit.h" |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
8290
diff
changeset
|
37 #include "oct-locbuf.h" |
3353 | 38 |
39 #include "defun.h" | |
40 #include "error.h" | |
41 #include "ov-cell.h" | |
3354 | 42 #include "oct-obj.h" |
3353 | 43 #include "unwind-prot.h" |
3354 | 44 #include "utils.h" |
3928 | 45 #include "ov-base-mat.h" |
46 #include "ov-base-mat.cc" | |
47 #include "ov-re-mat.h" | |
48 #include "ov-scalar.h" | |
5360 | 49 #include "pr-output.h" |
50 #include "ov-scalar.h" | |
3928 | 51 |
4687 | 52 #include "ls-oct-ascii.h" |
53 #include "ls-oct-binary.h" | |
54 #include "ls-hdf5.h" | |
55 #include "ls-utils.h" | |
56 | |
3928 | 57 template class octave_base_matrix<Cell>; |
3353 | 58 |
59 DEFINE_OCTAVE_ALLOCATOR (octave_cell); | |
60 | |
4612 | 61 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cell, "cell", "cell"); |
3353 | 62 |
6833 | 63 static void |
64 gripe_failed_assignment (void) | |
65 { | |
66 error ("assignment to cell array failed"); | |
67 } | |
68 | |
7651
443a8f5a50fd
require both subsref variants to be defined in octave_value subclasses
John W. Eaton <jwe@octave.org>
parents:
7622
diff
changeset
|
69 octave_value_list |
4247 | 70 octave_cell::subsref (const std::string& type, |
7651
443a8f5a50fd
require both subsref variants to be defined in octave_value subclasses
John W. Eaton <jwe@octave.org>
parents:
7622
diff
changeset
|
71 const std::list<octave_value_list>& idx, |
443a8f5a50fd
require both subsref variants to be defined in octave_value subclasses
John W. Eaton <jwe@octave.org>
parents:
7622
diff
changeset
|
72 int nargout) |
3933 | 73 { |
7651
443a8f5a50fd
require both subsref variants to be defined in octave_value subclasses
John W. Eaton <jwe@octave.org>
parents:
7622
diff
changeset
|
74 octave_value_list retval; |
3933 | 75 |
76 switch (type[0]) | |
77 { | |
78 case '(': | |
7651
443a8f5a50fd
require both subsref variants to be defined in octave_value subclasses
John W. Eaton <jwe@octave.org>
parents:
7622
diff
changeset
|
79 retval(0) = do_index_op (idx.front ()); |
3933 | 80 break; |
81 | |
82 case '{': | |
83 { | |
84 octave_value tmp = do_index_op (idx.front ()); | |
85 | |
4582 | 86 if (! error_state) |
3933 | 87 { |
4582 | 88 Cell tcell = tmp.cell_value (); |
89 | |
90 if (tcell.length () == 1) | |
7651
443a8f5a50fd
require both subsref variants to be defined in octave_value subclasses
John W. Eaton <jwe@octave.org>
parents:
7622
diff
changeset
|
91 retval(0) = tcell(0,0); |
4582 | 92 else |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
93 retval = octave_value (octave_value_list (tcell), true); |
3933 | 94 } |
95 } | |
96 break; | |
97 | |
98 case '.': | |
99 { | |
100 std::string nm = type_name (); | |
101 error ("%s cannot be indexed with %c", nm.c_str (), type[0]); | |
102 } | |
103 break; | |
104 | |
105 default: | |
106 panic_impossible (); | |
107 } | |
108 | |
5775 | 109 // FIXME -- perhaps there should be an |
4994 | 110 // octave_value_list::next_subsref member function? See also |
111 // octave_user_function::subsref. | |
112 | |
113 if (idx.size () > 1) | |
7651
443a8f5a50fd
require both subsref variants to be defined in octave_value subclasses
John W. Eaton <jwe@octave.org>
parents:
7622
diff
changeset
|
114 retval = retval(0).next_subsref (nargout, type, idx); |
4994 | 115 |
116 return retval; | |
3933 | 117 } |
118 | |
119 octave_value | |
8551
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
120 octave_cell::subsref (const std::string& type, |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
121 const std::list<octave_value_list>& idx, |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
122 bool auto_add) |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
123 { |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
124 octave_value retval; |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
125 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
126 switch (type[0]) |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
127 { |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
128 case '(': |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
129 retval = do_index_op (idx.front (), auto_add); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
130 break; |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
131 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
132 case '{': |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
133 { |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
134 octave_value tmp = do_index_op (idx.front (), auto_add); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
135 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
136 if (! error_state) |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
137 { |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
138 Cell tcell = tmp.cell_value (); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
139 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
140 if (tcell.length () == 1) |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
141 retval = tcell(0,0); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
142 else |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
143 retval = octave_value (octave_value_list (tcell), auto_add); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
144 } |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
145 } |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
146 break; |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
147 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
148 case '.': |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
149 { |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
150 std::string nm = type_name (); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
151 error ("%s cannot be indexed with %c", nm.c_str (), type[0]); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
152 } |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
153 break; |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
154 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
155 default: |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
156 panic_impossible (); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
157 } |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
158 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
159 // FIXME -- perhaps there should be an |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
160 // octave_value_list::next_subsref member function? See also |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
161 // octave_user_function::subsref. |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
162 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
163 if (idx.size () > 1) |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
164 retval = retval.next_subsref (auto_add, type, idx); |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
165 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
166 return retval; |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
167 } |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
168 |
906f976d35a8
further improve struct&cell indexing & indexed assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8546
diff
changeset
|
169 octave_value |
4247 | 170 octave_cell::subsasgn (const std::string& type, |
4219 | 171 const std::list<octave_value_list>& idx, |
3933 | 172 const octave_value& rhs) |
173 { | |
174 octave_value retval; | |
175 | |
176 int n = type.length (); | |
177 | |
178 octave_value t_rhs = rhs; | |
179 | |
180 if (n > 1) | |
181 { | |
182 switch (type[0]) | |
183 { | |
184 case '(': | |
185 { | |
6767 | 186 if (is_empty () && type[1] == '.') |
187 { | |
188 // Allow conversion of empty cell array to some other | |
189 // type in cases like | |
190 // | |
191 // x = []; x(i).f = rhs | |
3933 | 192 |
6767 | 193 octave_value tmp = octave_value::empty_conv (type, rhs); |
3933 | 194 |
6767 | 195 return tmp.subsasgn (type, idx, rhs); |
196 } | |
197 else | |
3933 | 198 { |
6767 | 199 octave_value tmp = do_index_op (idx.front (), true); |
3933 | 200 |
6767 | 201 if (! tmp.is_defined ()) |
202 tmp = octave_value::empty_conv (type.substr (1), rhs); | |
3933 | 203 |
6767 | 204 if (! error_state) |
205 { | |
206 std::list<octave_value_list> next_idx (idx); | |
4362 | 207 |
6767 | 208 next_idx.erase (next_idx.begin ()); |
209 | |
210 tmp.make_unique (); | |
211 | |
212 t_rhs = tmp.subsasgn (type.substr (1), next_idx, rhs); | |
213 } | |
3933 | 214 } |
215 } | |
216 break; | |
217 | |
218 case '{': | |
219 { | |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
220 Cell tmpc = matrix.index (idx.front (), true); |
3933 | 221 |
4362 | 222 if (! error_state) |
223 { | |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
224 std::list<octave_value_list> next_idx (idx); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
225 |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
226 next_idx.erase (next_idx.begin ()); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
227 |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
228 std::string next_type = type.substr (1); |
3933 | 229 |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
230 if (rhs.is_cs_list ()) |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
231 { |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
232 const octave_value_list rhsl = rhs.list_value (); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
233 if (tmpc.numel () == rhsl.length ()) |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
234 { |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
235 for (octave_idx_type k = 0; k < tmpc.numel () && ! error_state; k++) |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
236 { |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
237 octave_value tmp = tmpc (k); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
238 if (! tmp.is_defined () || tmp.is_zero_by_zero ()) |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
239 { |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
240 tmp = octave_value::empty_conv (next_type, rhs); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
241 tmp.make_unique (); // probably a no-op. |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
242 } |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
243 else |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
244 // optimization: ignore the copy still stored inside our array and in tmpc. |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
245 tmp.make_unique (2); |
4362 | 246 |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
247 tmpc(k) = tmp.subsasgn (next_type, next_idx, rhsl(k)); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
248 } |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
249 |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
250 t_rhs = octave_value (octave_value_list (tmpc), true); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
251 } |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
252 else |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
253 error ("invalid cs-list length in assignment"); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
254 } |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
255 else if (tmpc.numel () == 1) |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
256 { |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
257 octave_value tmp = tmpc(0); |
3933 | 258 |
5927 | 259 if (! tmp.is_defined () || tmp.is_zero_by_zero ()) |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
260 { |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
261 tmp = octave_value::empty_conv (type.substr (1), rhs); |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
262 tmp.make_unique (); // probably a no-op. |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
263 } |
8452
d6a349c7bd39
fix {} assigment if error occurs on subsequent assignment component
Jaroslav Hajek <highegg@gmail.com>
parents:
8446
diff
changeset
|
264 else |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
265 // optimization: ignore the copy still stored inside our array and in tmpc. |
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
266 tmp.make_unique (2); |
4519 | 267 |
268 if (! error_state) | |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
269 t_rhs = tmp.subsasgn (next_type, next_idx, rhs); |
4362 | 270 } |
8446
7b25349b32e6
avoid redundant copying in {} assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
271 else |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
272 error ("invalid assignment to cs-list outside multiple assignment."); |
3933 | 273 } |
274 } | |
275 break; | |
276 | |
277 case '.': | |
278 { | |
279 std::string nm = type_name (); | |
280 error ("%s cannot be indexed with %c", nm.c_str (), type[0]); | |
281 } | |
282 break; | |
283 | |
284 default: | |
285 panic_impossible (); | |
286 } | |
287 } | |
288 | |
3940 | 289 if (! error_state) |
3933 | 290 { |
3940 | 291 switch (type[0]) |
292 { | |
293 case '(': | |
294 { | |
295 octave_value_list i = idx.front (); | |
3933 | 296 |
3940 | 297 if (t_rhs.is_cell ()) |
298 octave_base_matrix<Cell>::assign (i, t_rhs.cell_value ()); | |
299 else | |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7813
diff
changeset
|
300 if (t_rhs.is_null_value ()) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7813
diff
changeset
|
301 octave_base_matrix<Cell>::delete_elements (i); |
4941 | 302 else |
303 octave_base_matrix<Cell>::assign (i, Cell (t_rhs)); | |
3933 | 304 |
6833 | 305 if (! error_state) |
306 { | |
307 count++; | |
308 retval = octave_value (this); | |
309 } | |
310 else | |
311 gripe_failed_assignment (); | |
3940 | 312 } |
313 break; | |
3933 | 314 |
3940 | 315 case '{': |
316 { | |
317 octave_value_list i = idx.front (); | |
3933 | 318 |
5846 | 319 if (t_rhs.is_cs_list ()) |
320 { | |
321 Cell tmp_cell = Cell (t_rhs.list_value ()); | |
322 | |
7040 | 323 // The shape of the RHS is irrelevant, we just want |
324 // the number of elements to agree and to preserve the | |
325 // shape of the left hand side of the assignment. | |
326 | |
327 if (numel () == tmp_cell.numel ()) | |
328 tmp_cell = tmp_cell.reshape (dims ()); | |
5846 | 329 |
330 octave_base_matrix<Cell>::assign (i, tmp_cell); | |
331 } | |
8457
c72207960242
minor simplifications to latest patches
Jaroslav Hajek <highegg@gmail.com>
parents:
8455
diff
changeset
|
332 else if (i.all_scalars () || do_index_op (i, true).numel () == 1) |
8455
fd11a08a9b31
disallow invalid {}-indexed assigments
Jaroslav Hajek <highegg@gmail.com>
parents:
8452
diff
changeset
|
333 // Regularize a null matrix if stored into a cell. |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8457
diff
changeset
|
334 octave_base_matrix<Cell>::assign (i, Cell (t_rhs.storable_value ())); |
8455
fd11a08a9b31
disallow invalid {}-indexed assigments
Jaroslav Hajek <highegg@gmail.com>
parents:
8452
diff
changeset
|
335 else if (! error_state) |
8546
3d8a914c580e
improve parser indexed assigment code
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
336 error ("invalid assignment to cs-list outside multiple assignment."); |
3933 | 337 |
6833 | 338 if (! error_state) |
339 { | |
340 count++; | |
341 retval = octave_value (this); | |
342 } | |
343 else | |
344 gripe_failed_assignment (); | |
3940 | 345 } |
346 break; | |
3933 | 347 |
3940 | 348 case '.': |
349 { | |
350 std::string nm = type_name (); | |
351 error ("%s cannot be indexed with %c", nm.c_str (), type[0]); | |
352 } | |
353 break; | |
3933 | 354 |
3940 | 355 default: |
356 panic_impossible (); | |
357 } | |
3933 | 358 } |
359 | |
360 return retval; | |
361 } | |
362 | |
3353 | 363 void |
364 octave_cell::assign (const octave_value_list& idx, const octave_value& rhs) | |
365 { | |
3928 | 366 if (rhs.is_cell ()) |
367 octave_base_matrix<Cell>::assign (idx, rhs.cell_value ()); | |
3353 | 368 else |
3928 | 369 octave_base_matrix<Cell>::assign (idx, Cell (rhs)); |
3353 | 370 } |
371 | |
4791 | 372 size_t |
373 octave_cell::byte_size (void) const | |
374 { | |
375 size_t retval = 0; | |
376 | |
5275 | 377 for (octave_idx_type i = 0; i < numel (); i++) |
4791 | 378 retval += matrix(i).byte_size (); |
379 | |
380 return retval; | |
381 } | |
382 | |
3933 | 383 octave_value_list |
384 octave_cell::list_value (void) const | |
385 { | |
386 octave_value_list retval; | |
387 | |
5275 | 388 octave_idx_type nr = rows (); |
389 octave_idx_type nc = columns (); | |
3933 | 390 |
391 if (nr == 1 && nc > 0) | |
392 { | |
393 retval.resize (nc); | |
394 | |
5275 | 395 for (octave_idx_type i = 0; i < nc; i++) |
3933 | 396 retval(i) = matrix(0,i); |
397 } | |
398 else if (nc == 1 && nr > 0) | |
399 { | |
400 retval.resize (nr); | |
401 | |
5275 | 402 for (octave_idx_type i = 0; i < nr; i++) |
3933 | 403 retval(i) = matrix(i,0); |
404 } | |
405 else | |
406 error ("invalid conversion from cell array to list"); | |
407 | |
408 return retval; | |
409 } | |
410 | |
4243 | 411 string_vector |
5715 | 412 octave_cell::all_strings (bool pad) const |
4243 | 413 { |
4358 | 414 string_vector retval; |
415 | |
7285 | 416 octave_idx_type nel = numel (); |
4243 | 417 |
4358 | 418 int n_elts = 0; |
419 | |
5275 | 420 octave_idx_type max_len = 0; |
4358 | 421 |
7285 | 422 for (octave_idx_type i = 0; i < nel; i++) |
4358 | 423 { |
7285 | 424 string_vector s = matrix(i).all_strings (); |
425 | |
426 if (error_state) | |
427 return retval; | |
4358 | 428 |
7285 | 429 octave_idx_type s_len = s.length (); |
4358 | 430 |
7285 | 431 n_elts += s_len ? s_len : 1; |
4358 | 432 |
7285 | 433 octave_idx_type s_max_len = s.max_length (); |
4358 | 434 |
7285 | 435 if (s_max_len > max_len) |
436 max_len = s_max_len; | |
4358 | 437 } |
438 | |
439 retval.resize (n_elts); | |
4243 | 440 |
5275 | 441 octave_idx_type k = 0; |
4243 | 442 |
7285 | 443 for (octave_idx_type i = 0; i < nel; i++) |
4243 | 444 { |
7285 | 445 string_vector s = matrix(i).all_strings (); |
446 | |
447 octave_idx_type s_len = s.length (); | |
4358 | 448 |
7285 | 449 if (s_len) |
450 { | |
451 for (octave_idx_type j = 0; j < s_len; j++) | |
5715 | 452 { |
7285 | 453 std::string t = s[j]; |
5715 | 454 int t_len = t.length (); |
455 | |
456 if (pad && max_len > t_len) | |
457 t += std::string (max_len - t_len, ' '); | |
458 | |
459 retval[k++] = t; | |
460 } | |
4243 | 461 } |
7285 | 462 else if (pad) |
463 retval[k++] = std::string (max_len, ' '); | |
464 else | |
465 retval[k++] = std::string (); | |
4243 | 466 } |
467 | |
468 return retval; | |
469 } | |
470 | |
4604 | 471 bool |
472 octave_cell::print_as_scalar (void) const | |
473 { | |
474 return (ndims () > 2 || numel () == 0); | |
475 } | |
476 | |
3933 | 477 void |
478 octave_cell::print (std::ostream& os, bool) const | |
479 { | |
480 print_raw (os); | |
481 } | |
482 | |
483 void | |
484 octave_cell::print_raw (std::ostream& os, bool) const | |
485 { | |
4587 | 486 int nd = matrix.ndims (); |
4513 | 487 |
4587 | 488 if (nd == 2) |
4513 | 489 { |
5275 | 490 octave_idx_type nr = rows (); |
491 octave_idx_type nc = columns (); | |
4513 | 492 |
493 if (nr > 0 && nc > 0) | |
494 { | |
495 indent (os); | |
496 os << "{"; | |
497 newline (os); | |
498 | |
499 increment_indent_level (); | |
500 | |
5275 | 501 for (octave_idx_type j = 0; j < nc; j++) |
4513 | 502 { |
5275 | 503 for (octave_idx_type i = 0; i < nr; i++) |
4513 | 504 { |
505 OCTAVE_QUIT; | |
506 | |
5765 | 507 std::ostringstream buf; |
508 buf << "[" << i+1 << "," << j+1 << "]"; | |
3933 | 509 |
4513 | 510 octave_value val = matrix(i,j); |
511 | |
5765 | 512 val.print_with_name (os, buf.str ()); |
4513 | 513 } |
514 } | |
515 | |
516 decrement_indent_level (); | |
517 | |
518 indent (os); | |
519 os << "}"; | |
520 newline (os); | |
521 } | |
522 else | |
523 { | |
524 os << "{}"; | |
5360 | 525 if (Vprint_empty_dimensions) |
4513 | 526 os << "(" << nr << "x" << nc << ")"; |
527 os << "\n"; | |
528 } | |
529 } | |
530 else | |
3933 | 531 { |
532 indent (os); | |
4513 | 533 dim_vector dv = matrix.dims (); |
4587 | 534 os << "{" << dv.str () << " Cell Array}"; |
3933 | 535 newline (os); |
536 } | |
537 } | |
538 | |
4687 | 539 #define CELL_ELT_TAG "<cell-element>" |
540 | |
541 bool | |
6974 | 542 octave_cell::save_ascii (std::ostream& os) |
4687 | 543 { |
544 dim_vector d = dims (); | |
545 if (d.length () > 2) | |
546 { | |
547 os << "# ndims: " << d.length () << "\n"; | |
548 | |
5275 | 549 for (int i = 0; i < d.length (); i++) |
4687 | 550 os << " " << d (i); |
551 os << "\n"; | |
552 | |
553 Cell tmp = cell_value (); | |
554 | |
5275 | 555 for (octave_idx_type i = 0; i < d.numel (); i++) |
4687 | 556 { |
557 octave_value o_val = tmp.elem (i); | |
558 | |
559 // Recurse to print sub-value. | |
6974 | 560 bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, false, 0); |
4687 | 561 |
562 if (! b) | |
563 return os; | |
564 } | |
565 } | |
566 else | |
567 { | |
568 // Keep this case, rather than use generic code above for backward | |
569 // compatiability. Makes load_ascii much more complex!! | |
570 os << "# rows: " << rows () << "\n" | |
571 << "# columns: " << columns () << "\n"; | |
572 | |
573 Cell tmp = cell_value (); | |
574 | |
5275 | 575 for (octave_idx_type j = 0; j < tmp.cols (); j++) |
4687 | 576 { |
5275 | 577 for (octave_idx_type i = 0; i < tmp.rows (); i++) |
4687 | 578 { |
579 octave_value o_val = tmp.elem (i, j); | |
580 | |
581 // Recurse to print sub-value. | |
6974 | 582 bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, false, 0); |
4687 | 583 |
584 if (! b) | |
585 return os; | |
586 } | |
587 | |
588 os << "\n"; | |
589 } | |
590 } | |
591 | |
592 return true; | |
593 } | |
594 | |
595 bool | |
596 octave_cell::load_ascii (std::istream& is) | |
597 { | |
598 bool success = true; | |
5099 | 599 |
600 string_vector keywords(2); | |
4687 | 601 |
5099 | 602 keywords[0] = "ndims"; |
603 keywords[1] = "rows"; | |
604 | |
605 std::string kw; | |
5275 | 606 octave_idx_type val = 0; |
5099 | 607 |
608 if (extract_keyword (is, keywords, kw, val, true)) | |
4687 | 609 { |
5099 | 610 if (kw == "ndims") |
4687 | 611 { |
5275 | 612 int mdims = static_cast<int> (val); |
4687 | 613 |
5099 | 614 if (mdims >= 0) |
615 { | |
616 dim_vector dv; | |
617 dv.resize (mdims); | |
618 | |
619 for (int i = 0; i < mdims; i++) | |
620 is >> dv(i); | |
4687 | 621 |
5099 | 622 Cell tmp(dv); |
4687 | 623 |
5275 | 624 for (octave_idx_type i = 0; i < dv.numel (); i++) |
5099 | 625 { |
626 octave_value t2; | |
627 bool dummy; | |
628 | |
629 // recurse to read cell elements | |
630 std::string nm = read_ascii_data (is, std::string (), | |
5759 | 631 dummy, t2, i); |
4687 | 632 |
5099 | 633 if (nm == CELL_ELT_TAG) |
634 { | |
635 if (is) | |
636 tmp.elem (i) = t2; | |
637 } | |
638 else | |
639 { | |
640 error ("load: cell array element had unexpected name"); | |
641 success = false; | |
642 break; | |
643 } | |
644 } | |
4687 | 645 |
5099 | 646 if (is) |
647 matrix = tmp; | |
4687 | 648 else |
649 { | |
5099 | 650 error ("load: failed to load matrix constant"); |
4687 | 651 success = false; |
652 } | |
653 } | |
654 else | |
655 { | |
5099 | 656 error ("load: failed to extract number of rows and columns"); |
657 success = false; | |
658 } | |
659 } | |
660 else if (kw == "rows") | |
661 { | |
5275 | 662 octave_idx_type nr = val; |
663 octave_idx_type nc = 0; | |
5099 | 664 |
665 if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0) | |
666 { | |
667 if (nr > 0 && nc > 0) | |
668 { | |
669 Cell tmp (nr, nc); | |
670 | |
5275 | 671 for (octave_idx_type j = 0; j < nc; j++) |
5099 | 672 { |
5275 | 673 for (octave_idx_type i = 0; i < nr; i++) |
5099 | 674 { |
675 octave_value t2; | |
676 bool dummy; | |
677 | |
678 // recurse to read cell elements | |
679 std::string nm = read_ascii_data (is, std::string (), | |
5759 | 680 dummy, t2, i); |
5099 | 681 |
682 if (nm == CELL_ELT_TAG) | |
683 { | |
684 if (is) | |
685 tmp.elem (i, j) = t2; | |
686 } | |
687 else | |
688 { | |
689 error ("load: cell array element had unexpected name"); | |
690 success = false; | |
691 goto cell_read_error; | |
692 } | |
693 } | |
694 } | |
695 | |
696 cell_read_error: | |
697 | |
698 if (is) | |
699 matrix = tmp; | |
700 else | |
701 { | |
702 error ("load: failed to load cell element"); | |
703 success = false; | |
704 } | |
705 } | |
706 else if (nr == 0 || nc == 0) | |
707 matrix = Cell (nr, nc); | |
708 else | |
709 panic_impossible (); | |
710 } | |
711 else | |
712 { | |
713 error ("load: failed to extract number of rows and columns for cell array"); | |
4687 | 714 success = false; |
715 } | |
716 } | |
717 else | |
5099 | 718 panic_impossible (); |
4687 | 719 } |
720 else | |
721 { | |
5099 | 722 error ("load: failed to extract number of rows and columns"); |
723 success = false; | |
4687 | 724 } |
725 | |
726 return success; | |
727 } | |
728 | |
729 bool | |
730 octave_cell::save_binary (std::ostream& os, bool& save_as_floats) | |
731 { | |
732 dim_vector d = dims (); | |
733 if (d.length () < 1) | |
734 return false; | |
735 | |
736 // Use negative value for ndims | |
5828 | 737 int32_t di = - d.length(); |
5760 | 738 os.write (reinterpret_cast<char *> (&di), 4); |
5275 | 739 for (int i = 0; i < d.length (); i++) |
4687 | 740 { |
741 di = d(i); | |
5760 | 742 os.write (reinterpret_cast<char *> (&di), 4); |
4687 | 743 } |
744 | |
745 Cell tmp = cell_value (); | |
746 | |
5275 | 747 for (octave_idx_type i = 0; i < d.numel (); i++) |
4687 | 748 { |
749 octave_value o_val = tmp.elem (i); | |
750 | |
751 // Recurse to print sub-value. | |
752 bool b = save_binary_data (os, o_val, CELL_ELT_TAG, "", 0, | |
753 save_as_floats); | |
754 | |
755 if (! b) | |
756 return false; | |
757 } | |
758 | |
759 return true; | |
760 } | |
761 | |
762 bool | |
763 octave_cell::load_binary (std::istream& is, bool swap, | |
764 oct_mach_info::float_format fmt) | |
765 { | |
766 bool success = true; | |
5828 | 767 int32_t mdims; |
5760 | 768 if (! is.read (reinterpret_cast<char *> (&mdims), 4)) |
4687 | 769 return false; |
770 if (swap) | |
4944 | 771 swap_bytes<4> (&mdims); |
4687 | 772 if (mdims >= 0) |
773 return false; | |
774 | |
775 mdims = -mdims; | |
5828 | 776 int32_t di; |
4687 | 777 dim_vector dv; |
778 dv.resize (mdims); | |
779 | |
780 for (int i = 0; i < mdims; i++) | |
781 { | |
5760 | 782 if (! is.read (reinterpret_cast<char *> (&di), 4)) |
4687 | 783 return false; |
784 if (swap) | |
4944 | 785 swap_bytes<4> (&di); |
4687 | 786 dv(i) = di; |
787 } | |
788 | |
5157 | 789 // Convert an array with a single dimension to be a row vector. |
790 // Octave should never write files like this, other software | |
791 // might. | |
792 | |
793 if (mdims == 1) | |
794 { | |
795 mdims = 2; | |
796 dv.resize (mdims); | |
797 dv(1) = dv(0); | |
798 dv(0) = 1; | |
799 } | |
800 | |
5275 | 801 octave_idx_type nel = dv.numel (); |
4687 | 802 Cell tmp(dv); |
803 | |
5275 | 804 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 805 { |
806 octave_value t2; | |
807 bool dummy; | |
808 std::string doc; | |
809 | |
810 // recurse to read cell elements | |
811 std::string nm = read_binary_data (is, swap, fmt, std::string (), | |
812 dummy, t2, doc); | |
813 | |
814 if (nm == CELL_ELT_TAG) | |
815 { | |
816 if (is) | |
817 tmp.elem (i) = t2; | |
818 } | |
819 else | |
820 { | |
821 error ("load: cell array element had unexpected name"); | |
822 success = false; | |
823 break; | |
824 } | |
825 } | |
826 | |
827 if (is) | |
828 matrix = tmp; | |
829 else | |
830 { | |
831 error ("load: failed to load matrix constant"); | |
832 success = false; | |
833 } | |
834 | |
835 return success; | |
836 } | |
837 | |
838 #if defined (HAVE_HDF5) | |
4815 | 839 |
4687 | 840 bool |
841 octave_cell::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats) | |
842 { | |
4814 | 843 dim_vector dv = dims (); |
4837 | 844 int empty = save_hdf5_empty (loc_id, name, dv); |
845 if (empty) | |
846 return (empty > 0); | |
847 | |
4815 | 848 hsize_t rank = dv.length (); |
4687 | 849 hid_t space_hid = -1, data_hid = -1, size_hid = -1; |
850 | |
851 data_hid = H5Gcreate (loc_id, name, 0); | |
4815 | 852 |
853 if (data_hid < 0) | |
854 return false; | |
4687 | 855 |
4814 | 856 // Have to save cell array shape, since can't have a |
857 // dataset of groups.... | |
4815 | 858 |
859 space_hid = H5Screate_simple (1, &rank, 0); | |
860 | |
4687 | 861 if (space_hid < 0) |
862 { | |
863 H5Gclose (data_hid); | |
864 return false; | |
865 } | |
866 | |
5351 | 867 OCTAVE_LOCAL_BUFFER (octave_idx_type, hdims, rank); |
4814 | 868 |
869 // Octave uses column-major, while HDF5 uses row-major ordering | |
4933 | 870 for (hsize_t i = 0; i < rank; i++) |
4815 | 871 hdims[i] = dv(rank-i-1); |
4814 | 872 |
5351 | 873 size_hid = H5Dcreate (data_hid, "dims", H5T_NATIVE_IDX, space_hid, |
4687 | 874 H5P_DEFAULT); |
875 if (size_hid < 0) | |
876 { | |
877 H5Sclose (space_hid); | |
878 H5Gclose (data_hid); | |
879 return false; | |
880 } | |
881 | |
6276 | 882 if (H5Dwrite (size_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, |
883 H5P_DEFAULT, hdims) < 0) | |
4687 | 884 { |
885 H5Dclose (size_hid); | |
886 H5Sclose (space_hid); | |
887 H5Gclose (data_hid); | |
888 return false; | |
889 } | |
4815 | 890 |
4687 | 891 H5Dclose (size_hid); |
892 H5Sclose (space_hid); | |
893 | |
4815 | 894 // Recursively add each element of the cell to this group. |
895 | |
4687 | 896 Cell tmp = cell_value (); |
5850 | 897 |
898 octave_idx_type nel = dv.numel (); | |
899 | |
900 for (octave_idx_type i = 0; i < nel; i++) | |
4687 | 901 { |
5765 | 902 std::ostringstream buf; |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7285
diff
changeset
|
903 int digits = static_cast<int> (::floor (::log10 (static_cast<double> (nel)) + 1.0)); |
5850 | 904 buf << "_" << std::setw (digits) << std::setfill ('0') << i; |
5765 | 905 std::string s = buf.str (); |
4687 | 906 |
5850 | 907 if (! add_hdf5_data (data_hid, tmp.elem (i), s.c_str (), "", false, |
908 save_as_floats)) | |
4814 | 909 { |
910 H5Gclose (data_hid); | |
911 return false; | |
4687 | 912 } |
913 } | |
914 | |
915 H5Gclose (data_hid); | |
4815 | 916 |
4687 | 917 return true; |
918 } | |
919 | |
920 bool | |
921 octave_cell::load_hdf5 (hid_t loc_id, const char *name, | |
922 bool have_h5giterate_bug) | |
923 { | |
924 bool retval = false; | |
4837 | 925 |
926 dim_vector dv; | |
927 int empty = load_hdf5_empty (loc_id, name, dv); | |
928 if (empty > 0) | |
929 matrix.resize(dv); | |
930 if (empty) | |
931 return (empty > 0); | |
932 | |
4687 | 933 hid_t group_id = H5Gopen (loc_id, name); |
934 | |
935 if (group_id < 0) | |
936 return false; | |
937 | |
4814 | 938 hid_t data_hid = H5Dopen (group_id, "dims"); |
4687 | 939 hid_t space_hid = H5Dget_space (data_hid); |
940 hsize_t rank = H5Sget_simple_extent_ndims (space_hid); | |
4814 | 941 if (rank != 1) |
4687 | 942 { |
4837 | 943 H5Dclose (data_hid); |
944 H5Gclose (group_id); | |
4687 | 945 return false; |
946 } | |
947 | |
4814 | 948 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); |
949 OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank); | |
4815 | 950 |
4814 | 951 H5Sget_simple_extent_dims (space_hid, hdims, maxdims); |
4687 | 952 |
4815 | 953 // Octave uses column-major, while HDF5 uses row-major ordering. |
954 | |
4814 | 955 dv.resize (hdims[0]); |
4815 | 956 |
5351 | 957 OCTAVE_LOCAL_BUFFER (octave_idx_type, tmp, hdims[0]); |
4814 | 958 |
5351 | 959 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, |
4815 | 960 H5P_DEFAULT, tmp) < 0) |
4687 | 961 { |
4837 | 962 H5Dclose (data_hid); |
963 H5Gclose (group_id); | |
4687 | 964 return false; |
965 } | |
4815 | 966 |
4687 | 967 H5Dclose (data_hid); |
968 H5Gclose (group_id); | |
969 | |
4815 | 970 for (hsize_t i = 0, j = hdims[0] - 1; i < hdims[0]; i++, j--) |
4814 | 971 dv(j) = tmp[i]; |
972 | |
4687 | 973 hdf5_callback_data dsub; |
974 | |
975 herr_t retval2 = -1; | |
4815 | 976 |
4814 | 977 Cell m (dv); |
4815 | 978 |
4687 | 979 int current_item = 0; |
4815 | 980 |
4687 | 981 if (have_h5giterate_bug) |
4815 | 982 current_item = 1; // Skip dims items in group. |
4687 | 983 |
4696 | 984 #ifdef HAVE_H5GGET_NUM_OBJS |
985 hsize_t num_obj = 0; | |
5060 | 986 group_id = H5Gopen (loc_id, name); |
987 H5Gget_num_objs (group_id, &num_obj); | |
988 H5Gclose (group_id); | |
4696 | 989 #endif |
990 | |
5275 | 991 for (octave_idx_type i = 0; i < dv.numel (); i++) |
4687 | 992 { |
4696 | 993 |
994 #ifdef HAVE_H5GGET_NUM_OBJS | |
4814 | 995 if (current_item >= static_cast<int> (num_obj)) |
996 retval2 = -1; | |
997 else | |
4696 | 998 #endif |
4814 | 999 retval2 = H5Giterate (loc_id, name, ¤t_item, |
1000 hdf5_read_next_data, &dsub); | |
1001 | |
4687 | 1002 if (retval2 <= 0) |
1003 break; | |
4814 | 1004 |
1005 octave_value ov = dsub.tc; | |
1006 m.elem (i) = ov; | |
1007 | |
1008 if (have_h5giterate_bug) | |
4815 | 1009 current_item++; // H5Giterate returned the last index processed. |
4814 | 1010 |
4687 | 1011 } |
1012 | |
1013 if (retval2 >= 0) | |
1014 { | |
1015 matrix = m; | |
1016 retval = true; | |
1017 } | |
1018 | |
1019 return retval; | |
1020 } | |
4815 | 1021 |
4687 | 1022 #endif |
1023 | |
3354 | 1024 DEFUN (iscell, args, , |
3448 | 1025 "-*- texinfo -*-\n\ |
1026 @deftypefn {Built-in Function} {} iscell (@var{x})\n\ | |
1027 Return true if @var{x} is a cell array object. Otherwise, return\n\ | |
1028 false.\n\ | |
1029 @end deftypefn") | |
3354 | 1030 { |
1031 octave_value retval; | |
1032 | |
1033 if (args.length () == 1) | |
1034 retval = args(0).is_cell (); | |
1035 else | |
5823 | 1036 print_usage (); |
3354 | 1037 |
1038 return retval; | |
1039 } | |
1040 | |
1041 DEFUN (cell, args, , | |
3448 | 1042 "-*- texinfo -*-\n\ |
1043 @deftypefn {Built-in Function} {} cell (@var{x})\n\ | |
1044 @deftypefnx {Built-in Function} {} cell (@var{n}, @var{m})\n\ | |
1045 Create a new cell array object. If invoked with a single scalar\n\ | |
1046 argument, @code{cell} returns a square cell array with the dimension\n\ | |
1047 specified. If you supply two scalar arguments, @code{cell} takes\n\ | |
1048 them to be the number of rows and columns. If given a vector with two\n\ | |
1049 elements, @code{cell} uses the values of the elements as the number of\n\ | |
1050 rows and columns, respectively.\n\ | |
1051 @end deftypefn") | |
3354 | 1052 { |
1053 octave_value retval; | |
1054 | |
1055 int nargin = args.length (); | |
1056 | |
4563 | 1057 dim_vector dims; |
1058 | |
3354 | 1059 switch (nargin) |
1060 { | |
4563 | 1061 case 0: |
1062 dims = dim_vector (0, 0); | |
3354 | 1063 break; |
1064 | |
4563 | 1065 case 1: |
1066 get_dimensions (args(0), "cell", dims); | |
3354 | 1067 break; |
1068 | |
1069 default: | |
4563 | 1070 { |
1071 dims.resize (nargin); | |
1072 | |
1073 for (int i = 0; i < nargin; i++) | |
1074 { | |
1075 dims(i) = args(i).is_empty () ? 0 : args(i).nint_value (); | |
1076 | |
1077 if (error_state) | |
1078 { | |
1079 error ("cell: expecting scalar arguments"); | |
1080 break; | |
1081 } | |
1082 } | |
1083 } | |
3354 | 1084 break; |
1085 } | |
1086 | |
4563 | 1087 if (! error_state) |
1088 { | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8150
diff
changeset
|
1089 dims.chop_trailing_singletons (); |
4563 | 1090 |
1091 check_dimensions (dims, "cell"); | |
1092 | |
1093 if (! error_state) | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8150
diff
changeset
|
1094 retval = Cell (dims, Matrix ()); |
4563 | 1095 } |
1096 | |
3354 | 1097 return retval; |
1098 } | |
1099 | |
4610 | 1100 DEFUN (iscellstr, args, , |
1101 "-*- texinfo -*-\n\ | |
1102 @deftypefn {Built-in Function} {} iscellstr (@var{cell})\n\ | |
1103 Return true if every element of the cell array @var{cell} is a\n\ | |
1104 character string\n\ | |
1105 @end deftypefn") | |
1106 { | |
4699 | 1107 octave_value retval; |
4610 | 1108 |
1109 if (args.length () == 1) | |
6116 | 1110 retval = args(0).is_cellstr (); |
4610 | 1111 else |
5823 | 1112 print_usage (); |
4610 | 1113 |
1114 return retval; | |
1115 } | |
1116 | |
4817 | 1117 // Note that since Fcellstr calls Fiscellstr, we need to have |
1118 // Fiscellstr defined first (to provide a declaration) and also we | |
1119 // should keep it in the same file (so we don't have to provide a | |
1120 // declaration) and so we don't have to use feval to call it. | |
1121 | |
1122 DEFUN (cellstr, args, , | |
1123 "-*- texinfo -*-\n\ | |
1124 @deftypefn {Built-in Function} {} cellstr (@var{string})\n\ | |
1125 Create a new cell array object from the elements of the string\n\ | |
1126 array @var{string}.\n\ | |
1127 @end deftypefn") | |
1128 { | |
1129 octave_value retval; | |
1130 | |
1131 if (args.length () == 1) | |
1132 { | |
1133 octave_value_list tmp = Fiscellstr (args, 1); | |
1134 | |
1135 if (tmp(0).is_true ()) | |
1136 retval = args(0); | |
1137 else | |
1138 { | |
1139 string_vector s = args(0).all_strings (); | |
1140 | |
1141 if (! error_state) | |
7813 | 1142 retval = (s.is_empty () |
1143 ? Cell (octave_value (std::string ())) | |
1144 : Cell (s, true)); | |
4817 | 1145 else |
1146 error ("cellstr: expecting argument to be a 2-d character array"); | |
1147 } | |
1148 } | |
1149 else | |
5823 | 1150 print_usage (); |
4817 | 1151 |
1152 return retval; | |
1153 } | |
1154 | |
4762 | 1155 DEFUN (struct2cell, args, , |
1156 "-*- texinfo -*-\n\ | |
1157 @deftypefn {Built-in Function} {} struct2cell (@var{S})\n\ | |
1158 Create a new cell array from the objects stored in the struct object.\n\ | |
4764 | 1159 If @var{f} is the number of fields in the structure, the resulting\n\ |
1160 cell array will have a dimension vector corresponding to\n\ | |
1161 @code{[@var{F} size(@var{S})]}.\n\ | |
5642 | 1162 @seealso{cell2struct, fieldnames}\n\ |
1163 @end deftypefn") | |
4762 | 1164 { |
1165 octave_value retval; | |
4764 | 1166 |
4762 | 1167 int nargin = args.length (); |
4764 | 1168 |
4762 | 1169 if (nargin == 1) |
1170 { | |
4764 | 1171 Octave_map m = args(0).map_value (); |
1172 | |
4762 | 1173 if (! error_state) |
1174 { | |
1175 dim_vector m_dv = m.dims (); | |
4764 | 1176 |
4762 | 1177 string_vector keys = m.keys (); |
4764 | 1178 |
7760
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1179 octave_idx_type num_fields = keys.length (); |
4764 | 1180 |
4762 | 1181 // The resulting dim_vector should have dimensions: |
1182 // [numel(fields) size(struct)] | |
4764 | 1183 |
4762 | 1184 dim_vector result_dv; |
4764 | 1185 result_dv.resize (m_dv.length () + 1); // Add 1 for the fields. |
1186 | |
7760
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1187 result_dv(0) = num_fields; |
4762 | 1188 |
1189 for (int i = 1; i < result_dv.length (); i++) | |
1190 result_dv(i) = m_dv(i-1); | |
4764 | 1191 |
4762 | 1192 Cell c (result_dv); |
4764 | 1193 |
7760
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1194 octave_idx_type n_elts = m.numel (); |
4764 | 1195 |
7760
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1196 for (octave_idx_type j = 0; j < num_fields; j++) |
4762 | 1197 { |
7760
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1198 octave_idx_type k = j; |
4764 | 1199 |
7760
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1200 const Cell vals = m.contents (keys(j)); |
4764 | 1201 |
7760
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1202 for (octave_idx_type i = 0; i < n_elts; i++) |
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1203 { |
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1204 c(k) = vals(i); |
f5268d7045d7
struct2cell: handle structure arrays properly
John W. Eaton <jwe@octave.org>
parents:
7651
diff
changeset
|
1205 k += num_fields; |
4762 | 1206 } |
1207 } | |
1208 | |
1209 retval = c; | |
1210 } | |
1211 else | |
1212 error ("struct2cell: expecting argument to be a cell array"); | |
1213 } | |
1214 else | |
5823 | 1215 print_usage (); |
4764 | 1216 |
4762 | 1217 return retval; |
1218 } | |
1219 | |
5900 | 1220 mxArray * |
1221 octave_cell::as_mxArray (void) const | |
1222 { | |
1223 mxArray *retval = new mxArray (dims ()); | |
1224 | |
1225 mxArray **elts = static_cast<mxArray **> (retval->get_data ()); | |
1226 | |
6686 | 1227 mwSize nel = numel (); |
5900 | 1228 |
1229 const octave_value *p = matrix.data (); | |
1230 | |
6686 | 1231 for (mwIndex i = 0; i < nel; i++) |
5900 | 1232 elts[i] = new mxArray (p[i]); |
1233 | |
1234 return retval; | |
1235 } | |
1236 | |
3353 | 1237 /* |
1238 ;;; Local Variables: *** | |
1239 ;;; mode: C++ *** | |
1240 ;;; End: *** | |
1241 */ |