Mercurial > hg > octave-nkf
comparison src/ov-struct.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 | b0f803b5ce41 |
comparison
equal
deleted
inserted
replaced
8550:1cb63ac13934 | 8551:906f976d35a8 |
---|---|
51 DEFINE_OCTAVE_ALLOCATOR(octave_struct); | 51 DEFINE_OCTAVE_ALLOCATOR(octave_struct); |
52 | 52 |
53 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct", "struct"); | 53 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct", "struct"); |
54 | 54 |
55 Cell | 55 Cell |
56 octave_struct::dotref (const octave_value_list& idx) | 56 octave_struct::dotref (const octave_value_list& idx, bool auto_add) |
57 { | 57 { |
58 Cell retval; | 58 Cell retval; |
59 | 59 |
60 assert (idx.length () == 1); | 60 assert (idx.length () == 1); |
61 | 61 |
63 | 63 |
64 Octave_map::const_iterator p = map.seek (nm); | 64 Octave_map::const_iterator p = map.seek (nm); |
65 | 65 |
66 if (p != map.end ()) | 66 if (p != map.end ()) |
67 retval = map.contents (p); | 67 retval = map.contents (p); |
68 else | 68 else if (auto_add) |
69 retval = (numel () == 0) ? Cell (dim_vector (1)) : Cell (dims ()); | |
70 else | |
69 error ("structure has no member `%s'", nm.c_str ()); | 71 error ("structure has no member `%s'", nm.c_str ()); |
70 | 72 |
71 return retval; | 73 return retval; |
72 } | 74 } |
73 | 75 |
117 | 119 |
118 Cell tmp = dotref (key_idx); | 120 Cell tmp = dotref (key_idx); |
119 | 121 |
120 if (! error_state) | 122 if (! error_state) |
121 { | 123 { |
122 Cell t = tmp.index (idx.front (), true); | 124 Cell t = tmp.index (idx.front ()); |
123 | 125 |
124 retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true); | 126 retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true); |
125 | 127 |
126 // We handled two index elements, so tell | 128 // We handled two index elements, so tell |
127 // next_subsref to skip both of them. | 129 // next_subsref to skip both of them. |
128 | 130 |
129 skip++; | 131 skip++; |
130 } | 132 } |
131 } | 133 } |
132 else | 134 else |
133 retval(0) = map.index (idx.front (), false); | 135 retval(0) = map.index (idx.front ()); |
134 } | 136 } |
135 break; | 137 break; |
136 | 138 |
137 case '.': | 139 case '.': |
138 { | 140 { |
157 // octave_value_list::next_subsref member function? See also | 159 // octave_value_list::next_subsref member function? See also |
158 // octave_user_function::subsref. | 160 // octave_user_function::subsref. |
159 | 161 |
160 if (idx.size () > 1) | 162 if (idx.size () > 1) |
161 retval = retval(0).next_subsref (nargout, type, idx, skip); | 163 retval = retval(0).next_subsref (nargout, type, idx, skip); |
164 | |
165 return retval; | |
166 } | |
167 | |
168 octave_value | |
169 octave_struct::subsref (const std::string& type, | |
170 const std::list<octave_value_list>& idx, | |
171 bool auto_add) | |
172 { | |
173 octave_value retval; | |
174 | |
175 int skip = 1; | |
176 | |
177 switch (type[0]) | |
178 { | |
179 case '(': | |
180 { | |
181 if (type.length () > 1 && type[1] == '.') | |
182 { | |
183 std::list<octave_value_list>::const_iterator p = idx.begin (); | |
184 octave_value_list key_idx = *++p; | |
185 | |
186 Cell tmp = dotref (key_idx, auto_add); | |
187 | |
188 if (! error_state) | |
189 { | |
190 Cell t = tmp.index (idx.front (), auto_add); | |
191 | |
192 retval = (t.length () == 1) ? t(0) : octave_value (t, true); | |
193 | |
194 // We handled two index elements, so tell | |
195 // next_subsref to skip both of them. | |
196 | |
197 skip++; | |
198 } | |
199 } | |
200 else | |
201 retval = map.index (idx.front (), auto_add); | |
202 } | |
203 break; | |
204 | |
205 case '.': | |
206 { | |
207 if (map.numel() > 0) | |
208 { | |
209 Cell t = dotref (idx.front (), auto_add); | |
210 | |
211 retval = (t.length () == 1) ? t(0) : octave_value (t, true); | |
212 } | |
213 } | |
214 break; | |
215 | |
216 case '{': | |
217 gripe_invalid_index_type (type_name (), type[0]); | |
218 break; | |
219 | |
220 default: | |
221 panic_impossible (); | |
222 } | |
223 | |
224 // FIXME -- perhaps there should be an | |
225 // octave_value_list::next_subsref member function? See also | |
226 // octave_user_function::subsref. | |
227 | |
228 if (idx.size () > 1) | |
229 retval = retval.next_subsref (auto_add, type, idx, skip); | |
162 | 230 |
163 return retval; | 231 return retval; |
164 } | 232 } |
165 | 233 |
166 /* | 234 /* |