comparison src/octave-value/ov-base.cc @ 15057:46b19589b593

maint: Partition src/ directory with more code in subdirs. Create new octave-value dir for ov* code. Create new parse-tre dir for pt* code. Move OPERATORS and TEMPLATE-INST directories to lowercase names * octave-value/module.mk: Hook code in octave-value dir into build system. * octave-value/ov-base-diag.cc, octave-value/ov-base-diag.h, octave-value/ov-base-int.cc, octave-value/ov-base-int.h, octave-value/ov-base-mat.cc, octave-value/ov-base-mat.h, octave-value/ov-base-scalar.cc, octave-value/ov-base-scalar.h, octave-value/ov-base-sparse.cc, octave-value/ov-base-sparse.h, octave-value/ov-base.cc, octave-value/ov-base.h, octave-value/ov-bool-mat.cc, octave-value/ov-bool-mat.h, octave-value/ov-bool-sparse.cc, octave-value/ov-bool-sparse.h, octave-value/ov-bool.cc, octave-value/ov-bool.h, octave-value/ov-builtin.cc, octave-value/ov-builtin.h, octave-value/ov-cell.cc, octave-value/ov-cell.h, octave-value/ov-ch-mat.cc, octave-value/ov-ch-mat.h, octave-value/ov-class.cc, octave-value/ov-class.h, octave-value/ov-colon.cc, octave-value/ov-colon.h, octave-value/ov-complex.cc, octave-value/ov-complex.h, octave-value/ov-cs-list.cc, octave-value/ov-cs-list.h, octave-value/ov-cx-diag.cc, octave-value/ov-cx-diag.h, octave-value/ov-cx-mat.cc, octave-value/ov-cx-mat.h, octave-value/ov-cx-sparse.cc, octave-value/ov-cx-sparse.h, octave-value/ov-dld-fcn.cc, octave-value/ov-dld-fcn.h, octave-value/ov-fcn-handle.cc, octave-value/ov-fcn-handle.h, octave-value/ov-fcn-inline.cc, octave-value/ov-fcn-inline.h, octave-value/ov-fcn.cc, octave-value/ov-fcn.h, octave-value/ov-float.cc, octave-value/ov-float.h, octave-value/ov-flt-complex.cc, octave-value/ov-flt-complex.h, octave-value/ov-flt-cx-diag.cc, octave-value/ov-flt-cx-diag.h, octave-value/ov-flt-cx-mat.cc, octave-value/ov-flt-cx-mat.h, octave-value/ov-flt-re-diag.cc, octave-value/ov-flt-re-diag.h, octave-value/ov-flt-re-mat.cc, octave-value/ov-flt-re-mat.h, octave-value/ov-int-traits.h, octave-value/ov-int16.cc, octave-value/ov-int16.h, octave-value/ov-int32.cc, octave-value/ov-int32.h, octave-value/ov-int64.cc, octave-value/ov-int64.h, octave-value/ov-int8.cc, octave-value/ov-int8.h, octave-value/ov-intx.h, octave-value/ov-lazy-idx.cc, octave-value/ov-lazy-idx.h, octave-value/ov-mex-fcn.cc, octave-value/ov-mex-fcn.h, octave-value/ov-null-mat.cc, octave-value/ov-null-mat.h, octave-value/ov-oncleanup.cc, octave-value/ov-oncleanup.h, octave-value/ov-perm.cc, octave-value/ov-perm.h, octave-value/ov-range.cc, octave-value/ov-range.h, octave-value/ov-re-diag.cc, octave-value/ov-re-diag.h, octave-value/ov-re-mat.cc, octave-value/ov-re-mat.h, octave-value/ov-re-sparse.cc, octave-value/ov-re-sparse.h, octave-value/ov-scalar.cc, octave-value/ov-scalar.h, octave-value/ov-str-mat.cc, octave-value/ov-str-mat.h, octave-value/ov-struct.cc, octave-value/ov-struct.h, octave-value/ov-type-conv.h, octave-value/ov-typeinfo.cc, octave-value/ov-typeinfo.h, octave-value/ov-uint16.cc, octave-value/ov-uint16.h, octave-value/ov-uint32.cc, octave-value/ov-uint32.h, octave-value/ov-uint64.cc, octave-value/ov-uint64.h, octave-value/ov-uint8.cc, octave-value/ov-uint8.h, octave-value/ov-usr-fcn.cc, octave-value/ov-usr-fcn.h, octave-value/ov.cc, octave-value/ov.h: Moved from src/ dir to octave-value dir. * operators/module.mk, operators/op-b-b.cc, operators/op-b-bm.cc, operators/op-b-sbm.cc, operators/op-bm-b.cc, operators/op-bm-bm.cc, operators/op-bm-sbm.cc, operators/op-cdm-cdm.cc, operators/op-cdm-cm.cc, operators/op-cdm-cs.cc, operators/op-cdm-dm.cc, operators/op-cdm-m.cc, operators/op-cdm-s.cc, operators/op-cell.cc, operators/op-chm.cc, operators/op-class.cc, operators/op-cm-cdm.cc, operators/op-cm-cm.cc, operators/op-cm-cs.cc, operators/op-cm-dm.cc, operators/op-cm-m.cc, operators/op-cm-pm.cc, operators/op-cm-s.cc, operators/op-cm-scm.cc, operators/op-cm-sm.cc, operators/op-cs-cm.cc, operators/op-cs-cs.cc, operators/op-cs-m.cc, operators/op-cs-s.cc, operators/op-cs-scm.cc, operators/op-cs-sm.cc, operators/op-dm-cdm.cc, operators/op-dm-cm.cc, operators/op-dm-cs.cc, operators/op-dm-dm.cc, operators/op-dm-m.cc, operators/op-dm-s.cc, operators/op-dm-scm.cc, operators/op-dm-sm.cc, operators/op-dm-template.cc, operators/op-dms-template.cc, operators/op-double-conv.cc, operators/op-fcdm-fcdm.cc, operators/op-fcdm-fcm.cc, operators/op-fcdm-fcs.cc, operators/op-fcdm-fdm.cc, operators/op-fcdm-fm.cc, operators/op-fcdm-fs.cc, operators/op-fcm-fcdm.cc, operators/op-fcm-fcm.cc, operators/op-fcm-fcs.cc, operators/op-fcm-fdm.cc, operators/op-fcm-fm.cc, operators/op-fcm-fs.cc, operators/op-fcm-pm.cc, operators/op-fcn.cc, operators/op-fcs-fcm.cc, operators/op-fcs-fcs.cc, operators/op-fcs-fm.cc, operators/op-fcs-fs.cc, operators/op-fdm-fcdm.cc, operators/op-fdm-fcm.cc, operators/op-fdm-fcs.cc, operators/op-fdm-fdm.cc, operators/op-fdm-fm.cc, operators/op-fdm-fs.cc, operators/op-float-conv.cc, operators/op-fm-fcdm.cc, operators/op-fm-fcm.cc, operators/op-fm-fcs.cc, operators/op-fm-fdm.cc, operators/op-fm-fm.cc, operators/op-fm-fs.cc, operators/op-fm-pm.cc, operators/op-fs-fcm.cc, operators/op-fs-fcs.cc, operators/op-fs-fm.cc, operators/op-fs-fs.cc, operators/op-i16-i16.cc, operators/op-i32-i32.cc, operators/op-i64-i64.cc, operators/op-i8-i8.cc, operators/op-int-concat.cc, operators/op-int-conv.cc, operators/op-int.h, operators/op-m-cdm.cc, operators/op-m-cm.cc, operators/op-m-cs.cc, operators/op-m-dm.cc, operators/op-m-m.cc, operators/op-m-pm.cc, operators/op-m-s.cc, operators/op-m-scm.cc, operators/op-m-sm.cc, operators/op-pm-cm.cc, operators/op-pm-fcm.cc, operators/op-pm-fm.cc, operators/op-pm-m.cc, operators/op-pm-pm.cc, operators/op-pm-scm.cc, operators/op-pm-sm.cc, operators/op-pm-template.cc, operators/op-range.cc, operators/op-s-cm.cc, operators/op-s-cs.cc, operators/op-s-m.cc, operators/op-s-s.cc, operators/op-s-scm.cc, operators/op-s-sm.cc, operators/op-sbm-b.cc, operators/op-sbm-bm.cc, operators/op-sbm-sbm.cc, operators/op-scm-cm.cc, operators/op-scm-cs.cc, operators/op-scm-m.cc, operators/op-scm-s.cc, operators/op-scm-scm.cc, operators/op-scm-sm.cc, operators/op-sm-cm.cc, operators/op-sm-cs.cc, operators/op-sm-m.cc, operators/op-sm-s.cc, operators/op-sm-scm.cc, operators/op-sm-sm.cc, operators/op-str-m.cc, operators/op-str-s.cc, operators/op-str-str.cc, operators/op-struct.cc, operators/op-ui16-ui16.cc, operators/op-ui32-ui32.cc, operators/op-ui64-ui64.cc, operators/op-ui8-ui8.cc: Moved from OPERATORS/ dir to operators/ directory. * mkops: Correctly print comment in generated file ops.cc that it is made by mkops. Change sed expression for OPERATORS/ to operators/. * parse-tree/module.mk: Hook code in parse-tree dir into build system. * parse-tree/pt-all.h, parse-tree/pt-arg-list.cc, parse-tree/pt-arg-list.h, parse-tree/pt-assign.cc, parse-tree/pt-assign.h, parse-tree/pt-binop.cc, parse-tree/pt-binop.h, parse-tree/pt-bp.cc, parse-tree/pt-bp.h, parse-tree/pt-cbinop.cc, parse-tree/pt-cbinop.h, parse-tree/pt-cell.cc, parse-tree/pt-cell.h, parse-tree/pt-check.cc, parse-tree/pt-check.h, parse-tree/pt-cmd.cc, parse-tree/pt-cmd.h, parse-tree/pt-colon.cc, parse-tree/pt-colon.h, parse-tree/pt-const.cc, parse-tree/pt-const.h, parse-tree/pt-decl.cc, parse-tree/pt-decl.h, parse-tree/pt-eval.cc, parse-tree/pt-eval.h, parse-tree/pt-except.cc, parse-tree/pt-except.h, parse-tree/pt-exp.cc, parse-tree/pt-exp.h, parse-tree/pt-fcn-handle.cc, parse-tree/pt-fcn-handle.h, parse-tree/pt-id.cc, parse-tree/pt-id.h, parse-tree/pt-idx.cc, parse-tree/pt-idx.h, parse-tree/pt-jump.cc, parse-tree/pt-jump.h, parse-tree/pt-loop.cc, parse-tree/pt-loop.h, parse-tree/pt-mat.cc, parse-tree/pt-mat.h, parse-tree/pt-misc.cc, parse-tree/pt-misc.h, parse-tree/pt-pr-code.cc, parse-tree/pt-pr-code.h, parse-tree/pt-select.cc, parse-tree/pt-select.h, parse-tree/pt-stmt.cc, parse-tree/pt-stmt.h, parse-tree/pt-unop.cc, parse-tree/pt-unop.h, parse-tree/pt-walk.h, parse-tree/pt.cc, parse-tree/pt.h: Moved from src/ dir to parse-tree dir. * template-inst/Array-jit.cc, template-inst/Array-os.cc, template-inst/Array-sym.cc, template-inst/Array-tc.cc, template-inst/module.mk: Moved from TEMPLATE-INST dir to template-inst/ directory. * src/Makefile.am: Add new directories to build system. * corefcn/module.mk: Use COREFCN_SRC with all capitals to indicate it is not an Automake special target.
author Rik <rik@octave.org>
date Mon, 30 Jul 2012 15:29:19 -0700
parents src/ov-base.cc@460a3c6d8bf1
children 62a35ae7d6a2
comparison
equal deleted inserted replaced
15056:bc32288f4a42 15057:46b19589b593
1 /*
2
3 Copyright (C) 1996-2012 John W. Eaton
4 Copyright (C) 2009-2010 VZLU Prague
5
6 This file is part of Octave.
7
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <climits>
29
30 #include <iostream>
31
32 #include "lo-ieee.h"
33 #include "lo-mappers.h"
34
35 #include "defun.h"
36 #include "gripes.h"
37 #include "oct-map.h"
38 #include "oct-obj.h"
39 #include "oct-lvalue.h"
40 #include "oct-stream.h"
41 #include "ops.h"
42 #include "ov-base.h"
43 #include "ov-cell.h"
44 #include "ov-ch-mat.h"
45 #include "ov-complex.h"
46 #include "ov-cx-mat.h"
47 #include "ov-range.h"
48 #include "ov-re-mat.h"
49 #include "ov-scalar.h"
50 #include "ov-str-mat.h"
51 #include "ov-fcn-handle.h"
52 #include "parse.h"
53 #include "pr-output.h"
54 #include "utils.h"
55 #include "variables.h"
56
57 builtin_type_t btyp_mixed_numeric (builtin_type_t x, builtin_type_t y)
58 {
59 builtin_type_t retval = btyp_unknown;
60
61 if (x == btyp_bool)
62 x = btyp_double;
63 if (y == btyp_bool)
64 y = btyp_double;
65
66 if (x <= btyp_float_complex && y <= btyp_float_complex)
67 retval = static_cast<builtin_type_t> (x | y);
68 else if (x <= btyp_uint64 && y <= btyp_float)
69 retval = x;
70 else if (x <= btyp_float && y <= btyp_uint64)
71 retval = y;
72 else if ((x >= btyp_int8 && x <= btyp_int64
73 && y >= btyp_int8 && y <= btyp_int64)
74 || (x >= btyp_uint8 && x <= btyp_uint64
75 && y >= btyp_uint8 && y <= btyp_uint64))
76 retval = (x > y) ? x : y;
77
78 return retval;
79 }
80
81 std::string btyp_class_name[btyp_num_types] =
82 {
83 "double", "single", "double", "single",
84 "int8", "int16", "int32", "int64",
85 "uint8", "uint16", "uint32", "uint64",
86 "logical", "char",
87 "struct", "cell", "function_handle"
88 };
89
90 string_vector
91 get_builtin_classes (void)
92 {
93 static string_vector retval;
94
95 if (retval.is_empty ())
96 {
97 int n = btyp_num_types - 2;
98 retval = string_vector (n);
99 int j = 0;
100 for (int i = 0; i < btyp_num_types; i++)
101 {
102 builtin_type_t ityp = static_cast<builtin_type_t> (i);
103 if (ityp != btyp_complex && ityp != btyp_float_complex)
104 retval(j++) = btyp_class_name[i];
105 }
106 }
107
108 return retval;
109 }
110
111 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_base_value,
112 "<unknown type>", "unknown");
113
114 // TRUE means to perform automatic sparse to real mutation if there
115 // is memory to be saved
116 bool Vsparse_auto_mutate = false;
117
118 octave_base_value *
119 octave_base_value::empty_clone (void) const
120 {
121 return resize (dim_vector ()).clone ();
122 }
123
124 octave_value
125 octave_base_value::squeeze (void) const
126 {
127 std::string nm = type_name ();
128 error ("squeeze: invalid operation for %s type", nm.c_str ());
129 return octave_value ();
130 }
131
132 octave_value
133 octave_base_value::full_value (void) const
134 {
135 gripe_wrong_type_arg ("full: invalid operation for %s type", type_name ());
136 return octave_value ();
137 }
138
139 Matrix
140 octave_base_value::size (void)
141 {
142 const dim_vector dv = dims ();
143 Matrix mdv (1, dv.length ());
144 for (octave_idx_type i = 0; i < dv.length (); i++)
145 mdv(i) = dv(i);
146 return mdv;
147 }
148
149 octave_idx_type
150 octave_base_value::numel (const octave_value_list& idx)
151 {
152 return dims_to_numel (dims (), idx);
153 }
154
155 octave_value
156 octave_base_value::subsref (const std::string&,
157 const std::list<octave_value_list>&)
158 {
159 std::string nm = type_name ();
160 error ("can't perform indexing operations for %s type", nm.c_str ());
161 return octave_value ();
162 }
163
164 octave_value_list
165 octave_base_value::subsref (const std::string&,
166 const std::list<octave_value_list>&, int)
167 {
168 std::string nm = type_name ();
169 error ("can't perform indexing operations for %s type", nm.c_str ());
170 return octave_value ();
171 }
172
173 octave_value
174 octave_base_value::subsref (const std::string& type,
175 const std::list<octave_value_list>& idx,
176 bool /* auto_add */)
177 {
178 // This way we may get a more meaningful error message.
179 return subsref (type, idx);
180 }
181
182 octave_value_list
183 octave_base_value::subsref (const std::string& type,
184 const std::list<octave_value_list>& idx,
185 int nargout,
186 const std::list<octave_lvalue> *)
187 {
188 // Fall back to call without passing lvalue list.
189 return subsref (type, idx, nargout);
190 }
191
192 octave_value
193 octave_base_value::do_index_op (const octave_value_list&, bool)
194 {
195 std::string nm = type_name ();
196 error ("can't perform indexing operations for %s type", nm.c_str ());
197 return octave_value ();
198 }
199
200 octave_value_list
201 octave_base_value::do_multi_index_op (int, const octave_value_list&)
202 {
203 std::string nm = type_name ();
204 error ("can't perform indexing operations for %s type", nm.c_str ());
205 return octave_value ();
206 }
207
208 octave_value_list
209 octave_base_value::do_multi_index_op (int nargout, const octave_value_list& idx,
210 const std::list<octave_lvalue> *)
211 {
212 // Fall back.
213 return do_multi_index_op (nargout, idx);
214 }
215
216 idx_vector
217 octave_base_value::index_vector (void) const
218 {
219 std::string nm = type_name ();
220 error ("%s type invalid as index value", nm.c_str ());
221 return idx_vector ();
222 }
223
224 octave_value
225 octave_base_value::subsasgn (const std::string& type,
226 const std::list<octave_value_list>& idx,
227 const octave_value& rhs)
228 {
229 octave_value retval;
230
231 if (is_defined ())
232 {
233 if (is_numeric_type ())
234 {
235 switch (type[0])
236 {
237 case '(':
238 {
239 if (type.length () == 1)
240 retval = numeric_assign (type, idx, rhs);
241 else if (is_empty ())
242 {
243 // Allow conversion of empty matrix to some other
244 // type in cases like
245 //
246 // x = []; x(i).f = rhs
247
248 octave_value tmp = octave_value::empty_conv (type, rhs);
249
250 retval = tmp.subsasgn (type, idx, rhs);
251 }
252 else
253 {
254 std::string nm = type_name ();
255 error ("in indexed assignment of %s, last rhs index must be ()",
256 nm.c_str ());
257 }
258 }
259 break;
260
261 case '{':
262 case '.':
263 {
264 std::string nm = type_name ();
265 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
266 }
267 break;
268
269 default:
270 panic_impossible ();
271 }
272 }
273 else
274 {
275 std::string nm = type_name ();
276 error ("can't perform indexed assignment for %s type", nm.c_str ());
277 }
278 }
279 else
280 {
281 // Create new object of appropriate type for given index and rhs
282 // types and then call undef_subsasgn for that object.
283
284 octave_value tmp = octave_value::empty_conv (type, rhs);
285
286 retval = tmp.undef_subsasgn (type, idx, rhs);
287 }
288
289 return retval;
290 }
291
292 octave_value
293 octave_base_value::undef_subsasgn (const std::string& type,
294 const std::list<octave_value_list>& idx,
295 const octave_value& rhs)
296 {
297 // In most cases, undef_subsasgn is handled the sams as subsasgn. One
298 // exception is octave_class objects.
299
300 return subsasgn (type, idx, rhs);
301 }
302
303 octave_idx_type
304 octave_base_value::nnz (void) const
305 {
306 gripe_wrong_type_arg ("octave_base_value::nnz ()", type_name ());
307 return -1;
308 }
309
310 octave_idx_type
311 octave_base_value::nzmax (void) const
312 {
313 return numel ();
314 }
315
316 octave_idx_type
317 octave_base_value::nfields (void) const
318 {
319 gripe_wrong_type_arg ("octave_base_value::nfields ()", type_name ());
320 return -1;
321 }
322
323 octave_value
324 octave_base_value::reshape (const dim_vector&) const
325 {
326 gripe_wrong_type_arg ("octave_base_value::reshape ()", type_name ());
327 return octave_value ();
328 }
329
330 octave_value
331 octave_base_value::permute (const Array<int>&, bool) const
332 {
333 gripe_wrong_type_arg ("octave_base_value::permute ()", type_name ());
334 return octave_value ();
335 }
336
337 octave_value
338 octave_base_value::resize (const dim_vector&, bool) const
339 {
340 gripe_wrong_type_arg ("octave_base_value::resize ()", type_name ());
341 return octave_value ();
342 }
343
344 MatrixType
345 octave_base_value::matrix_type (void) const
346 {
347 gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
348 return MatrixType ();
349 }
350
351 MatrixType
352 octave_base_value::matrix_type (const MatrixType&) const
353 {
354 gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
355 return MatrixType ();
356 }
357
358 octave_value
359 octave_base_value::all (int) const
360 {
361 return 0.0;
362 }
363
364 octave_value
365 octave_base_value::any (int) const
366 {
367 return 0.0;
368 }
369
370 octave_value
371 octave_base_value::convert_to_str (bool pad, bool force, char type) const
372 {
373 octave_value retval = convert_to_str_internal (pad, force, type);
374
375 if (! force && is_numeric_type ())
376 gripe_implicit_conversion ("Octave:num-to-str",
377 type_name (), retval.type_name ());
378
379 return retval;
380 }
381
382 octave_value
383 octave_base_value::convert_to_str_internal (bool, bool, char) const
384 {
385 gripe_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
386 type_name ());
387 return octave_value ();
388 }
389
390 void
391 octave_base_value::convert_to_row_or_column_vector (void)
392 {
393 gripe_wrong_type_arg
394 ("octave_base_value::convert_to_row_or_column_vector ()",
395 type_name ());
396 }
397
398 void
399 octave_base_value::print (std::ostream&, bool) const
400 {
401 gripe_wrong_type_arg ("octave_base_value::print ()", type_name ());
402 }
403
404 void
405 octave_base_value::print_raw (std::ostream&, bool) const
406 {
407 gripe_wrong_type_arg ("octave_base_value::print_raw ()", type_name ());
408 }
409
410 bool
411 octave_base_value::print_name_tag (std::ostream& os, const std::string& name) const
412 {
413 bool retval = false;
414
415 indent (os);
416
417 if (print_as_scalar ())
418 os << name << " = ";
419 else
420 {
421 os << name << " =";
422 newline (os);
423 if (! Vcompact_format)
424 newline (os);
425
426 retval = true;
427 }
428
429 return retval;
430 }
431
432 void
433 octave_base_value::print_with_name (std::ostream& output_buf,
434 const std::string& name,
435 bool print_padding)
436 {
437 bool pad_after = print_name_tag (output_buf, name);
438
439 print (output_buf);
440
441 if (print_padding && pad_after && ! Vcompact_format)
442 newline (output_buf);
443 }
444
445 void
446 octave_base_value::print_info (std::ostream& os,
447 const std::string& /* prefix */) const
448 {
449 os << "no info for type: " << type_name () << "\n";
450 }
451
452 #define INT_CONV_METHOD(T, F, MIN_LIMIT, MAX_LIMIT) \
453 T \
454 octave_base_value::F ## _value (bool require_int, bool frc_str_conv) const \
455 { \
456 T retval = 0; \
457 \
458 double d = double_value (frc_str_conv); \
459 \
460 if (! error_state) \
461 { \
462 if (require_int && D_NINT (d) != d) \
463 error_with_cfn ("conversion of %g to " #T " value failed", d); \
464 else if (d < MIN_LIMIT) \
465 retval = MIN_LIMIT; \
466 else if (d > MAX_LIMIT) \
467 retval = MAX_LIMIT; \
468 else \
469 retval = static_cast<T> (::fix (d)); \
470 } \
471 else \
472 gripe_wrong_type_arg ("octave_base_value::" #F "_value ()", \
473 type_name ()); \
474 \
475 return retval; \
476 }
477
478 INT_CONV_METHOD (short int, short, SHRT_MIN, SHRT_MAX)
479 INT_CONV_METHOD (unsigned short int, ushort, 0, USHRT_MAX)
480
481 INT_CONV_METHOD (int, int, INT_MIN, INT_MAX)
482 INT_CONV_METHOD (unsigned int, uint, 0, UINT_MAX)
483
484 INT_CONV_METHOD (long int, long, LONG_MIN, LONG_MAX)
485 INT_CONV_METHOD (unsigned long int, ulong, 0, ULONG_MAX)
486
487 int
488 octave_base_value::nint_value (bool frc_str_conv) const
489 {
490 int retval = 0;
491
492 double d = double_value (frc_str_conv);
493
494 if (! error_state)
495 {
496 if (xisnan (d))
497 {
498 error ("conversion of NaN to integer value failed");
499 return retval;
500 }
501
502 retval = static_cast<int> (::fix (d));
503 }
504 else
505 gripe_wrong_type_arg ("octave_base_value::nint_value ()", type_name ());
506
507 return retval;
508 }
509
510 double
511 octave_base_value::double_value (bool) const
512 {
513 double retval = lo_ieee_nan_value ();
514 gripe_wrong_type_arg ("octave_base_value::double_value ()", type_name ());
515 return retval;
516 }
517
518 float
519 octave_base_value::float_value (bool) const
520 {
521 float retval = lo_ieee_float_nan_value ();
522 gripe_wrong_type_arg ("octave_base_value::float_value ()", type_name ());
523 return retval;
524 }
525
526 Cell
527 octave_base_value::cell_value () const
528 {
529 Cell retval;
530 gripe_wrong_type_arg ("octave_base_value::cell_value()", type_name ());
531 return retval;
532 }
533
534 Matrix
535 octave_base_value::matrix_value (bool) const
536 {
537 Matrix retval;
538 gripe_wrong_type_arg ("octave_base_value::matrix_value()", type_name ());
539 return retval;
540 }
541
542 FloatMatrix
543 octave_base_value::float_matrix_value (bool) const
544 {
545 FloatMatrix retval;
546 gripe_wrong_type_arg ("octave_base_value::float_matrix_value()", type_name ());
547 return retval;
548 }
549
550 NDArray
551 octave_base_value::array_value (bool) const
552 {
553 FloatNDArray retval;
554 gripe_wrong_type_arg ("octave_base_value::array_value()", type_name ());
555 return retval;
556 }
557
558 FloatNDArray
559 octave_base_value::float_array_value (bool) const
560 {
561 FloatNDArray retval;
562 gripe_wrong_type_arg ("octave_base_value::float_array_value()", type_name ());
563 return retval;
564 }
565
566 Complex
567 octave_base_value::complex_value (bool) const
568 {
569 double tmp = lo_ieee_nan_value ();
570 Complex retval (tmp, tmp);
571 gripe_wrong_type_arg ("octave_base_value::complex_value()", type_name ());
572 return retval;
573 }
574
575 FloatComplex
576 octave_base_value::float_complex_value (bool) const
577 {
578 float tmp = lo_ieee_float_nan_value ();
579 FloatComplex retval (tmp, tmp);
580 gripe_wrong_type_arg ("octave_base_value::float_complex_value()", type_name ());
581 return retval;
582 }
583
584 ComplexMatrix
585 octave_base_value::complex_matrix_value (bool) const
586 {
587 ComplexMatrix retval;
588 gripe_wrong_type_arg ("octave_base_value::complex_matrix_value()",
589 type_name ());
590 return retval;
591 }
592
593 FloatComplexMatrix
594 octave_base_value::float_complex_matrix_value (bool) const
595 {
596 FloatComplexMatrix retval;
597 gripe_wrong_type_arg ("octave_base_value::float_complex_matrix_value()",
598 type_name ());
599 return retval;
600 }
601
602 ComplexNDArray
603 octave_base_value::complex_array_value (bool) const
604 {
605 ComplexNDArray retval;
606 gripe_wrong_type_arg ("octave_base_value::complex_array_value()",
607 type_name ());
608 return retval;
609 }
610
611 FloatComplexNDArray
612 octave_base_value::float_complex_array_value (bool) const
613 {
614 FloatComplexNDArray retval;
615 gripe_wrong_type_arg ("octave_base_value::float_complex_array_value()",
616 type_name ());
617 return retval;
618 }
619
620 bool
621 octave_base_value::bool_value (bool) const
622 {
623 bool retval = false;
624 gripe_wrong_type_arg ("octave_base_value::bool_value()", type_name ());
625 return retval;
626 }
627
628 boolMatrix
629 octave_base_value::bool_matrix_value (bool) const
630 {
631 boolMatrix retval;
632 gripe_wrong_type_arg ("octave_base_value::bool_matrix_value()",
633 type_name ());
634 return retval;
635 }
636
637 boolNDArray
638 octave_base_value::bool_array_value (bool) const
639 {
640 boolNDArray retval;
641 gripe_wrong_type_arg ("octave_base_value::bool_array_value()",
642 type_name ());
643 return retval;
644 }
645
646 charMatrix
647 octave_base_value::char_matrix_value (bool force) const
648 {
649 charMatrix retval;
650
651 octave_value tmp = convert_to_str (false, force);
652
653 if (! error_state)
654 retval = tmp.char_matrix_value ();
655
656 return retval;
657 }
658
659 charNDArray
660 octave_base_value::char_array_value (bool) const
661 {
662 charNDArray retval;
663 gripe_wrong_type_arg ("octave_base_value::char_array_value()",
664 type_name ());
665 return retval;
666 }
667
668 SparseMatrix
669 octave_base_value::sparse_matrix_value (bool) const
670 {
671 SparseMatrix retval;
672 gripe_wrong_type_arg ("octave_base_value::sparse_matrix_value()", type_name ());
673 return retval;
674 }
675
676 SparseComplexMatrix
677 octave_base_value::sparse_complex_matrix_value (bool) const
678 {
679 SparseComplexMatrix retval;
680 gripe_wrong_type_arg ("octave_base_value::sparse_complex_matrix_value()", type_name ());
681 return retval;
682 }
683
684 SparseBoolMatrix
685 octave_base_value::sparse_bool_matrix_value (bool) const
686 {
687 SparseBoolMatrix retval;
688 gripe_wrong_type_arg ("octave_base_value::sparse_bool_matrix_value()", type_name ());
689 return retval;
690 }
691
692 DiagMatrix
693 octave_base_value::diag_matrix_value (bool) const
694 {
695 DiagMatrix retval;
696 gripe_wrong_type_arg ("octave_base_value::diag_matrix_value()", type_name ());
697 return retval;
698 }
699
700 FloatDiagMatrix
701 octave_base_value::float_diag_matrix_value (bool) const
702 {
703 FloatDiagMatrix retval;
704 gripe_wrong_type_arg ("octave_base_value::float_diag_matrix_value()", type_name ());
705 return retval;
706 }
707
708 ComplexDiagMatrix
709 octave_base_value::complex_diag_matrix_value (bool) const
710 {
711 ComplexDiagMatrix retval;
712 gripe_wrong_type_arg ("octave_base_value::complex_diag_matrix_value()", type_name ());
713 return retval;
714 }
715
716 FloatComplexDiagMatrix
717 octave_base_value::float_complex_diag_matrix_value (bool) const
718 {
719 FloatComplexDiagMatrix retval;
720 gripe_wrong_type_arg ("octave_base_value::float_complex_diag_matrix_value()", type_name ());
721 return retval;
722 }
723
724 PermMatrix
725 octave_base_value::perm_matrix_value (void) const
726 {
727 PermMatrix retval;
728 gripe_wrong_type_arg ("octave_base_value::perm_matrix_value()", type_name ());
729 return retval;
730 }
731
732 octave_int8
733 octave_base_value::int8_scalar_value (void) const
734 {
735 octave_int8 retval;
736 gripe_wrong_type_arg ("octave_base_value::int8_scalar_value()",
737 type_name ());
738 return retval;
739 }
740
741 octave_int16
742 octave_base_value::int16_scalar_value (void) const
743 {
744 octave_int16 retval;
745 gripe_wrong_type_arg ("octave_base_value::int16_scalar_value()",
746 type_name ());
747 return retval;
748 }
749
750 octave_int32
751 octave_base_value::int32_scalar_value (void) const
752 {
753 octave_int32 retval;
754 gripe_wrong_type_arg ("octave_base_value::int32_scalar_value()",
755 type_name ());
756 return retval;
757 }
758
759 octave_int64
760 octave_base_value::int64_scalar_value (void) const
761 {
762 octave_int64 retval;
763 gripe_wrong_type_arg ("octave_base_value::int64_scalar_value()",
764 type_name ());
765 return retval;
766 }
767
768 octave_uint8
769 octave_base_value::uint8_scalar_value (void) const
770 {
771 octave_uint8 retval;
772 gripe_wrong_type_arg ("octave_base_value::uint8_scalar_value()",
773 type_name ());
774 return retval;
775 }
776
777 octave_uint16
778 octave_base_value::uint16_scalar_value (void) const
779 {
780 octave_uint16 retval;
781 gripe_wrong_type_arg ("octave_base_value::uint16_scalar_value()",
782 type_name ());
783 return retval;
784 }
785
786 octave_uint32
787 octave_base_value::uint32_scalar_value (void) const
788 {
789 octave_uint32 retval;
790 gripe_wrong_type_arg ("octave_base_value::uint32_scalar_value()",
791 type_name ());
792 return retval;
793 }
794
795 octave_uint64
796 octave_base_value::uint64_scalar_value (void) const
797 {
798 octave_uint64 retval;
799 gripe_wrong_type_arg ("octave_base_value::uint64_scalar_value()",
800 type_name ());
801 return retval;
802 }
803
804 int8NDArray
805 octave_base_value::int8_array_value (void) const
806 {
807 int8NDArray retval;
808 gripe_wrong_type_arg ("octave_base_value::int8_array_value()",
809 type_name ());
810 return retval;
811 }
812
813 int16NDArray
814 octave_base_value::int16_array_value (void) const
815 {
816 int16NDArray retval;
817 gripe_wrong_type_arg ("octave_base_value::int16_array_value()",
818 type_name ());
819 return retval;
820 }
821
822 int32NDArray
823 octave_base_value::int32_array_value (void) const
824 {
825 int32NDArray retval;
826 gripe_wrong_type_arg ("octave_base_value::int32_array_value()",
827 type_name ());
828 return retval;
829 }
830
831 int64NDArray
832 octave_base_value::int64_array_value (void) const
833 {
834 int64NDArray retval;
835 gripe_wrong_type_arg ("octave_base_value::int64_array_value()",
836 type_name ());
837 return retval;
838 }
839
840 uint8NDArray
841 octave_base_value::uint8_array_value (void) const
842 {
843 uint8NDArray retval;
844 gripe_wrong_type_arg ("octave_base_value::uint8_array_value()",
845 type_name ());
846 return retval;
847 }
848
849 uint16NDArray
850 octave_base_value::uint16_array_value (void) const
851 {
852 uint16NDArray retval;
853 gripe_wrong_type_arg ("octave_base_value::uint16_array_value()",
854 type_name ());
855 return retval;
856 }
857
858 uint32NDArray
859 octave_base_value::uint32_array_value (void) const
860 {
861 uint32NDArray retval;
862 gripe_wrong_type_arg ("octave_base_value::uint32_array_value()",
863 type_name ());
864 return retval;
865 }
866
867 uint64NDArray
868 octave_base_value::uint64_array_value (void) const
869 {
870 uint64NDArray retval;
871 gripe_wrong_type_arg ("octave_base_value::uint64_array_value()",
872 type_name ());
873 return retval;
874 }
875
876 string_vector
877 octave_base_value::all_strings (bool pad) const
878 {
879 string_vector retval;
880
881 octave_value tmp = convert_to_str (pad, true);
882
883 if (! error_state)
884 retval = tmp.all_strings ();
885
886 return retval;
887 }
888
889 std::string
890 octave_base_value::string_value (bool force) const
891 {
892 std::string retval;
893
894 octave_value tmp = convert_to_str (force);
895
896 if (! error_state)
897 retval = tmp.string_value ();
898
899 return retval;
900 }
901
902 Array<std::string>
903 octave_base_value::cellstr_value (void) const
904 {
905 Array<std::string> retval;
906 gripe_wrong_type_arg ("octave_base_value::cellstry_value()",
907 type_name ());
908 return retval;
909 }
910
911 Range
912 octave_base_value::range_value (void) const
913 {
914 Range retval;
915 gripe_wrong_type_arg ("octave_base_value::range_value()", type_name ());
916 return retval;
917 }
918
919 octave_map
920 octave_base_value::map_value (void) const
921 {
922 octave_map retval;
923 gripe_wrong_type_arg ("octave_base_value::map_value()", type_name ());
924 return retval;
925 }
926
927 octave_scalar_map
928 octave_base_value::scalar_map_value (void) const
929 {
930 octave_map tmp = map_value ();
931
932 if (tmp.numel () == 1)
933 return tmp.checkelem (0);
934 else
935 {
936 if (! error_state)
937 error ("invalid conversion of multi-dimensional struct to scalar struct");
938
939 return octave_scalar_map ();
940 }
941 }
942
943 string_vector
944 octave_base_value::map_keys (void) const
945 {
946 string_vector retval;
947 gripe_wrong_type_arg ("octave_base_value::map_keys()", type_name ());
948 return retval;
949 }
950
951 size_t
952 octave_base_value::nparents (void) const
953 {
954 size_t retval = 0;
955 gripe_wrong_type_arg ("octave_base_value::nparents()", type_name ());
956 return retval;
957 }
958
959 std::list<std::string>
960 octave_base_value::parent_class_name_list (void) const
961 {
962 std::list<std::string> retval;
963 gripe_wrong_type_arg ("octave_base_value::parent_class_name_list()",
964 type_name ());
965 return retval;
966 }
967
968 string_vector
969 octave_base_value::parent_class_names (void) const
970 {
971 string_vector retval;
972 gripe_wrong_type_arg ("octave_base_value::parent_class_names()",
973 type_name ());
974 return retval;
975 }
976
977 octave_function *
978 octave_base_value::function_value (bool silent)
979 {
980 octave_function *retval = 0;
981
982 if (! silent)
983 gripe_wrong_type_arg ("octave_base_value::function_value()",
984 type_name ());
985 return retval;
986 }
987
988 octave_user_function *
989 octave_base_value::user_function_value (bool silent)
990 {
991 octave_user_function *retval = 0;
992
993 if (! silent)
994 gripe_wrong_type_arg ("octave_base_value::user_function_value()",
995 type_name ());
996 return retval;
997 }
998
999 octave_user_script *
1000 octave_base_value::user_script_value (bool silent)
1001 {
1002 octave_user_script *retval = 0;
1003
1004 if (! silent)
1005 gripe_wrong_type_arg ("octave_base_value::user_script_value()",
1006 type_name ());
1007 return retval;
1008 }
1009
1010 octave_user_code *
1011 octave_base_value::user_code_value (bool silent)
1012 {
1013 octave_user_code *retval = 0;
1014
1015 if (! silent)
1016 gripe_wrong_type_arg ("octave_base_value::user_code_value()",
1017 type_name ());
1018 return retval;
1019 }
1020
1021 octave_fcn_handle *
1022 octave_base_value::fcn_handle_value (bool silent)
1023 {
1024 octave_fcn_handle *retval = 0;
1025
1026 if (! silent)
1027 gripe_wrong_type_arg ("octave_base_value::fcn_handle_value()",
1028 type_name ());
1029 return retval;
1030 }
1031
1032 octave_fcn_inline *
1033 octave_base_value::fcn_inline_value (bool silent)
1034 {
1035 octave_fcn_inline *retval = 0;
1036
1037 if (! silent)
1038 gripe_wrong_type_arg ("octave_base_value::fcn_inline_value()",
1039 type_name ());
1040 return retval;
1041 }
1042
1043 octave_value_list
1044 octave_base_value::list_value (void) const
1045 {
1046 octave_value_list retval;
1047 gripe_wrong_type_arg ("octave_base_value::list_value()", type_name ());
1048 return retval;
1049 }
1050
1051 bool
1052 octave_base_value::save_ascii (std::ostream&)
1053 {
1054 gripe_wrong_type_arg ("octave_base_value::save_ascii()", type_name ());
1055 return false;
1056 }
1057
1058 bool
1059 octave_base_value::load_ascii (std::istream&)
1060 {
1061 gripe_wrong_type_arg ("octave_base_value::load_ascii()", type_name ());
1062 return false;
1063 }
1064
1065 bool
1066 octave_base_value::save_binary (std::ostream&, bool&)
1067 {
1068 gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
1069 return false;
1070 }
1071
1072 bool
1073 octave_base_value::load_binary (std::istream&, bool,
1074 oct_mach_info::float_format)
1075 {
1076 gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
1077 return false;
1078 }
1079
1080 #if defined (HAVE_HDF5)
1081
1082 bool
1083 octave_base_value::save_hdf5 (hid_t, const char *, bool)
1084 {
1085 gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
1086
1087 return false;
1088 }
1089
1090 bool
1091 octave_base_value::load_hdf5 (hid_t, const char *)
1092 {
1093 gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
1094
1095 return false;
1096 }
1097
1098 #endif
1099
1100 int
1101 octave_base_value::write (octave_stream&, int, oct_data_conv::data_type,
1102 int, oct_mach_info::float_format) const
1103 {
1104 gripe_wrong_type_arg ("octave_base_value::write()", type_name ());
1105
1106 return false;
1107 }
1108
1109 mxArray *
1110 octave_base_value::as_mxArray (void) const
1111 {
1112 return 0;
1113 }
1114
1115 octave_value
1116 octave_base_value::diag (octave_idx_type) const
1117 {
1118 gripe_wrong_type_arg ("octave_base_value::diag ()", type_name ());
1119
1120 return octave_value ();
1121 }
1122
1123 octave_value
1124 octave_base_value::diag (octave_idx_type, octave_idx_type) const
1125 {
1126 gripe_wrong_type_arg ("octave_base_value::diag ()", type_name ());
1127
1128 return octave_value ();
1129 }
1130
1131 octave_value
1132 octave_base_value::sort (octave_idx_type, sortmode) const
1133 {
1134 gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ());
1135
1136 return octave_value ();
1137 }
1138
1139 octave_value
1140 octave_base_value::sort (Array<octave_idx_type> &,
1141 octave_idx_type, sortmode) const
1142 {
1143 gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ());
1144
1145 return octave_value ();
1146 }
1147
1148 sortmode
1149 octave_base_value::is_sorted (sortmode) const
1150 {
1151 gripe_wrong_type_arg ("octave_base_value::is_sorted ()", type_name ());
1152
1153 return UNSORTED;
1154 }
1155
1156 Array<octave_idx_type>
1157 octave_base_value::sort_rows_idx (sortmode) const
1158 {
1159 gripe_wrong_type_arg ("octave_base_value::sort_rows_idx ()", type_name ());
1160
1161 return Array<octave_idx_type> ();
1162 }
1163
1164 sortmode
1165 octave_base_value::is_sorted_rows (sortmode) const
1166 {
1167 gripe_wrong_type_arg ("octave_base_value::is_sorted_rows ()", type_name ());
1168
1169 return UNSORTED;
1170 }
1171
1172
1173 const char *
1174 octave_base_value::get_umap_name (unary_mapper_t umap)
1175 {
1176 static const char *names[num_unary_mappers] =
1177 {
1178 "abs",
1179 "acos",
1180 "acosh",
1181 "angle",
1182 "arg",
1183 "asin",
1184 "asinh",
1185 "atan",
1186 "atanh",
1187 "cbrt",
1188 "ceil",
1189 "conj",
1190 "cos",
1191 "cosh",
1192 "erf",
1193 "erfinv",
1194 "erfcinv",
1195 "erfc",
1196 "exp",
1197 "expm1",
1198 "finite",
1199 "fix",
1200 "floor",
1201 "gamma",
1202 "imag",
1203 "isinf",
1204 "isna",
1205 "isnan",
1206 "lgamma",
1207 "log",
1208 "log2",
1209 "log10",
1210 "log1p",
1211 "real",
1212 "round",
1213 "roundb",
1214 "signum",
1215 "sin",
1216 "sinh",
1217 "sqrt",
1218 "tan",
1219 "tanh",
1220 "isalnum",
1221 "isalpha",
1222 "isascii",
1223 "iscntrl",
1224 "isdigit",
1225 "isgraph",
1226 "islower",
1227 "isprint",
1228 "ispunct",
1229 "isspace",
1230 "isupper",
1231 "isxdigit",
1232 "toascii",
1233 "tolower",
1234 "toupper"
1235 };
1236
1237 if (umap < 0 || umap >= num_unary_mappers)
1238 return "unknown";
1239 else
1240 return names[umap];
1241 }
1242
1243 octave_value
1244 octave_base_value::map (unary_mapper_t umap) const
1245 {
1246 error ("%s: not defined for %s", get_umap_name (umap), type_name ().c_str ());
1247 return octave_value ();
1248 }
1249
1250 void
1251 octave_base_value::lock (void)
1252 {
1253 gripe_wrong_type_arg ("octave_base_value::lock ()", type_name ());
1254 }
1255
1256 void
1257 octave_base_value::unlock (void)
1258 {
1259 gripe_wrong_type_arg ("octave_base_value::unlock ()", type_name ());
1260 }
1261
1262 void
1263 octave_base_value::dump (std::ostream& os) const
1264 {
1265 dim_vector dv = this->dims ();
1266
1267 os << "class: " << this->class_name ()
1268 << " type: " << this->type_name ()
1269 << " dims: " << dv.str ();
1270 }
1271
1272 static void
1273 gripe_indexed_assignment (const std::string& tn1, const std::string& tn2)
1274 {
1275 error ("assignment of `%s' to indexed `%s' not implemented",
1276 tn2.c_str (), tn1.c_str ());
1277 }
1278
1279 static void
1280 gripe_assign_conversion_failed (const std::string& tn1,
1281 const std::string& tn2)
1282 {
1283 error ("type conversion for assignment of `%s' to indexed `%s' failed",
1284 tn2.c_str (), tn1.c_str ());
1285 }
1286
1287 static void
1288 gripe_no_conversion (const std::string& on, const std::string& tn1,
1289 const std::string& tn2)
1290 {
1291 error ("operator %s: no conversion for assignment of `%s' to indexed `%s'",
1292 on.c_str (), tn2.c_str (), tn1.c_str ());
1293 }
1294
1295 octave_value
1296 octave_base_value::numeric_assign (const std::string& type,
1297 const std::list<octave_value_list>& idx,
1298 const octave_value& rhs)
1299 {
1300 octave_value retval;
1301
1302 if (idx.front ().empty ())
1303 {
1304 error ("missing index in indexed assignment");
1305 return retval;
1306 }
1307
1308 int t_lhs = type_id ();
1309 int t_rhs = rhs.type_id ();
1310
1311 octave_value_typeinfo::assign_op_fcn f
1312 = octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
1313 t_lhs, t_rhs);
1314
1315 bool done = false;
1316
1317 if (f)
1318 {
1319 f (*this, idx.front (), rhs.get_rep ());
1320
1321 done = (! error_state);
1322 }
1323
1324 if (done)
1325 {
1326 count++;
1327 retval = octave_value (this);
1328 }
1329 else
1330 {
1331 int t_result
1332 = octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
1333
1334 if (t_result >= 0)
1335 {
1336 octave_base_value::type_conv_fcn cf
1337 = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
1338
1339 if (cf)
1340 {
1341 octave_base_value *tmp = cf (*this);
1342
1343 if (tmp)
1344 {
1345 octave_value val (tmp);
1346
1347 retval = val.subsasgn (type, idx, rhs);
1348
1349 done = (! error_state);
1350 }
1351 else
1352 gripe_assign_conversion_failed (type_name (),
1353 rhs.type_name ());
1354 }
1355 else
1356 gripe_indexed_assignment (type_name (), rhs.type_name ());
1357 }
1358
1359 if (! (done || error_state))
1360 {
1361 octave_value tmp_rhs;
1362
1363 octave_base_value::type_conv_info cf_rhs
1364 = rhs.numeric_conversion_function ();
1365
1366 octave_base_value::type_conv_info cf_this
1367 = numeric_conversion_function ();
1368
1369 // Try biased (one-sided) conversions first.
1370 if (cf_rhs.type_id () >= 0
1371 && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
1372 t_lhs, cf_rhs.type_id ())
1373 || octave_value_typeinfo::lookup_pref_assign_conv (t_lhs,
1374 cf_rhs.type_id ()) >= 0))
1375 cf_this = 0;
1376 else if (cf_this.type_id () >= 0
1377 && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
1378 cf_this.type_id (), t_rhs)
1379 || octave_value_typeinfo::lookup_pref_assign_conv (cf_this.type_id (),
1380 t_rhs) >= 0))
1381 cf_rhs = 0;
1382
1383 if (cf_rhs)
1384 {
1385 octave_base_value *tmp = cf_rhs (rhs.get_rep ());
1386
1387 if (tmp)
1388 tmp_rhs = octave_value (tmp);
1389 else
1390 {
1391 gripe_assign_conversion_failed (type_name (),
1392 rhs.type_name ());
1393 return octave_value ();
1394 }
1395 }
1396 else
1397 tmp_rhs = rhs;
1398
1399 count++;
1400 octave_value tmp_lhs = octave_value (this);
1401
1402 if (cf_this)
1403 {
1404 octave_base_value *tmp = cf_this (*this);
1405
1406 if (tmp)
1407 tmp_lhs = octave_value (tmp);
1408 else
1409 {
1410 gripe_assign_conversion_failed (type_name (),
1411 rhs.type_name ());
1412 return octave_value ();
1413 }
1414 }
1415
1416 if (cf_this || cf_rhs)
1417 {
1418 retval = tmp_lhs.subsasgn (type, idx, tmp_rhs);
1419
1420 done = (! error_state);
1421 }
1422 else
1423 gripe_no_conversion (octave_value::assign_op_as_string (octave_value::op_asn_eq),
1424 type_name (), rhs.type_name ());
1425 }
1426 }
1427
1428 // The assignment may have converted to a type that is wider than
1429 // necessary.
1430
1431 retval.maybe_mutate ();
1432
1433 return retval;
1434 }
1435
1436 // Current indentation.
1437 int octave_base_value::curr_print_indent_level = 0;
1438
1439 // TRUE means we are at the beginning of a line.
1440 bool octave_base_value::beginning_of_line = true;
1441
1442 // Each print() function should call this before printing anything.
1443 //
1444 // This doesn't need to be fast, but isn't there a better way?
1445
1446 void
1447 octave_base_value::indent (std::ostream& os) const
1448 {
1449 assert (curr_print_indent_level >= 0);
1450
1451 if (beginning_of_line)
1452 {
1453 // FIXME -- do we need this?
1454 // os << prefix;
1455
1456 for (int i = 0; i < curr_print_indent_level; i++)
1457 os << " ";
1458
1459 beginning_of_line = false;
1460 }
1461 }
1462
1463 // All print() functions should use this to print new lines.
1464
1465 void
1466 octave_base_value::newline (std::ostream& os) const
1467 {
1468 os << "\n";
1469
1470 beginning_of_line = true;
1471 }
1472
1473 // For ressetting print state.
1474
1475 void
1476 octave_base_value::reset (void) const
1477 {
1478 beginning_of_line = true;
1479 curr_print_indent_level = 0;
1480 }
1481
1482
1483 octave_value
1484 octave_base_value::fast_elem_extract (octave_idx_type) const
1485 {
1486 return octave_value ();
1487 }
1488
1489 bool
1490 octave_base_value::fast_elem_insert (octave_idx_type, const octave_value&)
1491 {
1492 return false;
1493 }
1494
1495 bool
1496 octave_base_value::fast_elem_insert_self (void *, builtin_type_t) const
1497 {
1498 return false;
1499 }
1500
1501 CONVDECLX (matrix_conv)
1502 {
1503 return new octave_matrix ();
1504 }
1505
1506 CONVDECLX (complex_matrix_conv)
1507 {
1508 return new octave_complex_matrix ();
1509 }
1510
1511 CONVDECLX (string_conv)
1512 {
1513 return new octave_char_matrix_str ();
1514 }
1515
1516 CONVDECLX (cell_conv)
1517 {
1518 return new octave_cell ();
1519 }
1520
1521 void
1522 install_base_type_conversions (void)
1523 {
1524 INSTALL_ASSIGNCONV (octave_base_value, octave_scalar, octave_matrix);
1525 INSTALL_ASSIGNCONV (octave_base_value, octave_matrix, octave_matrix);
1526 INSTALL_ASSIGNCONV (octave_base_value, octave_complex, octave_complex_matrix);
1527 INSTALL_ASSIGNCONV (octave_base_value, octave_complex_matrix, octave_complex_matrix);
1528 INSTALL_ASSIGNCONV (octave_base_value, octave_range, octave_matrix);
1529 INSTALL_ASSIGNCONV (octave_base_value, octave_char_matrix_str, octave_char_matrix_str);
1530 INSTALL_ASSIGNCONV (octave_base_value, octave_cell, octave_cell);
1531
1532 INSTALL_WIDENOP (octave_base_value, octave_matrix, matrix_conv);
1533 INSTALL_WIDENOP (octave_base_value, octave_complex_matrix, complex_matrix_conv);
1534 INSTALL_WIDENOP (octave_base_value, octave_char_matrix_str, string_conv);
1535 INSTALL_WIDENOP (octave_base_value, octave_cell, cell_conv);
1536 }
1537
1538 DEFUN (sparse_auto_mutate, args, nargout,
1539 "-*- texinfo -*-\n\
1540 @deftypefn {Built-in Function} {@var{val} =} sparse_auto_mutate ()\n\
1541 @deftypefnx {Built-in Function} {@var{old_val} =} sparse_auto_mutate (@var{new_val})\n\
1542 @deftypefnx {Built-in Function} {} sparse_auto_mutate (@var{new_val}, \"local\")\n\
1543 Query or set the internal variable that controls whether Octave will\n\
1544 automatically mutate sparse matrices to full matrices to save memory.\n\
1545 For example:\n\
1546 \n\
1547 @example\n\
1548 @group\n\
1549 s = speye (3);\n\
1550 sparse_auto_mutate (false);\n\
1551 s(:, 1) = 1;\n\
1552 typeinfo (s)\n\
1553 @result{} sparse matrix\n\
1554 sparse_auto_mutate (true);\n\
1555 s(1, :) = 1;\n\
1556 typeinfo (s)\n\
1557 @result{} matrix\n\
1558 @end group\n\
1559 @end example\n\
1560 \n\
1561 When called from inside a function with the \"local\" option, the variable is\n\
1562 changed locally for the function and any subroutines it calls. The original\n\
1563 variable value is restored when exiting the function.\n\
1564 @end deftypefn")
1565 {
1566 return SET_INTERNAL_VARIABLE (sparse_auto_mutate);
1567 }
1568
1569 /*
1570 %!test
1571 %! s = speye (3);
1572 %! sparse_auto_mutate (false);
1573 %! s(:, 1) = 1;
1574 %! assert (typeinfo (s), "sparse matrix");
1575 %! sparse_auto_mutate (true);
1576 %! s(1, :) = 1;
1577 %! assert (typeinfo (s), "matrix");
1578 %! sparse_auto_mutate (false);
1579 */