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 /*