1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29
30 #include <istream>
31 #include <limits>
32 #include <ostream>
33
34 #include "lo-ieee.h"
35 #include "lo-mappers.h"
36
37 #include "defun.h"
38 #include "errwarn.h"
39 #include "interpreter-private.h"
40 #include "interpreter.h"
41 #include "mxarray.h"
42 #include "oct-hdf5.h"
43 #include "oct-lvalue.h"
44 #include "oct-map.h"
45 #include "oct-stream.h"
46 #include "ops.h"
47 #include "ov-base.h"
48 #include "ov-cell.h"
49 #include "ov-ch-mat.h"
50 #include "ov-classdef.h"
51 #include "ov-complex.h"
52 #include "ov-cx-mat.h"
53 #include "ov-fcn-handle.h"
54 #include "ov-range.h"
55 #include "ov-re-mat.h"
56 #include "ov-scalar.h"
57 #include "ov-str-mat.h"
58 #include "ovl.h"
59 #include "parse.h"
60 #include "pr-flt-fmt.h"
61 #include "pr-output.h"
62 #include "utils.h"
63 #include "variables.h"
64
btyp_mixed_numeric(builtin_type_t x,builtin_type_t y)65 builtin_type_t btyp_mixed_numeric (builtin_type_t x, builtin_type_t y)
66 {
67 builtin_type_t retval = btyp_unknown;
68
69 if (x == btyp_bool)
70 x = btyp_double;
71 if (y == btyp_bool)
72 y = btyp_double;
73
74 if (x <= btyp_float_complex && y <= btyp_float_complex)
75 retval = static_cast<builtin_type_t> (x | y);
76 else if (x <= btyp_uint64 && y <= btyp_float)
77 retval = x;
78 else if (x <= btyp_float && y <= btyp_uint64)
79 retval = y;
80 else if ((x >= btyp_int8 && x <= btyp_int64
81 && y >= btyp_int8 && y <= btyp_int64)
82 || (x >= btyp_uint8 && x <= btyp_uint64
83 && y >= btyp_uint8 && y <= btyp_uint64))
84 retval = (x > y) ? x : y;
85
86 return retval;
87 }
88
89 std::string btyp_class_name[btyp_num_types] =
90 {
91 "double", "single", "double", "single",
92 "int8", "int16", "int32", "int64",
93 "uint8", "uint16", "uint32", "uint64",
94 "logical", "char",
95 "struct", "cell", "function_handle"
96 };
97
98 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_base_value,
99 "<unknown type>", "unknown");
100
101 // TRUE means to perform automatic sparse to real mutation if there
102 // is memory to be saved
103 bool Vsparse_auto_mutate = false;
104
105 octave_base_value *
empty_clone(void) const106 octave_base_value::empty_clone (void) const
107 {
108 return resize (dim_vector ()).clone ();
109 }
110
111 octave_value
squeeze(void) const112 octave_base_value::squeeze (void) const
113 {
114 std::string nm = type_name ();
115 error ("squeeze: invalid operation for %s type", nm.c_str ());
116 }
117
118 octave_value
full_value(void) const119 octave_base_value::full_value (void) const
120 {
121 err_wrong_type_arg ("full: invalid operation for %s type", type_name ());
122 }
123
124 octave_value
as_double(void) const125 octave_base_value::as_double (void) const
126 {
127 err_invalid_conversion (type_name (), "double");
128 }
129
130 octave_value
as_single(void) const131 octave_base_value::as_single (void) const
132 {
133 err_invalid_conversion (type_name (), "single");
134 }
135
136 octave_value
as_int8(void) const137 octave_base_value::as_int8 (void) const
138 {
139 err_invalid_conversion (type_name (), "int8");
140 }
141
142 octave_value
as_int16(void) const143 octave_base_value::as_int16 (void) const
144 {
145 err_invalid_conversion (type_name (), "int16");
146 }
147
148 octave_value
as_int32(void) const149 octave_base_value::as_int32 (void) const
150 {
151 err_invalid_conversion (type_name (), "int32");
152 }
153
154 octave_value
as_int64(void) const155 octave_base_value::as_int64 (void) const
156 {
157 err_invalid_conversion (type_name (), "int64");
158 }
159
160 octave_value
as_uint8(void) const161 octave_base_value::as_uint8 (void) const
162 {
163 err_invalid_conversion (type_name (), "uint8");
164 }
165
166 octave_value
as_uint16(void) const167 octave_base_value::as_uint16 (void) const
168 {
169 err_invalid_conversion (type_name (), "uint16");
170 }
171
172 octave_value
as_uint32(void) const173 octave_base_value::as_uint32 (void) const
174 {
175 err_invalid_conversion (type_name (), "uint32");
176 }
177
178 octave_value
as_uint64(void) const179 octave_base_value::as_uint64 (void) const
180 {
181 err_invalid_conversion (type_name (), "uint64");
182 }
183
184 Matrix
size(void)185 octave_base_value::size (void)
186 {
187 const dim_vector dv = dims ();
188 Matrix mdv (1, dv.ndims ());
189 for (octave_idx_type i = 0; i < dv.ndims (); i++)
190 mdv(i) = dv(i);
191 return mdv;
192 }
193
194 octave_idx_type
xnumel(const octave_value_list & idx)195 octave_base_value::xnumel (const octave_value_list& idx)
196 {
197 return octave::dims_to_numel (dims (), idx);
198 }
199
200 octave_value
subsref(const std::string &,const std::list<octave_value_list> &)201 octave_base_value::subsref (const std::string&,
202 const std::list<octave_value_list>&)
203 {
204 std::string nm = type_name ();
205 error ("can't perform indexing operations for %s type", nm.c_str ());
206 }
207
208 octave_value_list
subsref(const std::string &,const std::list<octave_value_list> &,int)209 octave_base_value::subsref (const std::string&,
210 const std::list<octave_value_list>&, int)
211 {
212 std::string nm = type_name ();
213 error ("can't perform indexing operations for %s type", nm.c_str ());
214 }
215
216 octave_value
subsref(const std::string & type,const std::list<octave_value_list> & idx,bool)217 octave_base_value::subsref (const std::string& type,
218 const std::list<octave_value_list>& idx,
219 bool /* auto_add */)
220 {
221 // This way we may get a more meaningful error message.
222 return subsref (type, idx);
223 }
224
225 octave_value
do_index_op(const octave_value_list &,bool)226 octave_base_value::do_index_op (const octave_value_list&, bool)
227 {
228 std::string nm = type_name ();
229 error ("can't perform indexing operations for %s type", nm.c_str ());
230 }
231
232 idx_vector
index_vector(bool) const233 octave_base_value::index_vector (bool /* require_integers */) const
234 {
235 std::string nm = '<' + type_name () + '>';
236 octave::err_invalid_index (nm.c_str ());
237 }
238
239 octave_value
subsasgn(const std::string & type,const std::list<octave_value_list> & idx,const octave_value & rhs)240 octave_base_value::subsasgn (const std::string& type,
241 const std::list<octave_value_list>& idx,
242 const octave_value& rhs)
243 {
244 octave_value retval;
245
246 if (is_defined ())
247 {
248 if (! isnumeric ())
249 {
250 std::string nm = type_name ();
251 error ("can't perform indexed assignment for %s type", nm.c_str ());
252 }
253
254 switch (type[0])
255 {
256 case '(':
257 {
258 if (type.length () == 1)
259 retval = numeric_assign (type, idx, rhs);
260 else if (isempty ())
261 {
262 // Allow conversion of empty matrix to some other
263 // type in cases like
264 //
265 // x = []; x(i).f = rhs
266
267 octave_value tmp = octave_value::empty_conv (type, rhs);
268
269 retval = tmp.subsasgn (type, idx, rhs);
270 }
271 else
272 {
273 std::string nm = type_name ();
274 error ("in indexed assignment of %s, last rhs index must be ()",
275 nm.c_str ());
276 }
277 }
278 break;
279
280 case '{':
281 case '.':
282 {
283 std::string nm = type_name ();
284 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
285 }
286 break;
287
288 default:
289 panic_impossible ();
290 }
291 }
292 else
293 {
294 // Create new object of appropriate type for given index and rhs
295 // types and then call undef_subsasgn for that object.
296
297 octave_value tmp = octave_value::empty_conv (type, rhs);
298
299 retval = tmp.undef_subsasgn (type, idx, rhs);
300 }
301
302 return retval;
303 }
304
305 octave_value
undef_subsasgn(const std::string & type,const std::list<octave_value_list> & idx,const octave_value & rhs)306 octave_base_value::undef_subsasgn (const std::string& type,
307 const std::list<octave_value_list>& idx,
308 const octave_value& rhs)
309 {
310 // In most cases, undef_subsasgn is handled the sams as subsasgn. One
311 // exception is octave_class objects.
312
313 return subsasgn (type, idx, rhs);
314 }
315
316 octave_idx_type
nnz(void) const317 octave_base_value::nnz (void) const
318 {
319 err_wrong_type_arg ("octave_base_value::nnz ()", type_name ());
320 }
321
322 octave_idx_type
nzmax(void) const323 octave_base_value::nzmax (void) const
324 {
325 return numel ();
326 }
327
328 octave_idx_type
nfields(void) const329 octave_base_value::nfields (void) const
330 {
331 err_wrong_type_arg ("octave_base_value::nfields ()", type_name ());
332 }
333
334 octave_value
reshape(const dim_vector &) const335 octave_base_value::reshape (const dim_vector&) const
336 {
337 err_wrong_type_arg ("octave_base_value::reshape ()", type_name ());
338 }
339
340 octave_value
permute(const Array<int> &,bool) const341 octave_base_value::permute (const Array<int>&, bool) const
342 {
343 err_wrong_type_arg ("octave_base_value::permute ()", type_name ());
344 }
345
346 octave_value
resize(const dim_vector &,bool) const347 octave_base_value::resize (const dim_vector&, bool) const
348 {
349 err_wrong_type_arg ("octave_base_value::resize ()", type_name ());
350 }
351
352 MatrixType
matrix_type(void) const353 octave_base_value::matrix_type (void) const
354 {
355 err_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
356 }
357
358 MatrixType
matrix_type(const MatrixType &) const359 octave_base_value::matrix_type (const MatrixType&) const
360 {
361 err_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
362 }
363
364 octave_value
all(int) const365 octave_base_value::all (int) const
366 {
367 return 0.0;
368 }
369
370 octave_value
any(int) const371 octave_base_value::any (int) const
372 {
373 return 0.0;
374 }
375
376 octave_value
convert_to_str(bool pad,bool force,char type) const377 octave_base_value::convert_to_str (bool pad, bool force, char type) const
378 {
379 octave_value retval = convert_to_str_internal (pad, force, type);
380
381 if (! force && isnumeric ())
382 warn_implicit_conversion ("Octave:num-to-str",
383 type_name (), retval.type_name ());
384
385 return retval;
386 }
387
388 octave_value
convert_to_str_internal(bool,bool,char) const389 octave_base_value::convert_to_str_internal (bool, bool, char) const
390 {
391 err_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
392 type_name ());
393 }
394
395 void
convert_to_row_or_column_vector(void)396 octave_base_value::convert_to_row_or_column_vector (void)
397 {
398 err_wrong_type_arg
399 ("octave_base_value::convert_to_row_or_column_vector ()", type_name ());
400 }
401
402 void
print(std::ostream &,bool)403 octave_base_value::print (std::ostream&, bool)
404 {
405 err_wrong_type_arg ("octave_base_value::print ()", type_name ());
406 }
407
408 void
print_raw(std::ostream &,bool) const409 octave_base_value::print_raw (std::ostream&, bool) const
410 {
411 err_wrong_type_arg ("octave_base_value::print_raw ()", type_name ());
412 }
413
414 bool
print_name_tag(std::ostream & os,const std::string & name) const415 octave_base_value::print_name_tag (std::ostream& os,
416 const std::string& name) const
417 {
418 indent (os);
419
420 if (print_as_scalar ())
421 os << name << " = ";
422 else
423 {
424 os << name << " =";
425 newline (os);
426 if (! Vcompact_format)
427 newline (os);
428
429 return true;
430 }
431
432 return false;
433 }
434
435 void
print_with_name(std::ostream & output_buf,const std::string & name,bool print_padding)436 octave_base_value::print_with_name (std::ostream& output_buf,
437 const std::string& name,
438 bool print_padding)
439 {
440 bool pad_after = print_name_tag (output_buf, name);
441
442 print (output_buf);
443
444 if (print_padding && pad_after && ! Vcompact_format)
445 newline (output_buf);
446 }
447
448 float_display_format
get_edit_display_format(void) const449 octave_base_value::get_edit_display_format (void) const
450 {
451 return float_display_format ();
452 }
453
454 void
print_info(std::ostream & os,const std::string &) const455 octave_base_value::print_info (std::ostream& os,
456 const std::string& /* prefix */) const
457 {
458 os << "no info for type: " << type_name () << "\n";
459 }
460
461 #define INT_CONV_METHOD(T, F) \
462 T \
463 octave_base_value::F ## _value (bool require_int, bool frc_str_conv) const \
464 { \
465 T retval = 0; \
466 \
467 double d = 0.0; \
468 \
469 try \
470 { \
471 d = double_value (frc_str_conv); \
472 } \
473 catch (octave::execution_exception& e) \
474 { \
475 err_wrong_type_arg (e, "octave_base_value::" #F "_value ()", type_name ()); \
476 } \
477 \
478 if (require_int && octave::math::x_nint (d) != d) \
479 error_with_cfn ("conversion of %g to " #T " value failed", d); \
480 else if (d < std::numeric_limits<T>::min ()) \
481 retval = std::numeric_limits<T>::min (); \
482 else if (d > std::numeric_limits<T>::max ()) \
483 retval = std::numeric_limits<T>::max (); \
484 else \
485 retval = static_cast<T> (octave::math::fix (d)); \
486 \
487 return retval; \
488 }
489
INT_CONV_METHOD(short int,short)490 INT_CONV_METHOD (short int, short)
491 INT_CONV_METHOD (unsigned short int, ushort)
492
493 INT_CONV_METHOD (int, int)
494 INT_CONV_METHOD (unsigned int, uint)
495
496 INT_CONV_METHOD (long int, long)
497 INT_CONV_METHOD (unsigned long int, ulong)
498
499 INT_CONV_METHOD (int64_t, int64)
500 INT_CONV_METHOD (uint64_t, uint64)
501
502 int
503 octave_base_value::nint_value (bool frc_str_conv) const
504 {
505 double d = 0.0;
506
507 try
508 {
509 d = double_value (frc_str_conv);
510 }
511 catch (octave::execution_exception& e)
512 {
513 err_wrong_type_arg (e, "octave_base_value::nint_value ()", type_name ());
514 }
515
516 if (octave::math::isnan (d))
517 error ("conversion of NaN to integer value failed");
518
519 return static_cast<int> (octave::math::fix (d));
520 }
521
522 double
double_value(bool) const523 octave_base_value::double_value (bool) const
524 {
525 err_wrong_type_arg ("octave_base_value::double_value ()", type_name ());
526 }
527
528 float
float_value(bool) const529 octave_base_value::float_value (bool) const
530 {
531 err_wrong_type_arg ("octave_base_value::float_value ()", type_name ());
532 }
533
534 Cell
cell_value() const535 octave_base_value::cell_value () const
536 {
537 err_wrong_type_arg ("octave_base_value::cell_value()", type_name ());
538 }
539
540 Matrix
matrix_value(bool) const541 octave_base_value::matrix_value (bool) const
542 {
543 err_wrong_type_arg ("octave_base_value::matrix_value()", type_name ());
544 }
545
546 FloatMatrix
float_matrix_value(bool) const547 octave_base_value::float_matrix_value (bool) const
548 {
549 err_wrong_type_arg ("octave_base_value::float_matrix_value()", type_name ());
550 }
551
552 NDArray
array_value(bool) const553 octave_base_value::array_value (bool) const
554 {
555 err_wrong_type_arg ("octave_base_value::array_value()", type_name ());
556 }
557
558 FloatNDArray
float_array_value(bool) const559 octave_base_value::float_array_value (bool) const
560 {
561 err_wrong_type_arg ("octave_base_value::float_array_value()", type_name ());
562 }
563
564 Complex
complex_value(bool) const565 octave_base_value::complex_value (bool) const
566 {
567 err_wrong_type_arg ("octave_base_value::complex_value()", type_name ());
568 }
569
570 FloatComplex
float_complex_value(bool) const571 octave_base_value::float_complex_value (bool) const
572 {
573 err_wrong_type_arg ("octave_base_value::float_complex_value()", type_name ());
574 }
575
576 ComplexMatrix
complex_matrix_value(bool) const577 octave_base_value::complex_matrix_value (bool) const
578 {
579 err_wrong_type_arg ("octave_base_value::complex_matrix_value()",
580 type_name ());
581 }
582
583 FloatComplexMatrix
float_complex_matrix_value(bool) const584 octave_base_value::float_complex_matrix_value (bool) const
585 {
586 err_wrong_type_arg ("octave_base_value::float_complex_matrix_value()",
587 type_name ());
588 }
589
590 ComplexNDArray
complex_array_value(bool) const591 octave_base_value::complex_array_value (bool) const
592 {
593 err_wrong_type_arg ("octave_base_value::complex_array_value()", type_name ());
594 }
595
596 FloatComplexNDArray
float_complex_array_value(bool) const597 octave_base_value::float_complex_array_value (bool) const
598 {
599 err_wrong_type_arg ("octave_base_value::float_complex_array_value()",
600 type_name ());
601 }
602
603 bool
bool_value(bool) const604 octave_base_value::bool_value (bool) const
605 {
606 err_wrong_type_arg ("octave_base_value::bool_value()", type_name ());
607 }
608
609 boolMatrix
bool_matrix_value(bool) const610 octave_base_value::bool_matrix_value (bool) const
611 {
612 err_wrong_type_arg ("octave_base_value::bool_matrix_value()", type_name ());
613 }
614
615 boolNDArray
bool_array_value(bool) const616 octave_base_value::bool_array_value (bool) const
617 {
618 err_wrong_type_arg ("octave_base_value::bool_array_value()", type_name ());
619 }
620
621 charMatrix
char_matrix_value(bool force) const622 octave_base_value::char_matrix_value (bool force) const
623 {
624 octave_value tmp = convert_to_str (false, force);
625
626 return tmp.char_matrix_value ();
627 }
628
629 charNDArray
char_array_value(bool) const630 octave_base_value::char_array_value (bool) const
631 {
632 err_wrong_type_arg ("octave_base_value::char_array_value()", type_name ());
633 }
634
635 SparseMatrix
sparse_matrix_value(bool) const636 octave_base_value::sparse_matrix_value (bool) const
637 {
638 err_wrong_type_arg ("octave_base_value::sparse_matrix_value()", type_name ());
639 }
640
641 SparseComplexMatrix
sparse_complex_matrix_value(bool) const642 octave_base_value::sparse_complex_matrix_value (bool) const
643 {
644 err_wrong_type_arg ("octave_base_value::sparse_complex_matrix_value()",
645 type_name ());
646 }
647
648 SparseBoolMatrix
sparse_bool_matrix_value(bool) const649 octave_base_value::sparse_bool_matrix_value (bool) const
650 {
651 err_wrong_type_arg ("octave_base_value::sparse_bool_matrix_value()",
652 type_name ());
653 }
654
655 DiagMatrix
diag_matrix_value(bool) const656 octave_base_value::diag_matrix_value (bool) const
657 {
658 err_wrong_type_arg ("octave_base_value::diag_matrix_value()", type_name ());
659 }
660
661 FloatDiagMatrix
float_diag_matrix_value(bool) const662 octave_base_value::float_diag_matrix_value (bool) const
663 {
664 err_wrong_type_arg ("octave_base_value::float_diag_matrix_value()",
665 type_name ());
666 }
667
668 ComplexDiagMatrix
complex_diag_matrix_value(bool) const669 octave_base_value::complex_diag_matrix_value (bool) const
670 {
671 err_wrong_type_arg ("octave_base_value::complex_diag_matrix_value()",
672 type_name ());
673 }
674
675 FloatComplexDiagMatrix
float_complex_diag_matrix_value(bool) const676 octave_base_value::float_complex_diag_matrix_value (bool) const
677 {
678 err_wrong_type_arg ("octave_base_value::float_complex_diag_matrix_value()",
679 type_name ());
680 }
681
682 PermMatrix
perm_matrix_value(void) const683 octave_base_value::perm_matrix_value (void) const
684 {
685 err_wrong_type_arg ("octave_base_value::perm_matrix_value()", type_name ());
686 }
687
688 octave_int8
int8_scalar_value(void) const689 octave_base_value::int8_scalar_value (void) const
690 {
691 err_wrong_type_arg ("octave_base_value::int8_scalar_value()", type_name ());
692 }
693
694 octave_int16
int16_scalar_value(void) const695 octave_base_value::int16_scalar_value (void) const
696 {
697 err_wrong_type_arg ("octave_base_value::int16_scalar_value()", type_name ());
698 }
699
700 octave_int32
int32_scalar_value(void) const701 octave_base_value::int32_scalar_value (void) const
702 {
703 err_wrong_type_arg ("octave_base_value::int32_scalar_value()", type_name ());
704 }
705
706 octave_int64
int64_scalar_value(void) const707 octave_base_value::int64_scalar_value (void) const
708 {
709 err_wrong_type_arg ("octave_base_value::int64_scalar_value()", type_name ());
710 }
711
712 octave_uint8
uint8_scalar_value(void) const713 octave_base_value::uint8_scalar_value (void) const
714 {
715 err_wrong_type_arg ("octave_base_value::uint8_scalar_value()", type_name ());
716 }
717
718 octave_uint16
uint16_scalar_value(void) const719 octave_base_value::uint16_scalar_value (void) const
720 {
721 err_wrong_type_arg ("octave_base_value::uint16_scalar_value()", type_name ());
722 }
723
724 octave_uint32
uint32_scalar_value(void) const725 octave_base_value::uint32_scalar_value (void) const
726 {
727 err_wrong_type_arg ("octave_base_value::uint32_scalar_value()", type_name ());
728 }
729
730 octave_uint64
uint64_scalar_value(void) const731 octave_base_value::uint64_scalar_value (void) const
732 {
733 err_wrong_type_arg ("octave_base_value::uint64_scalar_value()", type_name ());
734 }
735
736 int8NDArray
int8_array_value(void) const737 octave_base_value::int8_array_value (void) const
738 {
739 err_wrong_type_arg ("octave_base_value::int8_array_value()", type_name ());
740 }
741
742 int16NDArray
int16_array_value(void) const743 octave_base_value::int16_array_value (void) const
744 {
745 err_wrong_type_arg ("octave_base_value::int16_array_value()", type_name ());
746 }
747
748 int32NDArray
int32_array_value(void) const749 octave_base_value::int32_array_value (void) const
750 {
751 err_wrong_type_arg ("octave_base_value::int32_array_value()", type_name ());
752 }
753
754 int64NDArray
int64_array_value(void) const755 octave_base_value::int64_array_value (void) const
756 {
757 err_wrong_type_arg ("octave_base_value::int64_array_value()", type_name ());
758 }
759
760 uint8NDArray
uint8_array_value(void) const761 octave_base_value::uint8_array_value (void) const
762 {
763 err_wrong_type_arg ("octave_base_value::uint8_array_value()", type_name ());
764 }
765
766 uint16NDArray
uint16_array_value(void) const767 octave_base_value::uint16_array_value (void) const
768 {
769 err_wrong_type_arg ("octave_base_value::uint16_array_value()", type_name ());
770 }
771
772 uint32NDArray
uint32_array_value(void) const773 octave_base_value::uint32_array_value (void) const
774 {
775 err_wrong_type_arg ("octave_base_value::uint32_array_value()", type_name ());
776 }
777
778 uint64NDArray
uint64_array_value(void) const779 octave_base_value::uint64_array_value (void) const
780 {
781 err_wrong_type_arg ("octave_base_value::uint64_array_value()", type_name ());
782 }
783
784 string_vector
string_vector_value(bool pad) const785 octave_base_value::string_vector_value (bool pad) const
786 {
787 octave_value tmp = convert_to_str (pad, true);
788
789 return tmp.string_vector_value ();
790 }
791
792 std::string
string_value(bool force) const793 octave_base_value::string_value (bool force) const
794 {
795 octave_value tmp = convert_to_str (force);
796
797 return tmp.string_value ();
798 }
799
800 std::string
xstring_value(void) const801 octave_base_value::xstring_value (void) const
802 {
803 wrong_type_arg_error ();
804
805 return std::string ();
806 }
807
808 Array<std::string>
cellstr_value(void) const809 octave_base_value::cellstr_value (void) const
810 {
811 err_wrong_type_arg ("octave_base_value::cellstr_value()", type_name ());
812 }
813
814 Range
range_value(void) const815 octave_base_value::range_value (void) const
816 {
817 err_wrong_type_arg ("octave_base_value::range_value()", type_name ());
818 }
819
820 octave_map
map_value(void) const821 octave_base_value::map_value (void) const
822 {
823 err_wrong_type_arg ("octave_base_value::map_value()", type_name ());
824 }
825
826 octave_scalar_map
scalar_map_value(void) const827 octave_base_value::scalar_map_value (void) const
828 {
829 octave_map tmp = map_value ();
830
831 if (tmp.numel () != 1)
832 error ("invalid conversion of multi-dimensional struct to scalar struct");
833
834 return octave_scalar_map (tmp.checkelem (0));
835 }
836
837 string_vector
map_keys(void) const838 octave_base_value::map_keys (void) const
839 {
840 err_wrong_type_arg ("octave_base_value::map_keys()", type_name ());
841 }
842
843 std::size_t
nparents(void) const844 octave_base_value::nparents (void) const
845 {
846 err_wrong_type_arg ("octave_base_value::nparents()", type_name ());
847 }
848
849 std::list<std::string>
parent_class_name_list(void) const850 octave_base_value::parent_class_name_list (void) const
851 {
852 err_wrong_type_arg ("octave_base_value::parent_class_name_list()",
853 type_name ());
854 }
855
856 string_vector
parent_class_names(void) const857 octave_base_value::parent_class_names (void) const
858 {
859 err_wrong_type_arg ("octave_base_value::parent_class_names()", type_name ());
860 }
861
862 octave_classdef *
classdef_object_value(bool silent)863 octave_base_value::classdef_object_value (bool silent)
864 {
865 if (! silent)
866 err_wrong_type_arg ("octave_base_value::classdef_object_value()",
867 type_name ());
868
869 return nullptr;
870 }
871
872 octave_function *
function_value(bool silent)873 octave_base_value::function_value (bool silent)
874 {
875 if (! silent)
876 err_wrong_type_arg ("octave_base_value::function_value()", type_name ());
877
878 return nullptr;
879 }
880
881 octave_user_function *
user_function_value(bool silent)882 octave_base_value::user_function_value (bool silent)
883 {
884 if (! silent)
885 err_wrong_type_arg ("octave_base_value::user_function_value()",
886 type_name ());
887 return nullptr;
888 }
889
890 octave_user_script *
user_script_value(bool silent)891 octave_base_value::user_script_value (bool silent)
892 {
893 if (! silent)
894 err_wrong_type_arg ("octave_base_value::user_script_value()", type_name ());
895
896 return nullptr;
897 }
898
899 octave_user_code *
user_code_value(bool silent)900 octave_base_value::user_code_value (bool silent)
901 {
902 if (! silent)
903 err_wrong_type_arg ("octave_base_value::user_code_value()", type_name ());
904
905 return nullptr;
906 }
907
908 octave_fcn_handle *
fcn_handle_value(bool silent)909 octave_base_value::fcn_handle_value (bool silent)
910 {
911 if (! silent)
912 err_wrong_type_arg ("octave_base_value::fcn_handle_value()", type_name ());
913
914 return nullptr;
915 }
916
917 octave_value_list
list_value(void) const918 octave_base_value::list_value (void) const
919 {
920 err_wrong_type_arg ("octave_base_value::list_value()", type_name ());
921 }
922
923 bool
save_ascii(std::ostream &)924 octave_base_value::save_ascii (std::ostream&)
925 {
926 err_wrong_type_arg ("octave_base_value::save_ascii()", type_name ());
927 }
928
929 bool
load_ascii(std::istream &)930 octave_base_value::load_ascii (std::istream&)
931 {
932 err_wrong_type_arg ("octave_base_value::load_ascii()", type_name ());
933 }
934
935 bool
save_binary(std::ostream &,bool)936 octave_base_value::save_binary (std::ostream&, bool)
937 {
938 err_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
939 }
940
941 bool
load_binary(std::istream &,bool,octave::mach_info::float_format)942 octave_base_value::load_binary (std::istream&, bool,
943 octave::mach_info::float_format)
944 {
945 err_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
946 }
947
948 bool
save_hdf5(octave_hdf5_id,const char *,bool)949 octave_base_value::save_hdf5 (octave_hdf5_id, const char *, bool)
950 {
951 err_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
952 }
953
954 bool
load_hdf5(octave_hdf5_id,const char *)955 octave_base_value::load_hdf5 (octave_hdf5_id, const char *)
956 {
957 err_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
958 }
959
960 int
write(octave::stream &,int,oct_data_conv::data_type,int,octave::mach_info::float_format) const961 octave_base_value::write (octave::stream&, int, oct_data_conv::data_type,
962 int, octave::mach_info::float_format) const
963 {
964 err_wrong_type_arg ("octave_base_value::write()", type_name ());
965 }
966
967 mxArray *
as_mxArray(void) const968 octave_base_value::as_mxArray (void) const
969 {
970 return nullptr;
971 }
972
973 octave_value
diag(octave_idx_type) const974 octave_base_value::diag (octave_idx_type) const
975 {
976 err_wrong_type_arg ("octave_base_value::diag ()", type_name ());
977 }
978
979 octave_value
diag(octave_idx_type,octave_idx_type) const980 octave_base_value::diag (octave_idx_type, octave_idx_type) const
981 {
982 err_wrong_type_arg ("octave_base_value::diag ()", type_name ());
983 }
984
985 octave_value
sort(octave_idx_type,sortmode) const986 octave_base_value::sort (octave_idx_type, sortmode) const
987 {
988 err_wrong_type_arg ("octave_base_value::sort ()", type_name ());
989 }
990
991 octave_value
sort(Array<octave_idx_type> &,octave_idx_type,sortmode) const992 octave_base_value::sort (Array<octave_idx_type> &,
993 octave_idx_type, sortmode) const
994 {
995 err_wrong_type_arg ("octave_base_value::sort ()", type_name ());
996 }
997
998 sortmode
issorted(sortmode) const999 octave_base_value::issorted (sortmode) const
1000 {
1001 err_wrong_type_arg ("octave_base_value::issorted ()", type_name ());
1002 }
1003
1004 Array<octave_idx_type>
sort_rows_idx(sortmode) const1005 octave_base_value::sort_rows_idx (sortmode) const
1006 {
1007 err_wrong_type_arg ("octave_base_value::sort_rows_idx ()", type_name ());
1008 }
1009
1010 sortmode
is_sorted_rows(sortmode) const1011 octave_base_value::is_sorted_rows (sortmode) const
1012 {
1013 err_wrong_type_arg ("octave_base_value::is_sorted_rows ()", type_name ());
1014 }
1015
1016 const char *
get_umap_name(unary_mapper_t umap)1017 octave_base_value::get_umap_name (unary_mapper_t umap)
1018 {
1019 static const char *names[num_unary_mappers] =
1020 {
1021 "abs",
1022 "acos",
1023 "acosh",
1024 "angle",
1025 "arg",
1026 "asin",
1027 "asinh",
1028 "atan",
1029 "atanh",
1030 "cbrt",
1031 "ceil",
1032 "conj",
1033 "cos",
1034 "cosh",
1035 "erf",
1036 "erfinv",
1037 "erfcinv",
1038 "erfc",
1039 "erfcx",
1040 "erfi",
1041 "dawson",
1042 "exp",
1043 "expm1",
1044 "isfinite",
1045 "fix",
1046 "floor",
1047 "gamma",
1048 "imag",
1049 "isinf",
1050 "isna",
1051 "isnan",
1052 "lgamma",
1053 "log",
1054 "log2",
1055 "log10",
1056 "log1p",
1057 "real",
1058 "round",
1059 "roundb",
1060 "signum",
1061 "sin",
1062 "sinh",
1063 "sqrt",
1064 "tan",
1065 "tanh",
1066 "isalnum",
1067 "isalpha",
1068 "isascii",
1069 "iscntrl",
1070 "isdigit",
1071 "isgraph",
1072 "islower",
1073 "isprint",
1074 "ispunct",
1075 "isspace",
1076 "isupper",
1077 "isxdigit",
1078 "signbit",
1079 "tolower",
1080 "toupper"
1081 };
1082
1083 if (umap < 0 || umap >= num_unary_mappers)
1084 return "unknown";
1085 else
1086 return names[umap];
1087 }
1088
1089 void
warn_load(const char * type) const1090 octave_base_value::warn_load (const char *type) const
1091 {
1092 warning_with_id
1093 ("Octave:load-save-unavailable",
1094 "%s: loading %s files not available in this version of Octave",
1095 t_name.c_str (), type);
1096 }
1097
1098 void
warn_save(const char * type) const1099 octave_base_value::warn_save (const char *type) const
1100 {
1101 warning_with_id
1102 ("Octave:load-save-unavailable",
1103 "%s: saving %s files not available in this version of Octave",
1104 t_name.c_str (), type);
1105 }
1106
1107 void
wrong_type_arg_error(void) const1108 octave_base_value::wrong_type_arg_error (void) const
1109 {
1110 err_wrong_type_arg (type_name ());
1111 }
1112
1113 octave_value
map(unary_mapper_t umap) const1114 octave_base_value::map (unary_mapper_t umap) const
1115 {
1116 error ("%s: not defined for %s", get_umap_name (umap), type_name ().c_str ());
1117 }
1118
1119 void
lock(void)1120 octave_base_value::lock (void)
1121 {
1122 err_wrong_type_arg ("octave_base_value::lock ()", type_name ());
1123 }
1124
1125 void
unlock(void)1126 octave_base_value::unlock (void)
1127 {
1128 err_wrong_type_arg ("octave_base_value::unlock ()", type_name ());
1129 }
1130
1131 octave_value
dump(void) const1132 octave_base_value::dump (void) const
1133 {
1134 std::map<std::string, octave_value> m
1135 = {{ "class", this->class_name () },
1136 { "type", this->type_name () },
1137 { "dims", this->dims().as_array () }};
1138
1139 return octave_value (m);
1140 }
1141
1142 OCTAVE_NORETURN static
1143 void
err_indexed_assignment(const std::string & tn1,const std::string & tn2)1144 err_indexed_assignment (const std::string& tn1, const std::string& tn2)
1145 {
1146 error ("assignment of '%s' to indexed '%s' not implemented",
1147 tn2.c_str (), tn1.c_str ());
1148 }
1149
1150 OCTAVE_NORETURN static
1151 void
err_assign_conversion_failed(const std::string & tn1,const std::string & tn2)1152 err_assign_conversion_failed (const std::string& tn1, const std::string& tn2)
1153 {
1154 error ("type conversion for assignment of '%s' to indexed '%s' failed",
1155 tn2.c_str (), tn1.c_str ());
1156 }
1157
1158 OCTAVE_NORETURN static
1159 void
err_no_conversion(const std::string & on,const std::string & tn1,const std::string & tn2)1160 err_no_conversion (const std::string& on, const std::string& tn1,
1161 const std::string& tn2)
1162 {
1163 error ("operator %s: no conversion for assignment of '%s' to indexed '%s'",
1164 on.c_str (), tn2.c_str (), tn1.c_str ());
1165 }
1166
1167 octave_value
numeric_assign(const std::string & type,const std::list<octave_value_list> & idx,const octave_value & rhs)1168 octave_base_value::numeric_assign (const std::string& type,
1169 const std::list<octave_value_list>& idx,
1170 const octave_value& rhs)
1171 {
1172 octave_value retval;
1173
1174 if (idx.front ().empty ())
1175 error ("missing index in indexed assignment");
1176
1177 int t_lhs = type_id ();
1178 int t_rhs = rhs.type_id ();
1179
1180 octave::type_info& ti
1181 = octave::__get_type_info__ ("octave_base_value::numeric_assign");
1182
1183 octave::type_info::assign_op_fcn f
1184 = ti.lookup_assign_op (octave_value::op_asn_eq, t_lhs, t_rhs);
1185
1186 bool done = false;
1187
1188 if (f)
1189 {
1190 f (*this, idx.front (), rhs.get_rep ());
1191
1192 done = true;
1193 }
1194
1195 if (done)
1196 {
1197 count++;
1198 retval = octave_value (this);
1199 }
1200 else
1201 {
1202 int t_result = ti.lookup_pref_assign_conv (t_lhs, t_rhs);
1203
1204 if (t_result >= 0)
1205 {
1206 octave_base_value::type_conv_fcn cf
1207 = ti.lookup_widening_op (t_lhs, t_result);
1208
1209 if (! cf)
1210 err_indexed_assignment (type_name (), rhs.type_name ());
1211
1212 octave_base_value *tmp = cf (*this);
1213
1214 if (! tmp)
1215 err_assign_conversion_failed (type_name (), rhs.type_name ());
1216
1217 octave_value val (tmp);
1218
1219 retval = val.subsasgn (type, idx, rhs);
1220
1221 done = true;
1222 }
1223
1224 if (! done)
1225 {
1226 octave_value tmp_rhs;
1227
1228 octave_base_value::type_conv_info cf_rhs
1229 = rhs.numeric_conversion_function ();
1230
1231 octave_base_value::type_conv_info cf_this
1232 = numeric_conversion_function ();
1233
1234 // Try biased (one-sided) conversions first.
1235 if (cf_rhs.type_id () >= 0
1236 && (ti.lookup_assign_op (octave_value::op_asn_eq,
1237 t_lhs, cf_rhs.type_id ())
1238 || ti.lookup_pref_assign_conv (t_lhs,
1239 cf_rhs.type_id ()) >= 0))
1240 cf_this = nullptr;
1241 else if (cf_this.type_id () >= 0
1242 && (ti.lookup_assign_op (octave_value::op_asn_eq,
1243 cf_this.type_id (), t_rhs)
1244 || ti.lookup_pref_assign_conv (cf_this.type_id (),
1245 t_rhs) >= 0))
1246 cf_rhs = nullptr;
1247
1248 if (cf_rhs)
1249 {
1250 octave_base_value *tmp = cf_rhs (rhs.get_rep ());
1251
1252 if (! tmp)
1253 err_assign_conversion_failed (type_name (), rhs.type_name ());
1254
1255 tmp_rhs = octave_value (tmp);
1256 }
1257 else
1258 tmp_rhs = rhs;
1259
1260 count++;
1261 octave_value tmp_lhs = octave_value (this);
1262
1263 if (cf_this)
1264 {
1265 octave_base_value *tmp = cf_this (*this);
1266
1267 if (! tmp)
1268 err_assign_conversion_failed (type_name (), rhs.type_name ());
1269
1270 tmp_lhs = octave_value (tmp);
1271 }
1272
1273 if (! cf_this && ! cf_rhs)
1274 err_no_conversion (octave_value::assign_op_as_string
1275 (octave_value::op_asn_eq),
1276 type_name (), rhs.type_name ());
1277
1278 retval = tmp_lhs.subsasgn (type, idx, tmp_rhs);
1279
1280 done = true;
1281 }
1282 }
1283
1284 // The assignment may have converted to a type that is wider than necessary.
1285
1286 retval.maybe_mutate ();
1287
1288 return retval;
1289 }
1290
1291 // Current indentation.
1292 int octave_base_value::curr_print_indent_level = 0;
1293
1294 // TRUE means we are at the beginning of a line.
1295 bool octave_base_value::beginning_of_line = true;
1296
1297 // Each print() function should call this before printing anything.
1298 //
1299 // This doesn't need to be fast, but isn't there a better way?
1300
1301 void
indent(std::ostream & os) const1302 octave_base_value::indent (std::ostream& os) const
1303 {
1304 assert (curr_print_indent_level >= 0);
1305
1306 if (beginning_of_line)
1307 {
1308 // FIXME: do we need this?
1309 // os << prefix;
1310
1311 for (int i = 0; i < curr_print_indent_level; i++)
1312 os << ' ';
1313
1314 beginning_of_line = false;
1315 }
1316 }
1317
1318 // All print() functions should use this to print new lines.
1319
1320 void
newline(std::ostream & os) const1321 octave_base_value::newline (std::ostream& os) const
1322 {
1323 os << "\n";
1324
1325 beginning_of_line = true;
1326 }
1327
1328 // For resetting print state.
1329
1330 void
reset(void) const1331 octave_base_value::reset (void) const
1332 {
1333 beginning_of_line = true;
1334 curr_print_indent_level = 0;
1335 }
1336
1337 octave_value
fast_elem_extract(octave_idx_type) const1338 octave_base_value::fast_elem_extract (octave_idx_type) const
1339 {
1340 return octave_value ();
1341 }
1342
1343 bool
fast_elem_insert(octave_idx_type,const octave_value &)1344 octave_base_value::fast_elem_insert (octave_idx_type, const octave_value&)
1345 {
1346 return false;
1347 }
1348
1349 bool
fast_elem_insert_self(void *,builtin_type_t) const1350 octave_base_value::fast_elem_insert_self (void *, builtin_type_t) const
1351 {
1352 return false;
1353 }
1354
1355 static octave_base_value *
oct_conv_matrix_conv(const octave_base_value &)1356 oct_conv_matrix_conv (const octave_base_value&)
1357 {
1358 return new octave_matrix ();
1359 }
1360
1361 static octave_base_value *
oct_conv_complex_matrix_conv(const octave_base_value &)1362 oct_conv_complex_matrix_conv (const octave_base_value&)
1363 {
1364 return new octave_complex_matrix ();
1365 }
1366
1367 static octave_base_value *
oct_conv_string_conv(const octave_base_value &)1368 oct_conv_string_conv (const octave_base_value&)
1369 {
1370 return new octave_char_matrix_str ();
1371 }
1372
1373 static octave_base_value *
oct_conv_cell_conv(const octave_base_value &)1374 oct_conv_cell_conv (const octave_base_value&)
1375 {
1376 return new octave_cell ();
1377 }
1378
1379 static inline octave_value_list
sanitize(const octave_value_list & ovl)1380 sanitize (const octave_value_list& ovl)
1381 {
1382 octave_value_list retval = ovl;
1383
1384 for (octave_idx_type i = 0; i < ovl.length (); i++)
1385 {
1386 if (retval(i).is_magic_colon ())
1387 retval(i) = ":";
1388 }
1389
1390 return retval;
1391 }
1392
1393 octave_value
make_idx_args(const std::string & type,const std::list<octave_value_list> & idx,const std::string & who)1394 make_idx_args (const std::string& type,
1395 const std::list<octave_value_list>& idx,
1396 const std::string& who)
1397 {
1398 std::size_t len = type.length ();
1399
1400 if (len != idx.size ())
1401 error ("invalid index for %s", who.c_str ());
1402
1403 Cell type_field (1, len);
1404 Cell subs_field (1, len);
1405
1406 auto p = idx.begin ();
1407
1408 for (std::size_t i = 0; i < len; i++)
1409 {
1410 char t = type[i];
1411
1412 switch (t)
1413 {
1414 case '(':
1415 type_field(i) = "()";
1416 subs_field(i) = Cell (sanitize (*p++));
1417 break;
1418
1419 case '{':
1420 type_field(i) = "{}";
1421 subs_field(i) = Cell (sanitize (*p++));
1422 break;
1423
1424 case '.':
1425 {
1426 type_field(i) = ".";
1427
1428 octave_value_list vlist = *p++;
1429
1430 if (vlist.length () != 1)
1431 error ("only single argument permitted for '.' index");
1432
1433 octave_value val = vlist(0);
1434
1435 if (! val.is_string ())
1436 error ("string argument required for '.' index");
1437
1438 subs_field(i) = val;
1439 }
1440 break;
1441
1442 default:
1443 panic_impossible ();
1444 break;
1445 }
1446 }
1447
1448 octave_map m;
1449
1450 m.assign ("type", type_field);
1451 m.assign ("subs", subs_field);
1452
1453 return m;
1454 }
1455
1456 bool
called_from_builtin(void)1457 called_from_builtin (void)
1458 {
1459 octave::tree_evaluator& tw
1460 = octave::__get_evaluator__ ("called_from_builtin");
1461
1462 octave_function *fcn = tw.caller_function ();
1463
1464 // FIXME: we probably need a better check here, or some other
1465 // mechanism to avoid overloaded functions when builtin is used.
1466 // For example, what if someone overloads the builtin function?
1467 // Also, are there other places where using builtin is not properly
1468 // avoiding dispatch?
1469
1470 return (fcn && fcn->name () == "builtin");
1471 }
1472
1473 void
install_base_type_conversions(octave::type_info & ti)1474 install_base_type_conversions (octave::type_info& ti)
1475 {
1476 INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_scalar, octave_matrix);
1477 INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_matrix, octave_matrix);
1478 INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_complex,
1479 octave_complex_matrix);
1480 INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_complex_matrix,
1481 octave_complex_matrix);
1482 INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_range, octave_matrix);
1483 INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_char_matrix_str,
1484 octave_char_matrix_str);
1485 INSTALL_ASSIGNCONV_TI (ti, octave_base_value, octave_cell, octave_cell);
1486
1487 INSTALL_WIDENOP_TI (ti, octave_base_value, octave_matrix, matrix_conv);
1488 INSTALL_WIDENOP_TI (ti, octave_base_value, octave_complex_matrix,
1489 complex_matrix_conv);
1490 INSTALL_WIDENOP_TI (ti, octave_base_value, octave_char_matrix_str, string_conv);
1491 INSTALL_WIDENOP_TI (ti, octave_base_value, octave_cell, cell_conv);
1492 }
1493
1494 DEFUN (sparse_auto_mutate, args, nargout,
1495 doc: /* -*- texinfo -*-
1496 @deftypefn {} {@var{val} =} sparse_auto_mutate ()
1497 @deftypefnx {} {@var{old_val} =} sparse_auto_mutate (@var{new_val})
1498 @deftypefnx {} {} sparse_auto_mutate (@var{new_val}, "local")
1499 Query or set the internal variable that controls whether Octave will
1500 automatically mutate sparse matrices to full matrices to save memory.
1501
1502 For example:
1503
1504 @example
1505 @group
1506 s = speye (3);
1507 sparse_auto_mutate (false);
1508 s(:, 1) = 1;
1509 typeinfo (s)
1510 @result{} sparse matrix
1511 sparse_auto_mutate (true);
1512 s(1, :) = 1;
1513 typeinfo (s)
1514 @result{} matrix
1515 @end group
1516 @end example
1517
1518 When called from inside a function with the @qcode{"local"} option, the
1519 variable is changed locally for the function and any subroutines it calls.
1520 The original variable value is restored when exiting the function.
1521 @end deftypefn */)
1522 {
1523 return SET_INTERNAL_VARIABLE (sparse_auto_mutate);
1524 }
1525
1526 /*
1527 %!test
1528 %! s = speye (3);
1529 %! sparse_auto_mutate (false);
1530 %! s(:, 1) = 1;
1531 %! assert (typeinfo (s), "sparse matrix");
1532 %! sparse_auto_mutate (true);
1533 %! s(1, :) = 1;
1534 %! assert (typeinfo (s), "matrix");
1535 %! sparse_auto_mutate (false);
1536 */
1537