Mercurial > octave
comparison libinterp/octave-value/cdef-object.cc @ 31607:aac27ad79be6 stable
maint: Re-indent code after switch to using namespace macros.
* build-env.h, build-env.in.cc, Cell.h, __betainc__.cc, __eigs__.cc,
__ftp__.cc, __ichol__.cc, __ilu__.cc, __isprimelarge__.cc, __magick_read__.cc,
__pchip_deriv__.cc, amd.cc, base-text-renderer.cc, base-text-renderer.h,
besselj.cc, bitfcns.cc, bsxfun.cc, c-file-ptr-stream.h, call-stack.cc,
call-stack.h, ccolamd.cc, cellfun.cc, chol.cc, colamd.cc, dasrt.cc, data.cc,
debug.cc, defaults.cc, defaults.h, det.cc, display.cc, display.h, dlmread.cc,
dynamic-ld.cc, dynamic-ld.h, ellipj.cc, environment.cc, environment.h,
error.cc, error.h, errwarn.h, event-manager.cc, event-manager.h,
event-queue.cc, event-queue.h, fcn-info.cc, fcn-info.h, fft.cc, fft2.cc,
file-io.cc, filter.cc, find.cc, ft-text-renderer.cc, ft-text-renderer.h,
gcd.cc, gl-render.cc, gl-render.h, gl2ps-print.cc, gl2ps-print.h,
graphics-toolkit.cc, graphics-toolkit.h, graphics.cc, gsvd.cc, gtk-manager.cc,
gtk-manager.h, help.cc, help.h, hook-fcn.cc, hook-fcn.h, input.cc, input.h,
interpreter-private.cc, interpreter-private.h, interpreter.cc, interpreter.h,
inv.cc, jsondecode.cc, jsonencode.cc, latex-text-renderer.cc,
latex-text-renderer.h, load-path.cc, load-path.h, load-save.cc, load-save.h,
lookup.cc, ls-hdf5.cc, ls-mat4.cc, ls-mat5.cc, lsode.cc, lu.cc, mappers.cc,
matrix_type.cc, max.cc, mex.cc, mexproto.h, mxarray.h, mxtypes.in.h,
oct-errno.in.cc, oct-hdf5-types.cc, oct-hist.cc, oct-hist.h, oct-map.cc,
oct-map.h, oct-opengl.h, oct-prcstrm.h, oct-process.cc, oct-process.h,
oct-stdstrm.h, oct-stream.cc, oct-stream.h, oct-strstrm.h,
octave-default-image.h, ordqz.cc, ordschur.cc, pager.cc, pager.h, pinv.cc,
pow2.cc, pr-output.cc, psi.cc, qr.cc, quadcc.cc, rand.cc, regexp.cc,
settings.cc, settings.h, sighandlers.cc, sighandlers.h, sparse-xpow.cc,
sqrtm.cc, stack-frame.cc, stack-frame.h, stream-euler.cc, strfns.cc, svd.cc,
syminfo.cc, syminfo.h, symrcm.cc, symrec.cc, symrec.h, symscope.cc, symscope.h,
symtab.cc, symtab.h, sysdep.cc, sysdep.h, text-engine.cc, text-engine.h,
text-renderer.cc, text-renderer.h, time.cc, toplev.cc, typecast.cc,
url-handle-manager.cc, url-handle-manager.h, urlwrite.cc, utils.cc, utils.h,
variables.cc, variables.h, xdiv.cc, __delaunayn__.cc, __init_fltk__.cc,
__init_gnuplot__.cc, __ode15__.cc, __voronoi__.cc, audioread.cc, convhulln.cc,
gzip.cc, cdef-class.cc, cdef-class.h, cdef-fwd.h, cdef-manager.cc,
cdef-manager.h, cdef-method.cc, cdef-method.h, cdef-object.cc, cdef-object.h,
cdef-package.cc, cdef-package.h, cdef-property.cc, cdef-property.h,
cdef-utils.cc, cdef-utils.h, ov-base-diag.cc, ov-base-int.cc, ov-base-mat.cc,
ov-base-mat.h, ov-base-scalar.cc, ov-base.cc, ov-base.h, ov-bool-mat.cc,
ov-bool-mat.h, ov-bool-sparse.cc, ov-bool.cc, ov-builtin.h, ov-cell.cc,
ov-ch-mat.cc, ov-class.cc, ov-class.h, ov-classdef.cc, ov-classdef.h,
ov-complex.cc, ov-cx-diag.cc, ov-cx-mat.cc, ov-cx-sparse.cc, ov-dld-fcn.cc,
ov-dld-fcn.h, ov-fcn-handle.cc, ov-fcn-handle.h, ov-fcn.h, ov-float.cc,
ov-flt-complex.cc, ov-flt-cx-diag.cc, ov-flt-cx-mat.cc, ov-flt-re-diag.cc,
ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-intx.h, ov-java.cc, ov-lazy-idx.cc,
ov-legacy-range.cc, ov-magic-int.cc, ov-mex-fcn.cc, ov-mex-fcn.h,
ov-null-mat.cc, ov-perm.cc, ov-range.cc, ov-re-diag.cc, ov-re-mat.cc,
ov-re-mat.h, ov-re-sparse.cc, ov-scalar.cc, ov-str-mat.cc, ov-struct.cc,
ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc, ov-usr-fcn.h, ov.cc, ov.h, ovl.h,
octave.cc, octave.h, op-b-sbm.cc, op-bm-sbm.cc, op-cs-scm.cc, op-fm-fcm.cc,
op-fs-fcm.cc, op-s-scm.cc, op-scm-cs.cc, op-scm-s.cc, op-sm-cs.cc, ops.h,
anon-fcn-validator.cc, anon-fcn-validator.h, bp-table.cc, bp-table.h,
comment-list.cc, comment-list.h, filepos.h, lex.h, oct-lvalue.cc, oct-lvalue.h,
parse.h, profiler.cc, profiler.h, pt-anon-scopes.cc, pt-anon-scopes.h,
pt-arg-list.cc, pt-arg-list.h, pt-args-block.cc, pt-args-block.h,
pt-array-list.cc, pt-array-list.h, pt-assign.cc, pt-assign.h, pt-binop.cc,
pt-binop.h, pt-bp.cc, pt-bp.h, pt-cbinop.cc, pt-cbinop.h, pt-cell.cc,
pt-cell.h, pt-check.cc, pt-check.h, pt-classdef.cc, pt-classdef.h, pt-cmd.h,
pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h,
pt-eval.cc, pt-eval.h, pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h,
pt-fcn-handle.cc, pt-fcn-handle.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h,
pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h,
pt-pr-code.cc, pt-pr-code.h, pt-select.cc, pt-select.h, pt-spmd.cc, pt-spmd.h,
pt-stmt.cc, pt-stmt.h, pt-tm-const.cc, pt-tm-const.h, pt-unop.cc, pt-unop.h,
pt-walk.cc, pt-walk.h, pt.cc, pt.h, token.cc, token.h, Range.cc, Range.h,
idx-vector.cc, idx-vector.h, range-fwd.h, CollocWt.cc, CollocWt.h,
aepbalance.cc, aepbalance.h, chol.cc, chol.h, gepbalance.cc, gepbalance.h,
gsvd.cc, gsvd.h, hess.cc, hess.h, lo-mappers.cc, lo-mappers.h, lo-specfun.cc,
lo-specfun.h, lu.cc, lu.h, oct-convn.cc, oct-convn.h, oct-fftw.cc, oct-fftw.h,
oct-norm.cc, oct-norm.h, oct-rand.cc, oct-rand.h, oct-spparms.cc,
oct-spparms.h, qr.cc, qr.h, qrp.cc, qrp.h, randgamma.cc, randgamma.h,
randmtzig.cc, randmtzig.h, randpoisson.cc, randpoisson.h, schur.cc, schur.h,
sparse-chol.cc, sparse-chol.h, sparse-lu.cc, sparse-lu.h, sparse-qr.cc,
sparse-qr.h, svd.cc, svd.h, child-list.cc, child-list.h, dir-ops.cc, dir-ops.h,
file-ops.cc, file-ops.h, file-stat.cc, file-stat.h, lo-sysdep.cc, lo-sysdep.h,
lo-sysinfo.cc, lo-sysinfo.h, mach-info.cc, mach-info.h, oct-env.cc, oct-env.h,
oct-group.cc, oct-group.h, oct-password.cc, oct-password.h, oct-syscalls.cc,
oct-syscalls.h, oct-time.cc, oct-time.h, oct-uname.cc, oct-uname.h,
action-container.cc, action-container.h, base-list.h, cmd-edit.cc, cmd-edit.h,
cmd-hist.cc, cmd-hist.h, f77-fcn.h, file-info.cc, file-info.h,
lo-array-errwarn.cc, lo-array-errwarn.h, lo-hash.cc, lo-hash.h, lo-ieee.h,
lo-regexp.cc, lo-regexp.h, lo-utils.cc, lo-utils.h, oct-base64.cc,
oct-base64.h, oct-glob.cc, oct-glob.h, oct-inttypes.h, oct-mutex.cc,
oct-mutex.h, oct-refcount.h, oct-shlib.cc, oct-shlib.h, oct-sparse.cc,
oct-sparse.h, oct-string.h, octave-preserve-stream-state.h, pathsearch.cc,
pathsearch.h, quit.cc, quit.h, unwind-prot.cc, unwind-prot.h, url-transfer.cc,
url-transfer.h:
Re-indent code after switch to using namespace macros.
author | Rik <rik@octave.org> |
---|---|
date | Thu, 01 Dec 2022 18:02:15 -0800 |
parents | e88a07dec498 |
children | 597f3ee61a48 |
comparison
equal
deleted
inserted
replaced
31605:e88a07dec498 | 31607:aac27ad79be6 |
---|---|
38 // Define to 1 to enable debugging statements. | 38 // Define to 1 to enable debugging statements. |
39 #define DEBUG_TRACE 0 | 39 #define DEBUG_TRACE 0 |
40 | 40 |
41 OCTAVE_BEGIN_NAMESPACE(octave) | 41 OCTAVE_BEGIN_NAMESPACE(octave) |
42 | 42 |
43 void | 43 void |
44 cdef_object_rep::release (const cdef_object& obj) | 44 cdef_object_rep::release (const cdef_object& obj) |
45 { | 45 { |
46 // We need to be careful to keep a reference to the object if we are | 46 // We need to be careful to keep a reference to the object if we are |
47 // calling the delete method. The object is passed to the delete | 47 // calling the delete method. The object is passed to the delete |
48 // method as an argument and if the count is already zero when we | 48 // method as an argument and if the count is already zero when we |
49 // do that, then we will increment the count while creating the | 49 // do that, then we will increment the count while creating the |
50 // argument list for the delete method and then it will be decremented | 50 // argument list for the delete method and then it will be decremented |
51 // back to zero and we'll find ourselves in an infinite loop. | 51 // back to zero and we'll find ourselves in an infinite loop. |
52 | 52 |
53 if (m_count - 1 > static_count ()) | 53 if (m_count - 1 > static_count ()) |
54 { | |
55 --m_count; | |
56 return; | |
57 } | |
58 | |
59 if (is_handle_object () && ! is_meta_object ()) | |
60 { | |
61 unwind_protect frame; | |
62 | |
63 // Clear interrupts. | |
64 frame.protect_var (octave_interrupt_state); | |
65 octave_interrupt_state = 0; | |
66 | |
67 // Disallow quit(). | |
68 frame.protect_var (quit_allowed); | |
69 quit_allowed = false; | |
70 | |
71 interpreter& interp = __get_interpreter__ (); | |
72 | |
73 interpreter_try (frame); | |
74 | |
75 try | |
76 { | |
77 // Call classdef "delete()" method on object | |
78 get_class ().delete_object (obj); | |
79 } | |
80 catch (const interrupt_exception&) | |
81 { | |
82 interp.recover_from_exception (); | |
83 | |
84 warning ("interrupt occurred in handle class delete method"); | |
85 } | |
86 catch (const execution_exception& ee) | |
87 { | |
88 interp.recover_from_exception (); | |
89 | |
90 std::string msg = ee.message (); | |
91 | |
92 warning ("error caught while executing handle class delete method:\n%s\n", | |
93 msg.c_str ()); | |
94 } | |
95 catch (const exit_exception&) | |
96 { | |
97 // This shouldn't happen since we disabled quit above. | |
98 warning ("exit disabled while executing handle class delete method"); | |
99 } | |
100 catch (...) // Yes, the black hole. We're in a d-tor. | |
101 { | |
102 // This shouldn't happen, in theory. | |
103 warning ("internal error: unhandled exception in handle class delete method"); | |
104 } | |
105 } | |
106 | |
107 // Now it is safe to set the count to zero. | |
108 m_count--; | |
109 | |
110 destroy (); | |
111 } | |
112 | |
113 cdef_class | |
114 cdef_object_rep::get_class (void) const | |
115 { | |
116 err_invalid_object ("get_class"); | |
117 } | |
118 | |
119 std::string | |
120 cdef_object_rep::class_name (void) const | |
121 { | |
122 return get_class ().get_name (); | |
123 } | |
124 | |
125 string_vector | |
126 cdef_object_rep::map_keys (void) const | |
127 { | |
128 cdef_class cls = get_class (); | |
129 | |
130 if (cls.ok ()) | |
131 return cls.get_names (); | |
132 | |
133 return string_vector (); | |
134 } | |
135 | |
136 octave_map | |
137 cdef_object::map_value (void) const | |
138 { | |
139 octave_map retval; | |
140 | |
141 warning_with_id ("Octave:classdef-to-struct", | |
142 "struct: converting a classdef object into a struct " | |
143 "overrides the access restrictions defined for properties. " | |
144 "All properties are returned, including private and " | |
145 "protected ones."); | |
146 | |
147 cdef_class cls = get_class (); | |
148 | |
149 if (cls.ok ()) | |
150 { | |
151 std::map<std::string, cdef_property> props; | |
152 | |
153 props = cls.get_property_map (cdef_class::property_all); | |
154 | |
155 // FIXME: Why not const here? | |
156 for (auto& prop_val : props) | |
157 { | |
158 if (is_array ()) | |
159 { | |
160 Array<cdef_object> a_obj = array_value (); | |
161 | |
162 Cell cvalue (a_obj.dims ()); | |
163 | |
164 for (octave_idx_type i = 0; i < a_obj.numel (); i++) | |
165 cvalue (i) = prop_val.second.get_value (a_obj(i), false); | |
166 | |
167 retval.setfield (prop_val.first, cvalue); | |
168 } | |
169 else | |
170 { | |
171 Cell cvalue (dim_vector (1, 1), | |
172 prop_val.second.get_value (*this, false)); | |
173 | |
174 retval.setfield (prop_val.first, cvalue); | |
175 } | |
176 } | |
177 } | |
178 | |
179 return retval; | |
180 } | |
181 | |
182 cdef_class | |
183 cdef_object::get_class (void) const | |
184 { | |
185 return m_rep->get_class (); | |
186 } | |
187 | |
188 cdef_class | |
189 cdef_object_base::get_class (void) const | |
190 { | |
191 return cdef_class (m_klass); | |
192 } | |
193 | |
194 void | |
195 cdef_object_base::set_class (const cdef_class& cls) | |
196 { | |
197 if ((m_klass.ok () && cls.ok () && cls != get_class ()) | |
198 || (m_klass.ok () && ! cls.ok ()) | |
199 || (! m_klass.ok () && cls.ok ())) | |
200 { | |
201 m_klass = cls; | |
202 } | |
203 } | |
204 | |
205 cdef_object_rep * | |
206 cdef_object_base::make_array (void) const | |
207 { | |
208 cdef_object_rep *r = new cdef_object_array (); | |
209 | |
210 r->set_class (get_class ()); | |
211 | |
212 return r; | |
213 } | |
214 | |
215 octave_value_list | |
216 cdef_object_array::subsref (const std::string& type, | |
217 const std::list<octave_value_list>& idx, | |
218 int /* nargout */, std::size_t& skip, | |
219 const cdef_class& /* context */, bool auto_add) | |
220 { | |
221 octave_value_list retval; | |
222 | |
223 skip = 1; | |
224 | |
225 switch (type[0]) | |
226 { | |
227 case '(': | |
54 { | 228 { |
55 --m_count; | 229 const octave_value_list& ival = idx.front (); |
56 return; | 230 |
231 if (ival.empty ()) | |
232 { | |
233 m_count++; | |
234 retval(0) = to_ov (cdef_object (this)); | |
235 break; | |
236 } | |
237 | |
238 bool is_scalar = true; | |
239 Array<idx_vector> iv (dim_vector (1, ival.length ())); | |
240 | |
241 for (int i = 0; i < ival.length (); i++) | |
242 { | |
243 try | |
244 { | |
245 iv(i) = ival(i).index_vector (); | |
246 } | |
247 catch (index_exception& ie) | |
248 { | |
249 // Rethrow to allow more info to be reported later. | |
250 ie.set_pos_if_unset (ival.length (), i+1); | |
251 throw; | |
252 } | |
253 | |
254 is_scalar = is_scalar && iv(i).is_scalar (); | |
255 } | |
256 | |
257 Array<cdef_object> ires = m_array.index (iv, auto_add); | |
258 | |
259 // If resizing is enabled (auto_add = true), it's possible | |
260 // indexing was out-of-bound and the result array contains | |
261 // invalid cdef_objects. | |
262 | |
263 if (auto_add) | |
264 fill_empty_values (ires); | |
265 | |
266 if (is_scalar) | |
267 retval(0) = to_ov (ires(0)); | |
268 else | |
269 { | |
270 cdef_object array_obj (new cdef_object_array (ires)); | |
271 | |
272 array_obj.set_class (get_class ()); | |
273 | |
274 retval(0) = to_ov (array_obj); | |
275 } | |
57 } | 276 } |
58 | 277 break; |
59 if (is_handle_object () && ! is_meta_object ()) | 278 |
60 { | 279 case '.': |
61 unwind_protect frame; | 280 if (type.size () == 1 && idx.size () == 1) |
62 | 281 { |
63 // Clear interrupts. | 282 Cell c (dims ()); |
64 frame.protect_var (octave_interrupt_state); | 283 |
65 octave_interrupt_state = 0; | 284 octave_idx_type n = m_array.numel (); |
66 | 285 |
67 // Disallow quit(). | 286 // dummy variables |
68 frame.protect_var (quit_allowed); | 287 std::size_t dummy_skip; |
69 quit_allowed = false; | 288 cdef_class dummy_cls; |
70 | 289 |
71 interpreter& interp = __get_interpreter__ (); | 290 for (octave_idx_type i = 0; i < n; i++) |
72 | 291 { |
73 interpreter_try (frame); | 292 octave_value_list r = m_array(i).subsref (type, idx, 1, |
74 | 293 dummy_skip, |
75 try | 294 dummy_cls); |
76 { | 295 |
77 // Call classdef "delete()" method on object | 296 if (r.length () > 0) |
78 get_class ().delete_object (obj); | 297 c(i) = r(0); |
79 } | 298 } |
80 catch (const interrupt_exception&) | 299 |
81 { | 300 retval(0) = octave_value (c, true); |
82 interp.recover_from_exception (); | 301 |
83 | 302 break; |
84 warning ("interrupt occurred in handle class delete method"); | 303 } |
85 } | 304 OCTAVE_FALLTHROUGH; |
86 catch (const execution_exception& ee) | 305 |
87 { | 306 default: |
88 interp.recover_from_exception (); | 307 error ("can't perform indexing operation on array of %s objects", |
89 | 308 class_name ().c_str ()); |
90 std::string msg = ee.message (); | 309 break; |
91 | 310 } |
92 warning ("error caught while executing handle class delete method:\n%s\n", | 311 |
93 msg.c_str ()); | 312 return retval; |
94 } | 313 } |
95 catch (const exit_exception&) | 314 |
96 { | 315 octave_value |
97 // This shouldn't happen since we disabled quit above. | 316 cdef_object_array::subsasgn (const std::string& type, |
98 warning ("exit disabled while executing handle class delete method"); | 317 const std::list<octave_value_list>& idx, |
99 } | 318 const octave_value& rhs) |
100 catch (...) // Yes, the black hole. We're in a d-tor. | 319 { |
101 { | 320 octave_value retval; |
102 // This shouldn't happen, in theory. | 321 |
103 warning ("internal error: unhandled exception in handle class delete method"); | 322 switch (type[0]) |
104 } | 323 { |
105 } | 324 case '(': |
106 | 325 if (type.length () == 1) |
107 // Now it is safe to set the count to zero. | 326 { |
108 m_count--; | 327 cdef_object rhs_obj = to_cdef (rhs); |
109 | 328 |
110 destroy (); | 329 if (rhs_obj.get_class () != get_class ()) |
111 } | 330 error ("can't assign %s object into array of %s objects", |
112 | 331 rhs_obj.class_name ().c_str (), |
113 cdef_class | 332 class_name ().c_str ()); |
114 cdef_object_rep::get_class (void) const | 333 |
115 { | |
116 err_invalid_object ("get_class"); | |
117 } | |
118 | |
119 std::string | |
120 cdef_object_rep::class_name (void) const | |
121 { | |
122 return get_class ().get_name (); | |
123 } | |
124 | |
125 string_vector | |
126 cdef_object_rep::map_keys (void) const | |
127 { | |
128 cdef_class cls = get_class (); | |
129 | |
130 if (cls.ok ()) | |
131 return cls.get_names (); | |
132 | |
133 return string_vector (); | |
134 } | |
135 | |
136 octave_map | |
137 cdef_object::map_value (void) const | |
138 { | |
139 octave_map retval; | |
140 | |
141 warning_with_id ("Octave:classdef-to-struct", | |
142 "struct: converting a classdef object into a struct " | |
143 "overrides the access restrictions defined for properties. " | |
144 "All properties are returned, including private and " | |
145 "protected ones."); | |
146 | |
147 cdef_class cls = get_class (); | |
148 | |
149 if (cls.ok ()) | |
150 { | |
151 std::map<std::string, cdef_property> props; | |
152 | |
153 props = cls.get_property_map (cdef_class::property_all); | |
154 | |
155 // FIXME: Why not const here? | |
156 for (auto& prop_val : props) | |
157 { | |
158 if (is_array ()) | |
159 { | |
160 Array<cdef_object> a_obj = array_value (); | |
161 | |
162 Cell cvalue (a_obj.dims ()); | |
163 | |
164 for (octave_idx_type i = 0; i < a_obj.numel (); i++) | |
165 cvalue (i) = prop_val.second.get_value (a_obj(i), false); | |
166 | |
167 retval.setfield (prop_val.first, cvalue); | |
168 } | |
169 else | |
170 { | |
171 Cell cvalue (dim_vector (1, 1), | |
172 prop_val.second.get_value (*this, false)); | |
173 | |
174 retval.setfield (prop_val.first, cvalue); | |
175 } | |
176 } | |
177 } | |
178 | |
179 return retval; | |
180 } | |
181 | |
182 cdef_class | |
183 cdef_object::get_class (void) const | |
184 { | |
185 return m_rep->get_class (); | |
186 } | |
187 | |
188 cdef_class | |
189 cdef_object_base::get_class (void) const | |
190 { | |
191 return cdef_class (m_klass); | |
192 } | |
193 | |
194 void | |
195 cdef_object_base::set_class (const cdef_class& cls) | |
196 { | |
197 if ((m_klass.ok () && cls.ok () && cls != get_class ()) | |
198 || (m_klass.ok () && ! cls.ok ()) | |
199 || (! m_klass.ok () && cls.ok ())) | |
200 { | |
201 m_klass = cls; | |
202 } | |
203 } | |
204 | |
205 cdef_object_rep * | |
206 cdef_object_base::make_array (void) const | |
207 { | |
208 cdef_object_rep *r = new cdef_object_array (); | |
209 | |
210 r->set_class (get_class ()); | |
211 | |
212 return r; | |
213 } | |
214 | |
215 octave_value_list | |
216 cdef_object_array::subsref (const std::string& type, | |
217 const std::list<octave_value_list>& idx, | |
218 int /* nargout */, std::size_t& skip, | |
219 const cdef_class& /* context */, bool auto_add) | |
220 { | |
221 octave_value_list retval; | |
222 | |
223 skip = 1; | |
224 | |
225 switch (type[0]) | |
226 { | |
227 case '(': | |
228 { | |
229 const octave_value_list& ival = idx.front (); | 334 const octave_value_list& ival = idx.front (); |
230 | 335 bool is_scalar = true; |
231 if (ival.empty ()) | 336 Array<idx_vector> iv (dim_vector (1, ival.length ())); |
337 | |
338 for (int i = 0; i < ival.length (); i++) | |
232 { | 339 { |
233 m_count++; | 340 try |
234 retval(0) = to_ov (cdef_object (this)); | 341 { |
235 break; | 342 iv(i) = ival(i).index_vector (); |
343 } | |
344 catch (index_exception& ie) | |
345 { | |
346 ie.set_pos_if_unset (ival.length (), i+1); | |
347 throw; // var name set in pt-idx.cc / pt-assign.cc | |
348 } | |
349 | |
350 is_scalar = is_scalar && iv(i).is_scalar (); | |
236 } | 351 } |
237 | 352 |
353 Array<cdef_object> rhs_mat; | |
354 | |
355 if (! rhs_obj.is_array ()) | |
356 { | |
357 rhs_mat = Array<cdef_object> (dim_vector (1, 1)); | |
358 rhs_mat(0) = rhs_obj; | |
359 } | |
360 else | |
361 rhs_mat = rhs_obj.array_value (); | |
362 | |
363 octave_idx_type n = m_array.numel (); | |
364 | |
365 m_array.assign (iv, rhs_mat, cdef_object ()); | |
366 | |
367 if (m_array.numel () > n) | |
368 fill_empty_values (); | |
369 | |
370 m_count++; | |
371 retval = to_ov (cdef_object (this)); | |
372 } | |
373 else | |
374 { | |
375 const octave_value_list& ivl = idx.front (); | |
376 | |
377 // Fill in trailing singleton dimensions so that | |
378 // array.index doesn't create a new blank entry (bug #46660). | |
379 const octave_idx_type one = static_cast<octave_idx_type> (1); | |
380 const octave_value_list& ival = ivl.length () >= 2 | |
381 ? ivl : ((m_array.dims ()(0) == 1) | |
382 ? ovl (one, ivl(0)) | |
383 : ovl (ivl(0), one)); | |
384 | |
238 bool is_scalar = true; | 385 bool is_scalar = true; |
386 | |
239 Array<idx_vector> iv (dim_vector (1, ival.length ())); | 387 Array<idx_vector> iv (dim_vector (1, ival.length ())); |
240 | 388 |
241 for (int i = 0; i < ival.length (); i++) | 389 for (int i = 0; i < ival.length (); i++) |
242 { | 390 { |
243 try | 391 try |
250 ie.set_pos_if_unset (ival.length (), i+1); | 398 ie.set_pos_if_unset (ival.length (), i+1); |
251 throw; | 399 throw; |
252 } | 400 } |
253 | 401 |
254 is_scalar = is_scalar && iv(i).is_scalar (); | 402 is_scalar = is_scalar && iv(i).is_scalar (); |
403 | |
404 if (! is_scalar) | |
405 error ("subsasgn: invalid indexing for object array assignment" | |
406 ", the index must reference a single object in the " | |
407 "array."); | |
255 } | 408 } |
256 | 409 |
257 Array<cdef_object> ires = m_array.index (iv, auto_add); | 410 Array<cdef_object> a = m_array.index (iv, true); |
258 | 411 |
259 // If resizing is enabled (auto_add = true), it's possible | 412 if (a.numel () != 1) |
260 // indexing was out-of-bound and the result array contains | 413 error ("subsasgn: invalid indexing for object array assignment"); |
261 // invalid cdef_objects. | 414 |
262 | 415 cdef_object obj = a(0); |
263 if (auto_add) | 416 |
264 fill_empty_values (ires); | 417 int ignore_copies = 0; |
265 | 418 |
266 if (is_scalar) | 419 // If the object in 'a' is not valid, this means the index |
267 retval(0) = to_ov (ires(0)); | 420 // was out-of-bound and we need to create a new object. |
421 | |
422 if (! obj.ok ()) | |
423 obj = get_class ().construct_object (octave_value_list ()); | |
268 else | 424 else |
425 // Optimize the subsasgn call to come. There are 2 copies | |
426 // that we can safely ignore: | |
427 // - 1 in "array" | |
428 // - 1 in "a" | |
429 ignore_copies = 2; | |
430 | |
431 std::list<octave_value_list> next_idx (idx); | |
432 | |
433 next_idx.erase (next_idx.begin ()); | |
434 | |
435 octave_value tmp = obj.subsasgn (type.substr (1), next_idx, | |
436 rhs, ignore_copies); | |
437 | |
438 cdef_object robj = to_cdef (tmp); | |
439 | |
440 if (! robj.ok () | |
441 || robj.is_array () | |
442 || robj.get_class () != get_class ()) | |
443 error ("subsasgn: invalid assignment into array of %s objects", | |
444 class_name ().c_str ()); | |
445 | |
446 // Small optimization, when dealing with handle | |
447 // objects, we don't need to re-assign the result | |
448 // of subsasgn back into the array. | |
449 | |
450 if (! robj.is (a(0))) | |
269 { | 451 { |
270 cdef_object array_obj (new cdef_object_array (ires)); | 452 Array<cdef_object> rhs_a (dim_vector (1, 1), |
271 | 453 robj); |
272 array_obj.set_class (get_class ()); | 454 |
273 | 455 octave_idx_type n = m_array.numel (); |
274 retval(0) = to_ov (array_obj); | 456 |
457 m_array.assign (iv, rhs_a); | |
458 | |
459 if (m_array.numel () > n) | |
460 fill_empty_values (); | |
275 } | 461 } |
276 } | 462 |
277 break; | 463 m_count++; |
278 | 464 |
279 case '.': | 465 retval = to_ov (cdef_object (this)); |
280 if (type.size () == 1 && idx.size () == 1) | 466 } |
281 { | 467 break; |
282 Cell c (dims ()); | 468 |
283 | 469 default: |
284 octave_idx_type n = m_array.numel (); | 470 error ("can't perform indexing operation on array of %s objects", |
285 | 471 class_name ().c_str ()); |
286 // dummy variables | 472 break; |
287 std::size_t dummy_skip; | 473 } |
288 cdef_class dummy_cls; | 474 |
289 | 475 return retval; |
290 for (octave_idx_type i = 0; i < n; i++) | 476 } |
477 | |
478 void | |
479 cdef_object_array::fill_empty_values (Array<cdef_object>& arr) | |
480 { | |
481 cdef_class cls = get_class (); | |
482 | |
483 cdef_object obj; | |
484 | |
485 int n = arr.numel (); | |
486 | |
487 for (int i = 0; i < n; i++) | |
488 { | |
489 if (! arr.xelem (i).ok ()) | |
490 { | |
491 if (! obj.ok ()) | |
492 { | |
493 obj = cls.construct_object (octave_value_list ()); | |
494 | |
495 arr.xelem (i) = obj; | |
496 } | |
497 else | |
498 arr.xelem (i) = obj.copy (); | |
499 } | |
500 } | |
501 } | |
502 | |
503 void | |
504 cdef_object_scalar::break_closure_cycles (const std::shared_ptr<stack_frame>& frame) | |
505 { | |
506 for (octave_idx_type i = 0; i < m_map.nfields (); i++) | |
507 m_map.contents(i).break_closure_cycles (frame); | |
508 } | |
509 | |
510 octave_value_list | |
511 cdef_object_scalar::subsref (const std::string& type, | |
512 const std::list<octave_value_list>& idx, | |
513 int nargout, std::size_t& skip, | |
514 const cdef_class& context, bool auto_add) | |
515 { | |
516 skip = 0; | |
517 | |
518 cdef_class cls = (context.ok () ? context : get_class ()); | |
519 | |
520 octave_value_list retval; | |
521 | |
522 if (! cls.ok ()) | |
523 return retval; | |
524 | |
525 switch (type[0]) | |
526 { | |
527 case '.': | |
528 { | |
529 std::string name = (idx.front ())(0).string_value (); | |
530 | |
531 cdef_method meth = cls.find_method (name); | |
532 | |
533 if (meth.ok ()) | |
534 { | |
535 int _nargout = (type.length () > 2 ? 1 : nargout); | |
536 | |
537 octave_value_list args; | |
538 | |
539 skip = 1; | |
540 | |
541 if (type.length () > 1 && type[1] == '(') | |
291 { | 542 { |
292 octave_value_list r = m_array(i).subsref (type, idx, 1, | 543 auto it = idx.begin (); |
293 dummy_skip, | 544 |
294 dummy_cls); | 545 args = *++it; |
295 | 546 |
296 if (r.length () > 0) | 547 skip++; |
297 c(i) = r(0); | |
298 } | 548 } |
299 | 549 |
300 retval(0) = octave_value (c, true); | 550 if (meth.is_static ()) |
301 | 551 retval = meth.execute (args, _nargout, true, "subsref"); |
302 break; | 552 else |
303 } | 553 { |
304 OCTAVE_FALLTHROUGH; | 554 m_count++; |
305 | 555 retval = meth.execute (cdef_object (this), args, _nargout, |
306 default: | 556 true, "subsref"); |
307 error ("can't perform indexing operation on array of %s objects", | 557 } |
308 class_name ().c_str ()); | 558 } |
559 | |
560 if (skip == 0) | |
561 { | |
562 cdef_property prop = cls.find_property (name); | |
563 | |
564 if (! prop.ok ()) | |
565 error ("subsref: unknown method or property: %s", name.c_str ()); | |
566 | |
567 if (prop.is_constant ()) | |
568 retval(0) = prop.get_value (true, "subsref"); | |
569 else | |
570 { | |
571 m_count++; | |
572 retval(0) = prop.get_value (cdef_object (this), | |
573 true, "subsref"); | |
574 } | |
575 | |
576 skip = 1; | |
577 } | |
309 break; | 578 break; |
310 } | 579 } |
311 | 580 |
312 return retval; | 581 case '(': |
313 } | |
314 | |
315 octave_value | |
316 cdef_object_array::subsasgn (const std::string& type, | |
317 const std::list<octave_value_list>& idx, | |
318 const octave_value& rhs) | |
319 { | |
320 octave_value retval; | |
321 | |
322 switch (type[0]) | |
323 { | 582 { |
324 case '(': | 583 const octave_value_list& ival = idx.front (); |
584 | |
585 m_count++; | |
586 cdef_object this_obj (this); | |
587 | |
588 if (ival.empty ()) | |
589 { | |
590 skip++; | |
591 retval(0) = to_ov (this_obj); | |
592 } | |
593 else | |
594 { | |
595 Array<cdef_object> arr (dim_vector (1, 1), this_obj); | |
596 | |
597 cdef_object new_obj = cdef_object (new cdef_object_array (arr)); | |
598 | |
599 new_obj.set_class (get_class ()); | |
600 | |
601 retval = new_obj.subsref (type, idx, nargout, skip, cls, auto_add); | |
602 } | |
603 } | |
604 break; | |
605 | |
606 default: | |
607 error ("object cannot be indexed with '%c'", type[0]); | |
608 break; | |
609 } | |
610 | |
611 return retval; | |
612 } | |
613 | |
614 octave_value | |
615 cdef_object_scalar::subsasgn (const std::string& type, | |
616 const std::list<octave_value_list>& idx, | |
617 const octave_value& rhs) | |
618 { | |
619 octave_value retval; | |
620 | |
621 cdef_class cls = get_class (); | |
622 | |
623 switch (type[0]) | |
624 { | |
625 case '.': | |
626 { | |
627 std::string name = (idx.front ())(0).string_value (); | |
628 | |
629 cdef_property prop = cls.find_property (name); | |
630 | |
631 if (! prop.ok ()) | |
632 error ("subsasgn: unknown property: %s", name.c_str ()); | |
633 | |
634 if (prop.is_constant ()) | |
635 error ("subsasgn: cannot assign constant property: %s", | |
636 name.c_str ()); | |
637 | |
638 m_count++; | |
639 | |
640 cdef_object obj (this); | |
641 | |
325 if (type.length () == 1) | 642 if (type.length () == 1) |
326 { | 643 { |
327 cdef_object rhs_obj = to_cdef (rhs); | 644 prop.set_value (obj, rhs, true, "subsasgn"); |
328 | 645 |
329 if (rhs_obj.get_class () != get_class ()) | 646 retval = to_ov (obj); |
330 error ("can't assign %s object into array of %s objects", | |
331 rhs_obj.class_name ().c_str (), | |
332 class_name ().c_str ()); | |
333 | |
334 const octave_value_list& ival = idx.front (); | |
335 bool is_scalar = true; | |
336 Array<idx_vector> iv (dim_vector (1, ival.length ())); | |
337 | |
338 for (int i = 0; i < ival.length (); i++) | |
339 { | |
340 try | |
341 { | |
342 iv(i) = ival(i).index_vector (); | |
343 } | |
344 catch (index_exception& ie) | |
345 { | |
346 ie.set_pos_if_unset (ival.length (), i+1); | |
347 throw; // var name set in pt-idx.cc / pt-assign.cc | |
348 } | |
349 | |
350 is_scalar = is_scalar && iv(i).is_scalar (); | |
351 } | |
352 | |
353 Array<cdef_object> rhs_mat; | |
354 | |
355 if (! rhs_obj.is_array ()) | |
356 { | |
357 rhs_mat = Array<cdef_object> (dim_vector (1, 1)); | |
358 rhs_mat(0) = rhs_obj; | |
359 } | |
360 else | |
361 rhs_mat = rhs_obj.array_value (); | |
362 | |
363 octave_idx_type n = m_array.numel (); | |
364 | |
365 m_array.assign (iv, rhs_mat, cdef_object ()); | |
366 | |
367 if (m_array.numel () > n) | |
368 fill_empty_values (); | |
369 | |
370 m_count++; | |
371 retval = to_ov (cdef_object (this)); | |
372 } | 647 } |
373 else | 648 else |
374 { | 649 { |
375 const octave_value_list& ivl = idx.front (); | 650 octave_value val = prop.get_value (obj, true, "subsasgn"); |
376 | 651 |
377 // Fill in trailing singleton dimensions so that | 652 std::list<octave_value_list> args (idx); |
378 // array.index doesn't create a new blank entry (bug #46660). | 653 |
379 const octave_idx_type one = static_cast<octave_idx_type> (1); | 654 args.erase (args.begin ()); |
380 const octave_value_list& ival = ivl.length () >= 2 | 655 |
381 ? ivl : ((m_array.dims ()(0) == 1) | 656 val = val.assign (octave_value::op_asn_eq, |
382 ? ovl (one, ivl(0)) | 657 type.substr (1), args, rhs); |
383 : ovl (ivl(0), one)); | 658 |
384 | 659 if (val.class_name () != "object" |
385 bool is_scalar = true; | 660 || ! to_cdef (val).is_handle_object ()) |
386 | 661 prop.set_value (obj, val, true, "subsasgn"); |
387 Array<idx_vector> iv (dim_vector (1, ival.length ())); | 662 |
388 | 663 retval = to_ov (obj); |
389 for (int i = 0; i < ival.length (); i++) | 664 } |
390 { | |
391 try | |
392 { | |
393 iv(i) = ival(i).index_vector (); | |
394 } | |
395 catch (index_exception& ie) | |
396 { | |
397 // Rethrow to allow more info to be reported later. | |
398 ie.set_pos_if_unset (ival.length (), i+1); | |
399 throw; | |
400 } | |
401 | |
402 is_scalar = is_scalar && iv(i).is_scalar (); | |
403 | |
404 if (! is_scalar) | |
405 error ("subsasgn: invalid indexing for object array assignment" | |
406 ", the index must reference a single object in the " | |
407 "array."); | |
408 } | |
409 | |
410 Array<cdef_object> a = m_array.index (iv, true); | |
411 | |
412 if (a.numel () != 1) | |
413 error ("subsasgn: invalid indexing for object array assignment"); | |
414 | |
415 cdef_object obj = a(0); | |
416 | |
417 int ignore_copies = 0; | |
418 | |
419 // If the object in 'a' is not valid, this means the index | |
420 // was out-of-bound and we need to create a new object. | |
421 | |
422 if (! obj.ok ()) | |
423 obj = get_class ().construct_object (octave_value_list ()); | |
424 else | |
425 // Optimize the subsasgn call to come. There are 2 copies | |
426 // that we can safely ignore: | |
427 // - 1 in "array" | |
428 // - 1 in "a" | |
429 ignore_copies = 2; | |
430 | |
431 std::list<octave_value_list> next_idx (idx); | |
432 | |
433 next_idx.erase (next_idx.begin ()); | |
434 | |
435 octave_value tmp = obj.subsasgn (type.substr (1), next_idx, | |
436 rhs, ignore_copies); | |
437 | |
438 cdef_object robj = to_cdef (tmp); | |
439 | |
440 if (! robj.ok () | |
441 || robj.is_array () | |
442 || robj.get_class () != get_class ()) | |
443 error ("subsasgn: invalid assignment into array of %s objects", | |
444 class_name ().c_str ()); | |
445 | |
446 // Small optimization, when dealing with handle | |
447 // objects, we don't need to re-assign the result | |
448 // of subsasgn back into the array. | |
449 | |
450 if (! robj.is (a(0))) | |
451 { | |
452 Array<cdef_object> rhs_a (dim_vector (1, 1), | |
453 robj); | |
454 | |
455 octave_idx_type n = m_array.numel (); | |
456 | |
457 m_array.assign (iv, rhs_a); | |
458 | |
459 if (m_array.numel () > n) | |
460 fill_empty_values (); | |
461 } | |
462 | |
463 m_count++; | |
464 | |
465 retval = to_ov (cdef_object (this)); | |
466 } | |
467 break; | |
468 | |
469 default: | |
470 error ("can't perform indexing operation on array of %s objects", | |
471 class_name ().c_str ()); | |
472 break; | |
473 } | 665 } |
474 | 666 break; |
475 return retval; | 667 |
476 } | 668 case '(': |
477 | |
478 void | |
479 cdef_object_array::fill_empty_values (Array<cdef_object>& arr) | |
480 { | |
481 cdef_class cls = get_class (); | |
482 | |
483 cdef_object obj; | |
484 | |
485 int n = arr.numel (); | |
486 | |
487 for (int i = 0; i < n; i++) | |
488 { | 669 { |
489 if (! arr.xelem (i).ok ()) | 670 m_count++; |
490 { | 671 |
491 if (! obj.ok ()) | 672 cdef_object this_obj (this); |
492 { | 673 |
493 obj = cls.construct_object (octave_value_list ()); | 674 Array<cdef_object> arr (dim_vector (1, 1), this_obj); |
494 | 675 |
495 arr.xelem (i) = obj; | 676 cdef_object new_obj = cdef_object (new cdef_object_array (arr)); |
496 } | 677 |
497 else | 678 new_obj.set_class (get_class ()); |
498 arr.xelem (i) = obj.copy (); | 679 |
499 } | 680 octave_value tmp = new_obj.subsasgn (type, idx, rhs); |
681 | |
682 retval = tmp; | |
500 } | 683 } |
501 } | 684 break; |
502 | 685 |
503 void | 686 default: |
504 cdef_object_scalar::break_closure_cycles (const std::shared_ptr<stack_frame>& frame) | 687 error ("subsasgn: object cannot be index with '%c'", type[0]); |
505 { | 688 break; |
506 for (octave_idx_type i = 0; i < m_map.nfields (); i++) | 689 } |
507 m_map.contents(i).break_closure_cycles (frame); | 690 |
508 } | 691 return retval; |
509 | 692 } |
510 octave_value_list | 693 |
511 cdef_object_scalar::subsref (const std::string& type, | 694 void |
512 const std::list<octave_value_list>& idx, | 695 cdef_object_scalar::mark_for_construction (const cdef_class& cls) |
513 int nargout, std::size_t& skip, | 696 { |
514 const cdef_class& context, bool auto_add) | 697 std::string cls_name = cls.get_name (); |
515 { | 698 |
516 skip = 0; | 699 Cell supcls = cls.get ("SuperClasses").cell_value (); |
517 | 700 |
518 cdef_class cls = (context.ok () ? context : get_class ()); | 701 std::list<cdef_class> supcls_list = lookup_classes (supcls); |
519 | 702 |
520 octave_value_list retval; | 703 m_ctor_list[cls] = supcls_list; |
521 | 704 } |
522 if (! cls.ok ()) | 705 |
523 return retval; | 706 bool |
524 | 707 cdef_object_scalar::is_constructed_for (const cdef_class& cls) const |
525 switch (type[0]) | 708 { |
526 { | 709 return (is_constructed () |
527 case '.': | 710 || m_ctor_list.find (cls) == m_ctor_list.end ()); |
528 { | 711 } |
529 std::string name = (idx.front ())(0).string_value (); | 712 |
530 | 713 bool |
531 cdef_method meth = cls.find_method (name); | 714 cdef_object_scalar::is_partially_constructed_for (const cdef_class& cls) const |
532 | 715 { |
533 if (meth.ok ()) | 716 if (is_constructed ()) |
534 { | 717 return true; |
535 int _nargout = (type.length () > 2 ? 1 : nargout); | 718 |
536 | 719 std::map<cdef_class, std::list<cdef_class>>::const_iterator it |
537 octave_value_list args; | |
538 | |
539 skip = 1; | |
540 | |
541 if (type.length () > 1 && type[1] == '(') | |
542 { | |
543 auto it = idx.begin (); | |
544 | |
545 args = *++it; | |
546 | |
547 skip++; | |
548 } | |
549 | |
550 if (meth.is_static ()) | |
551 retval = meth.execute (args, _nargout, true, "subsref"); | |
552 else | |
553 { | |
554 m_count++; | |
555 retval = meth.execute (cdef_object (this), args, _nargout, | |
556 true, "subsref"); | |
557 } | |
558 } | |
559 | |
560 if (skip == 0) | |
561 { | |
562 cdef_property prop = cls.find_property (name); | |
563 | |
564 if (! prop.ok ()) | |
565 error ("subsref: unknown method or property: %s", name.c_str ()); | |
566 | |
567 if (prop.is_constant ()) | |
568 retval(0) = prop.get_value (true, "subsref"); | |
569 else | |
570 { | |
571 m_count++; | |
572 retval(0) = prop.get_value (cdef_object (this), | |
573 true, "subsref"); | |
574 } | |
575 | |
576 skip = 1; | |
577 } | |
578 break; | |
579 } | |
580 | |
581 case '(': | |
582 { | |
583 const octave_value_list& ival = idx.front (); | |
584 | |
585 m_count++; | |
586 cdef_object this_obj (this); | |
587 | |
588 if (ival.empty ()) | |
589 { | |
590 skip++; | |
591 retval(0) = to_ov (this_obj); | |
592 } | |
593 else | |
594 { | |
595 Array<cdef_object> arr (dim_vector (1, 1), this_obj); | |
596 | |
597 cdef_object new_obj = cdef_object (new cdef_object_array (arr)); | |
598 | |
599 new_obj.set_class (get_class ()); | |
600 | |
601 retval = new_obj.subsref (type, idx, nargout, skip, cls, auto_add); | |
602 } | |
603 } | |
604 break; | |
605 | |
606 default: | |
607 error ("object cannot be indexed with '%c'", type[0]); | |
608 break; | |
609 } | |
610 | |
611 return retval; | |
612 } | |
613 | |
614 octave_value | |
615 cdef_object_scalar::subsasgn (const std::string& type, | |
616 const std::list<octave_value_list>& idx, | |
617 const octave_value& rhs) | |
618 { | |
619 octave_value retval; | |
620 | |
621 cdef_class cls = get_class (); | |
622 | |
623 switch (type[0]) | |
624 { | |
625 case '.': | |
626 { | |
627 std::string name = (idx.front ())(0).string_value (); | |
628 | |
629 cdef_property prop = cls.find_property (name); | |
630 | |
631 if (! prop.ok ()) | |
632 error ("subsasgn: unknown property: %s", name.c_str ()); | |
633 | |
634 if (prop.is_constant ()) | |
635 error ("subsasgn: cannot assign constant property: %s", | |
636 name.c_str ()); | |
637 | |
638 m_count++; | |
639 | |
640 cdef_object obj (this); | |
641 | |
642 if (type.length () == 1) | |
643 { | |
644 prop.set_value (obj, rhs, true, "subsasgn"); | |
645 | |
646 retval = to_ov (obj); | |
647 } | |
648 else | |
649 { | |
650 octave_value val = prop.get_value (obj, true, "subsasgn"); | |
651 | |
652 std::list<octave_value_list> args (idx); | |
653 | |
654 args.erase (args.begin ()); | |
655 | |
656 val = val.assign (octave_value::op_asn_eq, | |
657 type.substr (1), args, rhs); | |
658 | |
659 if (val.class_name () != "object" | |
660 || ! to_cdef (val).is_handle_object ()) | |
661 prop.set_value (obj, val, true, "subsasgn"); | |
662 | |
663 retval = to_ov (obj); | |
664 } | |
665 } | |
666 break; | |
667 | |
668 case '(': | |
669 { | |
670 m_count++; | |
671 | |
672 cdef_object this_obj (this); | |
673 | |
674 Array<cdef_object> arr (dim_vector (1, 1), this_obj); | |
675 | |
676 cdef_object new_obj = cdef_object (new cdef_object_array (arr)); | |
677 | |
678 new_obj.set_class (get_class ()); | |
679 | |
680 octave_value tmp = new_obj.subsasgn (type, idx, rhs); | |
681 | |
682 retval = tmp; | |
683 } | |
684 break; | |
685 | |
686 default: | |
687 error ("subsasgn: object cannot be index with '%c'", type[0]); | |
688 break; | |
689 } | |
690 | |
691 return retval; | |
692 } | |
693 | |
694 void | |
695 cdef_object_scalar::mark_for_construction (const cdef_class& cls) | |
696 { | |
697 std::string cls_name = cls.get_name (); | |
698 | |
699 Cell supcls = cls.get ("SuperClasses").cell_value (); | |
700 | |
701 std::list<cdef_class> supcls_list = lookup_classes (supcls); | |
702 | |
703 m_ctor_list[cls] = supcls_list; | |
704 } | |
705 | |
706 bool | |
707 cdef_object_scalar::is_constructed_for (const cdef_class& cls) const | |
708 { | |
709 return (is_constructed () | |
710 || m_ctor_list.find (cls) == m_ctor_list.end ()); | |
711 } | |
712 | |
713 bool | |
714 cdef_object_scalar::is_partially_constructed_for (const cdef_class& cls) const | |
715 { | |
716 if (is_constructed ()) | |
717 return true; | |
718 | |
719 std::map<cdef_class, std::list<cdef_class>>::const_iterator it | |
720 = m_ctor_list.find (cls); | 720 = m_ctor_list.find (cls); |
721 | 721 |
722 if (it == m_ctor_list.end () || it->second.empty ()) | 722 if (it == m_ctor_list.end () || it->second.empty ()) |
723 return true; | |
724 | |
725 for (const auto& cdef_cls : it->second) | |
726 if (! is_partially_constructed_for (cdef_cls)) | |
727 return false; | |
728 | |
729 return true; | 723 return true; |
730 } | 724 |
731 | 725 for (const auto& cdef_cls : it->second) |
732 void | 726 if (! is_partially_constructed_for (cdef_cls)) |
733 cdef_object_scalar::mark_as_constructed (const cdef_class& cls) | 727 return false; |
734 { | 728 |
735 m_ctor_list.erase (cls); | 729 return true; |
736 } | 730 } |
737 | 731 |
738 handle_cdef_object::~handle_cdef_object (void) | 732 void |
739 { | 733 cdef_object_scalar::mark_as_constructed (const cdef_class& cls) |
734 { | |
735 m_ctor_list.erase (cls); | |
736 } | |
737 | |
738 handle_cdef_object::~handle_cdef_object (void) | |
739 { | |
740 #if DEBUG_TRACE | 740 #if DEBUG_TRACE |
741 std::cerr << "deleting " << get_class ().get_name () | 741 std::cerr << "deleting " << get_class ().get_name () |
742 << " object (handle)" << std::endl; | 742 << " object (handle)" << std::endl; |
743 #endif | 743 #endif |
744 } | 744 } |
745 | 745 |
746 value_cdef_object::~value_cdef_object (void) | 746 value_cdef_object::~value_cdef_object (void) |
747 { | 747 { |
748 #if DEBUG_TRACE | 748 #if DEBUG_TRACE |
749 std::cerr << "deleting " << get_class ().get_name () | 749 std::cerr << "deleting " << get_class ().get_name () |
750 << " object (value)" << std::endl; | 750 << " object (value)" << std::endl; |
751 #endif | 751 #endif |
752 } | 752 } |
753 | 753 |
754 OCTAVE_END_NAMESPACE(octave) | 754 OCTAVE_END_NAMESPACE(octave) |