GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2018 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
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License 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 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include "data-conv.h"
29 #include "quit.h"
30 #include "str-vec.h"
31 
32 #include "ovl.h"
33 #include "oct-stream.h"
34 #include "ov.h"
35 #include "ov-base.h"
36 #include "ov-bool.h"
37 #include "ov-bool-mat.h"
38 #include "ov-cell.h"
39 #include "ov-scalar.h"
40 #include "ov-float.h"
41 #include "ov-re-mat.h"
42 #include "ov-flt-re-mat.h"
43 #include "ov-re-diag.h"
44 #include "ov-flt-re-diag.h"
45 #include "ov-perm.h"
46 #include "ov-bool-sparse.h"
47 #include "ov-cx-sparse.h"
48 #include "ov-re-sparse.h"
49 #include "ov-int8.h"
50 #include "ov-int16.h"
51 #include "ov-int32.h"
52 #include "ov-int64.h"
53 #include "ov-uint8.h"
54 #include "ov-uint16.h"
55 #include "ov-uint32.h"
56 #include "ov-uint64.h"
57 #include "ov-complex.h"
58 #include "ov-flt-complex.h"
59 #include "ov-cx-mat.h"
60 #include "ov-flt-cx-mat.h"
61 #include "ov-cx-diag.h"
62 #include "ov-flt-cx-diag.h"
63 #include "ov-ch-mat.h"
64 #include "ov-str-mat.h"
65 #include "ov-range.h"
66 #include "ov-struct.h"
67 #include "ov-class.h"
68 #include "ov-classdef.h"
69 #include "ov-oncleanup.h"
70 #include "ov-cs-list.h"
71 #include "ov-colon.h"
72 #include "ov-builtin.h"
73 #include "ov-dld-fcn.h"
74 #include "ov-usr-fcn.h"
75 #include "ov-fcn-handle.h"
76 #include "ov-fcn-inline.h"
77 #include "ov-typeinfo.h"
78 #include "ov-null-mat.h"
79 #include "ov-lazy-idx.h"
80 #include "ov-java.h"
81 
82 #include "defun.h"
83 #include "error.h"
84 #include "errwarn.h"
85 #include "interpreter-private.h"
86 #include "pager.h"
87 #include "parse.h"
88 #include "pr-flt-fmt.h"
89 #include "pr-output.h"
90 #include "symtab.h"
91 #include "utils.h"
92 #include "variables.h"
93 
94 // We are likely to have a lot of octave_value objects to allocate, so
95 // make the grow_size large.
96 
97 // If TRUE, don't create special diagonal matrix objects.
98 
99 static bool Vdisable_diagonal_matrix = false;
100 
101 // If TRUE, don't create special permutation matrix objects.
102 
103 static bool Vdisable_permutation_matrix = false;
104 
105 // If TRUE, don't create special range objects.
106 
107 static bool Vdisable_range = false;
108 
109 // FIXME
110 
111 // Octave's value type.
112 
115 {
116  static octave_base_value nr;
117  return &nr;
118 }
119 
122 {
123  switch (op)
124  {
125  case op_not:
126  return "!";
127 
128  case op_uplus:
129  return "+";
130 
131  case op_uminus:
132  return "-";
133 
134  case op_transpose:
135  return ".'";
136 
137  case op_hermitian:
138  return "'";
139 
140  case op_incr:
141  return "++";
142 
143  case op_decr:
144  return "--";
145 
146  default:
147  return "<unknown>";
148  }
149 }
150 
153 {
154  switch (op)
155  {
156  case op_not:
157  return "not";
158 
159  case op_uplus:
160  return "uplus";
161 
162  case op_uminus:
163  return "uminus";
164 
165  case op_transpose:
166  return "transpose";
167 
168  case op_hermitian:
169  return "ctranspose";
170 
171  default:
172  return "<unknown>";
173  }
174 }
175 
178 {
179  switch (op)
180  {
181  case op_add:
182  return "+";
183 
184  case op_sub:
185  return "-";
186 
187  case op_mul:
188  return "*";
189 
190  case op_div:
191  return "/";
192 
193  case op_pow:
194  return "^";
195 
196  case op_ldiv:
197  return R"(\)";
198 
199  case op_lt:
200  return "<";
201 
202  case op_le:
203  return "<=";
204 
205  case op_eq:
206  return "==";
207 
208  case op_ge:
209  return ">=";
210 
211  case op_gt:
212  return ">";
213 
214  case op_ne:
215  return "!=";
216 
217  case op_el_mul:
218  return ".*";
219 
220  case op_el_div:
221  return "./";
222 
223  case op_el_pow:
224  return ".^";
225 
226  case op_el_ldiv:
227  return R"(.\)";
228 
229  case op_el_and:
230  return "&";
231 
232  case op_el_or:
233  return "|";
234 
235  case op_struct_ref:
236  return ".";
237 
238  default:
239  return "<unknown>";
240  }
241 }
242 
245 {
246  switch (op)
247  {
248  case op_add:
249  return "plus";
250 
251  case op_sub:
252  return "minus";
253 
254  case op_mul:
255  return "mtimes";
256 
257  case op_div:
258  return "mrdivide";
259 
260  case op_pow:
261  return "mpower";
262 
263  case op_ldiv:
264  return "mldivide";
265 
266  case op_lt:
267  return "lt";
268 
269  case op_le:
270  return "le";
271 
272  case op_eq:
273  return "eq";
274 
275  case op_ge:
276  return "ge";
277 
278  case op_gt:
279  return "gt";
280 
281  case op_ne:
282  return "ne";
283 
284  case op_el_mul:
285  return "times";
286 
287  case op_el_div:
288  return "rdivide";
289 
290  case op_el_pow:
291  return "power";
292 
293  case op_el_ldiv:
294  return "ldivide";
295 
296  case op_el_and:
297  return "and";
298 
299  case op_el_or:
300  return "or";
301 
302  default:
303  return "<unknown>";
304  }
305 }
306 
309 {
310  switch (op)
311  {
312  case op_trans_mul:
313  return "transtimes";
314 
315  case op_mul_trans:
316  return "timestrans";
317 
318  case op_herm_mul:
319  return "hermtimes";
320 
321  case op_mul_herm:
322  return "timesherm";
323 
324  case op_trans_ldiv:
325  return "transldiv";
326 
327  case op_herm_ldiv:
328  return "hermldiv";
329 
330  case op_el_and_not:
331  return "andnot";
332 
333  case op_el_or_not:
334  return "ornot";
335 
336  case op_el_not_and:
337  return "notand";
338 
339  case op_el_not_or:
340  return "notor";
341 
342  default:
343  return "<unknown>";
344  }
345 }
346 
349 {
350  switch (op)
351  {
352  case op_asn_eq:
353  return "=";
354 
355  case op_add_eq:
356  return "+=";
357 
358  case op_sub_eq:
359  return "-=";
360 
361  case op_mul_eq:
362  return "*=";
363 
364  case op_div_eq:
365  return "/=";
366 
367  case op_ldiv_eq:
368  return R"(\=)";
369 
370  case op_pow_eq:
371  return "^=";
372 
373  case op_el_mul_eq:
374  return ".*=";
375 
376  case op_el_div_eq:
377  return "./=";
378 
379  case op_el_ldiv_eq:
380  return R"(.\=)";
381 
382  case op_el_pow_eq:
383  return ".^=";
384 
385  case op_el_and_eq:
386  return "&=";
387 
388  case op_el_or_eq:
389  return "|=";
390 
391  default:
392  return "<unknown>";
393  }
394 }
395 
398 {
399  switch (op)
400  {
401  case op_add_eq:
402  return op_add;
403 
404  case op_sub_eq:
405  return op_sub;
406 
407  case op_mul_eq:
408  return op_mul;
409 
410  case op_div_eq:
411  return op_div;
412 
413  case op_ldiv_eq:
414  return op_ldiv;
415 
416  case op_pow_eq:
417  return op_pow;
418 
419  case op_el_mul_eq:
420  return op_el_mul;
421 
422  case op_el_div_eq:
423  return op_el_div;
424 
425  case op_el_ldiv_eq:
426  return op_el_ldiv;
427 
428  case op_el_pow_eq:
429  return op_el_pow;
430 
431  case op_el_and_eq:
432  return op_el_and;
433 
434  case op_el_or_eq:
435  return op_el_or;
436 
437  default:
438  return unknown_binary_op;
439  }
440 }
441 
444 {
445  switch (op)
446  {
447  case op_add:
448  return op_add_eq;
449 
450  case op_sub:
451  return op_sub_eq;
452 
453  case op_mul:
454  return op_mul_eq;
455 
456  case op_div:
457  return op_div_eq;
458 
459  case op_el_mul:
460  return op_el_mul_eq;
461 
462  case op_el_div:
463  return op_el_div_eq;
464 
465  case op_el_and:
466  return op_el_and_eq;
467 
468  case op_el_or:
469  return op_el_or_eq;
470 
471  default:
472  return unknown_assign_op;
473  }
474 }
475 
477  : rep (new octave_scalar (i))
478 { }
479 
480 octave_value::octave_value (unsigned short int i)
481  : rep (new octave_scalar (i))
482 { }
483 
485  : rep (new octave_scalar (i))
486 { }
487 
489  : rep (new octave_scalar (i))
490 { }
491 
493  : rep (new octave_scalar (i))
494 { }
495 
496 octave_value::octave_value (unsigned long int i)
497  : rep (new octave_scalar (i))
498 { }
499 
500 #if defined (OCTAVE_HAVE_LONG_LONG_INT)
501 octave_value::octave_value (long long int i)
502  : rep (new octave_scalar (i))
503 { }
504 #endif
505 
506 #if defined (OCTAVE_HAVE_UNSIGNED_LONG_LONG_INT)
507 octave_value::octave_value (unsigned long long int i)
508  : rep (new octave_scalar (i))
509 { }
510 #endif
511 
513  : rep (new octave_scalar (t.double_value ()))
514 { }
515 
517  : rep (new octave_scalar (d))
518 { }
519 
521  : rep (new octave_float_scalar (d))
522 { }
523 
524 octave_value::octave_value (const Cell& c, bool is_csl)
525  : rep (is_csl
526  ? dynamic_cast<octave_base_value *> (new octave_cs_list (c))
527  : dynamic_cast<octave_base_value *> (new octave_cell (c)))
528 { }
529 
531  : rep (is_csl
532  ? dynamic_cast<octave_base_value *> (new octave_cs_list (Cell (a)))
533  : dynamic_cast<octave_base_value *> (new octave_cell (Cell (a))))
534 { }
535 
537  : rep (new octave_matrix (m, t))
538 {
539  maybe_mutate ();
540 }
541 
543  : rep (new octave_float_matrix (m, t))
544 {
545  maybe_mutate ();
546 }
547 
549  : rep (new octave_matrix (a))
550 {
551  maybe_mutate ();
552 }
553 
555  : rep (new octave_float_matrix (a))
556 {
557  maybe_mutate ();
558 }
559 
561  : rep (new octave_matrix (a))
562 {
563  maybe_mutate ();
564 }
565 
567  : rep (new octave_float_matrix (a))
568 {
569  maybe_mutate ();
570 }
571 
574  ? dynamic_cast<octave_base_value *> (new octave_matrix (Matrix (d)))
575  : dynamic_cast<octave_base_value *> (new octave_diag_matrix (d)))
576 {
577  maybe_mutate ();
578 }
579 
582  ? dynamic_cast<octave_base_value *> (new octave_float_matrix (FloatMatrix (d)))
583  : dynamic_cast<octave_base_value *> (new octave_float_diag_matrix (d)))
584 {
585  maybe_mutate ();
586 }
587 
590  ? dynamic_cast<octave_base_value *> (new octave_complex_matrix (ComplexMatrix (d)))
591  : dynamic_cast<octave_base_value *> (new octave_complex_diag_matrix (d)))
592 {
593  maybe_mutate ();
594 }
595 
599  : dynamic_cast<octave_base_value *> (new octave_float_complex_diag_matrix (d)))
600 {
601  maybe_mutate ();
602 }
603 
606  ? dynamic_cast<octave_base_value *> (new octave_matrix (Matrix (d)))
607  : dynamic_cast<octave_base_value *> (new octave_diag_matrix (d)))
608 {
609  maybe_mutate ();
610 }
611 
614  ? dynamic_cast<octave_base_value *> (new octave_float_matrix (FloatMatrix (d)))
615  : dynamic_cast<octave_base_value *> (new octave_float_diag_matrix (d)))
616 {
617  maybe_mutate ();
618 }
619 
621  : rep (new octave_matrix (v))
622 {
623  maybe_mutate ();
624 }
625 
627  : rep (new octave_float_matrix (v))
628 {
629  maybe_mutate ();
630 }
631 
633  : rep (new octave_matrix (v))
634 {
635  maybe_mutate ();
636 }
637 
639  : rep (new octave_float_matrix (v))
640 {
641  maybe_mutate ();
642 }
643 
645  : rep (new octave_complex (C))
646 {
647  maybe_mutate ();
648 }
649 
651  : rep (new octave_float_complex (C))
652 {
653  maybe_mutate ();
654 }
655 
657  : rep (new octave_complex_matrix (m, t))
658 {
659  maybe_mutate ();
660 }
661 
663  : rep (new octave_float_complex_matrix (m, t))
664 {
665  maybe_mutate ();
666 }
667 
669  : rep (new octave_complex_matrix (a))
670 {
671  maybe_mutate ();
672 }
673 
675  : rep (new octave_float_complex_matrix (a))
676 {
677  maybe_mutate ();
678 }
679 
681  : rep (new octave_complex_matrix (a))
682 {
683  maybe_mutate ();
684 }
685 
687  : rep (new octave_float_complex_matrix (a))
688 {
689  maybe_mutate ();
690 }
691 
694  ? dynamic_cast<octave_base_value *> (new octave_complex_matrix (ComplexMatrix (d)))
695  : dynamic_cast<octave_base_value *> (new octave_complex_diag_matrix (d)))
696 {
697  maybe_mutate ();
698 }
699 
703  : dynamic_cast<octave_base_value *> (new octave_float_complex_diag_matrix (d)))
704 {
705  maybe_mutate ();
706 }
707 
709  : rep (new octave_complex_matrix (v))
710 {
711  maybe_mutate ();
712 }
713 
715  : rep (new octave_float_complex_matrix (v))
716 {
717  maybe_mutate ();
718 }
719 
721  : rep (new octave_complex_matrix (v))
722 {
723  maybe_mutate ();
724 }
725 
727  : rep (new octave_float_complex_matrix (v))
728 {
729  maybe_mutate ();
730 }
731 
734  ? dynamic_cast<octave_base_value *> (new octave_matrix (Matrix (p)))
735  : dynamic_cast<octave_base_value *> (new octave_perm_matrix (p)))
736 {
737  maybe_mutate ();
738 }
739 
741  : rep (new octave_bool (b))
742 { }
743 
745  : rep (new octave_bool_matrix (bm, t))
746 {
747  maybe_mutate ();
748 }
749 
751  : rep (new octave_bool_matrix (bnda))
752 {
753  maybe_mutate ();
754 }
755 
757  : rep (new octave_bool_matrix (bnda))
758 {
759  maybe_mutate ();
760 }
761 
763  : rep (type == '"'
766 {
767  maybe_mutate ();
768 }
769 
770 octave_value::octave_value (const char *s, char type)
771  : rep (type == '"'
774 {
775  maybe_mutate ();
776 }
777 
779  : rep (type == '"'
782 {
783  maybe_mutate ();
784 }
785 
787  : rep (type == '"'
790 {
791  maybe_mutate ();
792 }
793 
795  : rep (type == '"'
796  ? new octave_char_matrix_dq_str (chm)
797  : new octave_char_matrix_sq_str (chm))
798 {
799  maybe_mutate ();
800 }
801 
803  : rep (type == '"'
804  ? new octave_char_matrix_dq_str (chm)
805  : new octave_char_matrix_sq_str (chm))
806 {
807  maybe_mutate ();
808 }
809 
811  : rep (type == '"'
812  ? new octave_char_matrix_dq_str (chm)
813  : new octave_char_matrix_sq_str (chm))
814 {
815  maybe_mutate ();
816 }
817 
819  : rep (new octave_sparse_matrix (m, t))
820 {
821  maybe_mutate ();
822 }
823 
825  : rep (new octave_sparse_matrix (m, t))
826 {
827  maybe_mutate ();
828 }
829 
831  : rep (new octave_sparse_complex_matrix (m, t))
832 {
833  maybe_mutate ();
834 }
835 
837  : rep (new octave_sparse_complex_matrix (m, t))
838 {
839  maybe_mutate ();
840 }
841 
843  : rep (new octave_sparse_bool_matrix (bm, t))
844 {
845  maybe_mutate ();
846 }
847 
849  : rep (new octave_sparse_bool_matrix (bm, t))
850 {
851  maybe_mutate ();
852 }
853 
855  : rep (new octave_int8_scalar (i))
856 {
857  maybe_mutate ();
858 }
859 
861  : rep (new octave_uint8_scalar (i))
862 {
863  maybe_mutate ();
864 }
865 
867  : rep (new octave_int16_scalar (i))
868 {
869  maybe_mutate ();
870 }
871 
873  : rep (new octave_uint16_scalar (i))
874 {
875  maybe_mutate ();
876 }
877 
879  : rep (new octave_int32_scalar (i))
880 {
881  maybe_mutate ();
882 }
883 
885  : rep (new octave_uint32_scalar (i))
886 {
887  maybe_mutate ();
888 }
889 
891  : rep (new octave_int64_scalar (i))
892 {
893  maybe_mutate ();
894 }
895 
897  : rep (new octave_uint64_scalar (i))
898 {
899  maybe_mutate ();
900 }
901 
903  : rep (new octave_int8_matrix (inda))
904 {
905  maybe_mutate ();
906 }
907 
909  : rep (new octave_int8_matrix (inda))
910 {
911  maybe_mutate ();
912 }
913 
915  : rep (new octave_uint8_matrix (inda))
916 {
917  maybe_mutate ();
918 }
919 
921  : rep (new octave_uint8_matrix (inda))
922 {
923  maybe_mutate ();
924 }
925 
927  : rep (new octave_int16_matrix (inda))
928 {
929  maybe_mutate ();
930 }
931 
933  : rep (new octave_int16_matrix (inda))
934 {
935  maybe_mutate ();
936 }
937 
939  : rep (new octave_uint16_matrix (inda))
940 {
941  maybe_mutate ();
942 }
943 
945  : rep (new octave_uint16_matrix (inda))
946 {
947  maybe_mutate ();
948 }
949 
951  : rep (new octave_int32_matrix (inda))
952 {
953  maybe_mutate ();
954 }
955 
957  : rep (new octave_int32_matrix (inda))
958 {
959  maybe_mutate ();
960 }
961 
963  : rep (new octave_uint32_matrix (inda))
964 {
965  maybe_mutate ();
966 }
967 
969  : rep (new octave_uint32_matrix (inda))
970 {
971  maybe_mutate ();
972 }
973 
975  : rep (new octave_int64_matrix (inda))
976 {
977  maybe_mutate ();
978 }
979 
981  : rep (new octave_int64_matrix (inda))
982 {
983  maybe_mutate ();
984 }
985 
987  : rep (new octave_uint64_matrix (inda))
988 {
989  maybe_mutate ();
990 }
991 
993  : rep (new octave_uint64_matrix (inda))
994 {
995  maybe_mutate ();
996 }
997 
998 octave_value::octave_value (const Array<octave_idx_type>& inda, bool zero_based,
999  bool cache_index)
1000  : rep (new octave_matrix (inda, zero_based, cache_index))
1001 {
1002  maybe_mutate ();
1003 }
1004 
1005 octave_value::octave_value (const idx_vector& idx, bool lazy)
1006  : rep ()
1007 {
1008  double scalar;
1009  Range range;
1010  NDArray array;
1011  boolNDArray mask;
1012  idx_vector::idx_class_type idx_class;
1013 
1014  if (lazy)
1015  {
1016  // Only make lazy indices out of ranges and index vectors.
1017  switch (idx.idx_class ())
1018  {
1021  rep = new octave_lazy_index (idx);
1022  maybe_mutate ();
1023  return;
1024 
1025  default:
1026  break;
1027  }
1028  }
1029 
1030  idx.unconvert (idx_class, scalar, range, array, mask);
1031 
1032  switch (idx_class)
1033  {
1035  rep = new octave_magic_colon ();
1036  break;
1037 
1039  rep = new octave_range (range, idx);
1040  break;
1041 
1043  rep = new octave_scalar (scalar);
1044  break;
1045 
1047  rep = new octave_matrix (array, idx);
1048  break;
1049 
1051  rep = new octave_bool_matrix (mask, idx);
1052  break;
1053 
1054  default:
1055  panic_impossible ();
1056  break;
1057  }
1058 
1059  // FIXME: needed?
1060  maybe_mutate ();
1061 }
1062 
1064  : rep (new octave_cell (cellstr))
1065 {
1066  maybe_mutate ();
1067 }
1068 
1069 octave_value::octave_value (double base, double limit, double inc)
1070  : rep (new octave_range (base, limit, inc))
1071 {
1072  maybe_mutate ();
1073 }
1074 
1075 octave_value::octave_value (const Range& r, bool force_range)
1076  : rep (force_range || ! Vdisable_range
1077  ? dynamic_cast<octave_base_value *> (new octave_range (r))
1078  : dynamic_cast<octave_base_value *> (new octave_matrix (r.matrix_value ())))
1079 {
1080  maybe_mutate ();
1081 }
1082 
1084  : rep (new octave_struct (m))
1085 {
1086  maybe_mutate ();
1087 }
1088 
1090  : rep (new octave_scalar_struct (m))
1091 { }
1092 
1093 octave_value::octave_value (const std::map<std::string, octave_value>& m)
1094  : rep (new octave_scalar_struct (m))
1095 { }
1096 
1098  const std::list<std::string>& plist)
1099  : rep (new octave_class (m, id, plist))
1100 {
1101  maybe_mutate ();
1102 }
1103 
1105  const std::list<std::string>& plist)
1106  : rep (new octave_class (m, id, plist))
1107 { }
1108 
1110  : rep (new octave_cs_list (l))
1111 { }
1112 
1114  : rep (new octave_cs_list (l))
1115 { }
1116 
1118  : rep (new octave_magic_colon ())
1119 { }
1120 
1121 octave_value::octave_value (octave_base_value *new_rep, bool borrow)
1122  : rep (new_rep)
1123 {
1124  if (borrow)
1125  rep->count++;
1126 }
1127 
1129 octave_value::clone (void) const
1130 {
1131  return rep->clone ();
1132 }
1133 
1134 void
1136 {
1138 
1139  if (tmp && tmp != rep)
1140  {
1141  if (--rep->count == 0)
1142  delete rep;
1143 
1144  rep = tmp;
1145  }
1146 }
1147 
1148 DEFUN (double, args, ,
1149  doc: /* -*- texinfo -*-
1150 @deftypefn {} {} double (@var{x})
1151 Convert @var{x} to double precision type.
1152 @seealso{single}
1153 @end deftypefn */)
1154 {
1155  if (args.length () != 1)
1156  print_usage ();
1157 
1158  return ovl (args(0).as_double ());
1159 }
1160 
1161 /*
1162 %!assert (class (double (single (1))), "double")
1163 %!assert (class (double (single (1 + i))), "double")
1164 %!assert (class (double (int8 (1))), "double")
1165 %!assert (class (double (uint8 (1))), "double")
1166 %!assert (class (double (int16 (1))), "double")
1167 %!assert (class (double (uint16 (1))), "double")
1168 %!assert (class (double (int32 (1))), "double")
1169 %!assert (class (double (uint32 (1))), "double")
1170 %!assert (class (double (int64 (1))), "double")
1171 %!assert (class (double (uint64 (1))), "double")
1172 %!assert (class (double (true)), "double")
1173 %!assert (class (double ("A")), "double")
1174 %!test
1175 %! x = sparse (logical ([1 0; 0 1]));
1176 %! y = double (x);
1177 %! assert (class (x), "logical");
1178 %! assert (class (y), "double");
1179 %! assert (issparse (y));
1180 %!test
1181 %! x = diag (single ([1 3 2]));
1182 %! y = double (x);
1183 %! assert (class (x), "single");
1184 %! assert (class (y), "double");
1185 %!test
1186 %! x = diag (single ([i 3 2]));
1187 %! y = double (x);
1188 %! assert (class (x), "single");
1189 %! assert (class (y), "double");
1190 */
1191 
1192 DEFUN (single, args, ,
1193  doc: /* -*- texinfo -*-
1194 @deftypefn {} {} single (@var{x})
1195 Convert @var{x} to single precision type.
1196 @seealso{double}
1197 @end deftypefn */)
1198 {
1199  if (args.length () != 1)
1200  print_usage ();
1201 
1202  return args(0).as_single ();
1203 
1204  return ovl ();
1205 }
1206 
1207 /*
1208 %!assert (class (single (1)), "single")
1209 %!assert (class (single (1 + i)), "single")
1210 %!assert (class (single (int8 (1))), "single")
1211 %!assert (class (single (uint8 (1))), "single")
1212 %!assert (class (single (int16 (1))), "single")
1213 %!assert (class (single (uint16 (1))), "single")
1214 %!assert (class (single (int32 (1))), "single")
1215 %!assert (class (single (uint32 (1))), "single")
1216 %!assert (class (single (int64 (1))), "single")
1217 %!assert (class (single (uint64 (1))), "single")
1218 %!assert (class (single (true)), "single")
1219 %!assert (class (single ("A")), "single")
1220 %!error (single (sparse (1)))
1221 %!test
1222 %! x = diag ([1 3 2]);
1223 %! y = single (x);
1224 %! assert (class (x), "double");
1225 %! assert (class (y), "single");
1226 %!test
1227 %! x = diag ([i 3 2]);
1228 %! y = single (x);
1229 %! assert (class (x), "double");
1230 %! assert (class (y), "single");
1231 */
1232 
1233 DEFUN (int8, args, ,
1234  doc: /* -*- texinfo -*-
1235 @deftypefn {} {} int8 (@var{x})
1236 Convert @var{x} to 8-bit integer type.
1237 @seealso{uint8, int16, uint16, int32, uint32, int64, uint64}
1238 @end deftypefn */)
1239 {
1240  if (args.length () != 1)
1241  print_usage ();
1242 
1243  return args(0).as_int8 ();
1244 }
1245 
1246 /*
1247 %!assert (class (int8 (1)), "int8")
1248 %!assert (int8 (1.25), int8 (1))
1249 %!assert (int8 (1.5), int8 (2))
1250 %!assert (int8 (-1.5), int8 (-2))
1251 %!assert (int8 (2^9), int8 (2^8-1))
1252 %!assert (int8 (-2^9), int8 (-2^8))
1253 */
1254 
1255 DEFUN (int16, args, ,
1256  doc: /* -*- texinfo -*-
1257 @deftypefn {} {} int16 (@var{x})
1258 Convert @var{x} to 16-bit integer type.
1259 @seealso{int8, uint8, uint16, int32, uint32, int64, uint64}
1260 @end deftypefn */)
1261 {
1262  if (args.length () != 1)
1263  print_usage ();
1264 
1265  return args(0).as_int16 ();
1266 }
1267 
1268 /*
1269 %!assert (class (int16 (1)), "int16")
1270 %!assert (int16 (1.25), int16 (1))
1271 %!assert (int16 (1.5), int16 (2))
1272 %!assert (int16 (-1.5), int16 (-2))
1273 %!assert (int16 (2^17), int16 (2^16-1))
1274 %!assert (int16 (-2^17), int16 (-2^16))
1275 */
1276 
1277 DEFUN (int32, args, ,
1278  doc: /* -*- texinfo -*-
1279 @deftypefn {} {} int32 (@var{x})
1280 Convert @var{x} to 32-bit integer type.
1281 @seealso{int8, uint8, int16, uint16, uint32, int64, uint64}
1282 @end deftypefn */)
1283 {
1284  if (args.length () != 1)
1285  print_usage ();
1286 
1287  return args(0).as_int32 ();
1288 }
1289 
1290 /*
1291 %!assert (class (int32 (1)), "int32")
1292 %!assert (int32 (1.25), int32 (1))
1293 %!assert (int32 (1.5), int32 (2))
1294 %!assert (int32 (-1.5), int32 (-2))
1295 %!assert (int32 (2^33), int32 (2^32-1))
1296 %!assert (int32 (-2^33), int32 (-2^32))
1297 */
1298 
1299 DEFUN (int64, args, ,
1300  doc: /* -*- texinfo -*-
1301 @deftypefn {} {} int64 (@var{x})
1302 Convert @var{x} to 64-bit integer type.
1303 @seealso{int8, uint8, int16, uint16, int32, uint32, uint64}
1304 @end deftypefn */)
1305 {
1306  if (args.length () != 1)
1307  print_usage ();
1308 
1309  return args(0).as_int64 ();
1310 }
1311 
1312 /*
1313 %!assert (class (int64 (1)), "int64")
1314 %!assert (int64 (1.25), int64 (1))
1315 %!assert (int64 (1.5), int64 (2))
1316 %!assert (int64 (-1.5), int64 (-2))
1317 %!assert (int64 (2^65), int64 (2^64-1))
1318 %!assert (int64 (-2^65), int64 (-2^64))
1319 */
1320 
1321 DEFUN (uint8, args, ,
1322  doc: /* -*- texinfo -*-
1323 @deftypefn {} {} uint8 (@var{x})
1324 Convert @var{x} to unsigned 8-bit integer type.
1325 @seealso{int8, int16, uint16, int32, uint32, int64, uint64}
1326 @end deftypefn */)
1327 {
1328  if (args.length () != 1)
1329  print_usage ();
1330 
1331  return args(0).as_uint8 ();
1332 }
1333 
1334 /*
1335 %!assert (class (uint8 (1)), "uint8")
1336 %!assert (uint8 (1.25), uint8 (1))
1337 %!assert (uint8 (1.5), uint8 (2))
1338 %!assert (uint8 (-1.5), uint8 (0))
1339 %!assert (uint8 (2^9), uint8 (2^8-1))
1340 %!assert (uint8 (-2^9), uint8 (0))
1341 */
1342 
1343 DEFUN (uint16, args, ,
1344  doc: /* -*- texinfo -*-
1345 @deftypefn {} {} uint16 (@var{x})
1346 Convert @var{x} to unsigned 16-bit integer type.
1347 @seealso{int8, uint8, int16, int32, uint32, int64, uint64}
1348 @end deftypefn */)
1349 {
1350  if (args.length () != 1)
1351  print_usage ();
1352 
1353  return args(0).as_uint16 ();
1354 }
1355 
1356 /*
1357 %!assert (class (uint16 (1)), "uint16")
1358 %!assert (uint16 (1.25), uint16 (1))
1359 %!assert (uint16 (1.5), uint16 (2))
1360 %!assert (uint16 (-1.5), uint16 (0))
1361 %!assert (uint16 (2^17), uint16 (2^16-1))
1362 %!assert (uint16 (-2^17), uint16 (0))
1363 */
1364 
1365 DEFUN (uint32, args, ,
1366  doc: /* -*- texinfo -*-
1367 @deftypefn {} {} uint32 (@var{x})
1368 Convert @var{x} to unsigned 32-bit integer type.
1369 @seealso{int8, uint8, int16, uint16, int32, int64, uint64}
1370 @end deftypefn */)
1371 {
1372  if (args.length () != 1)
1373  print_usage ();
1374 
1375  return args(0).as_uint32 ();
1376 }
1377 
1378 /*
1379 %!assert (class (uint32 (1)), "uint32")
1380 %!assert (uint32 (1.25), uint32 (1))
1381 %!assert (uint32 (1.5), uint32 (2))
1382 %!assert (uint32 (-1.5), uint32 (0))
1383 %!assert (uint32 (2^33), uint32 (2^32-1))
1384 %!assert (uint32 (-2^33), uint32 (0))
1385 */
1386 
1387 DEFUN (uint64, args, ,
1388  doc: /* -*- texinfo -*-
1389 @deftypefn {} {} uint64 (@var{x})
1390 Convert @var{x} to unsigned 64-bit integer type.
1391 @seealso{int8, uint8, int16, uint16, int32, uint32, int64}
1392 @end deftypefn */)
1393 {
1394  if (args.length () != 1)
1395  print_usage ();
1396 
1397  return args(0).as_uint64 ();
1398 }
1399 
1400 /*
1401 %!assert (class (uint64 (1)), "uint64")
1402 %!assert (uint64 (1.25), uint64 (1))
1403 %!assert (uint64 (1.5), uint64 (2))
1404 %!assert (uint64 (-1.5), uint64 (0))
1405 %!assert (uint64 (2^65), uint64 (2^64-1))
1406 %!assert (uint64 (-2^65), uint64 (0))
1407 */
1408 
1411  const octave_value_list& idx)
1412 {
1413  std::list<octave_value_list> i;
1414 
1415  i.push_back (idx);
1416 
1417  return rep->subsref (type, i);
1418 }
1419 
1422  const std::list<octave_value_list>& idx, int nargout)
1423 {
1424  return rep->subsref (type, idx, nargout);
1425 }
1426 
1429  const std::list<octave_value_list>& idx,
1430  size_t skip)
1431 {
1432  if (idx.size () > skip)
1433  {
1434  std::list<octave_value_list> new_idx (idx);
1435  for (size_t i = 0; i < skip; i++)
1436  new_idx.erase (new_idx.begin ());
1437  return subsref (type.substr (skip), new_idx);
1438  }
1439  else
1440  return *this;
1441 }
1442 
1445  const std::list<octave_value_list>& idx,
1446  size_t skip)
1447 {
1448  if (idx.size () > skip)
1449  {
1450  std::list<octave_value_list> new_idx (idx);
1451  for (size_t i = 0; i < skip; i++)
1452  new_idx.erase (new_idx.begin ());
1453  return subsref (type.substr (skip), new_idx, nargout);
1454  }
1455  else
1456  return *this;
1457 }
1458 
1460 octave_value::next_subsref (bool auto_add, const std::string& type,
1461  const std::list<octave_value_list>& idx,
1462  size_t skip)
1463 {
1464  if (idx.size () > skip)
1465  {
1466  std::list<octave_value_list> new_idx (idx);
1467  for (size_t i = 0; i < skip; i++)
1468  new_idx.erase (new_idx.begin ());
1469  return subsref (type.substr (skip), new_idx, auto_add);
1470  }
1471  else
1472  return *this;
1473 }
1474 
1477  const std::list<octave_value_list>& idx,
1478  const octave_value& rhs)
1479 {
1480  return rep->subsasgn (type, idx, rhs);
1481 }
1482 
1485  const std::list<octave_value_list>& idx,
1486  const octave_value& rhs)
1487 {
1488  return rep->undef_subsasgn (type, idx, rhs);
1489 }
1490 
1491 octave_value&
1492 octave_value::assign (assign_op op, const std::string& type,
1493  const std::list<octave_value_list>& idx,
1494  const octave_value& rhs)
1495 {
1496  make_unique ();
1497 
1498  octave_value t_rhs = rhs;
1499 
1500  if (op != op_asn_eq)
1501  {
1502  if (! is_defined ())
1503  error ("in computed assignment A(index) OP= X, A must be defined first");
1504 
1505  octave_value t = subsref (type, idx);
1506 
1507  binary_op binop = op_eq_to_binary_op (op);
1508 
1509  t_rhs = do_binary_op (binop, t, rhs);
1510  }
1511 
1512  *this = subsasgn (type, idx, t_rhs);
1513 
1514  return *this;
1515 }
1516 
1517 octave_value&
1518 octave_value::assign (assign_op op, const octave_value& rhs)
1519 {
1520  if (op == op_asn_eq)
1521  // Regularize a null matrix if stored into a variable.
1522  operator = (rhs.storable_value ());
1523  else if (is_defined ())
1524  {
1526 
1527  // Only attempt to operate in-place if this variable is unshared.
1528  if (rep->count == 1)
1529  {
1530  int tthis = this->type_id ();
1531  int trhs = rhs.type_id ();
1532 
1533  octave::type_info& ti
1534  = octave::__get_type_info__ ("octave_value::assign");
1535 
1536  f = ti.lookup_assign_op (op, tthis, trhs);
1537  }
1538 
1539  if (f)
1540  {
1541  f (*rep, octave_value_list (), *rhs.rep);
1542  // Usually unnecessary, but may be needed (complex arrays).
1543  maybe_mutate ();
1544  }
1545  else
1546  {
1547 
1548  binary_op binop = op_eq_to_binary_op (op);
1549 
1550  octave_value t = do_binary_op (binop, *this, rhs);
1551 
1552  operator = (t);
1553  }
1554  }
1555  else
1556  error ("in computed assignment A OP= X, A must be defined first");
1557 
1558  return *this;
1559 }
1560 
1562 octave_value::length (void) const
1563 {
1564  octave_idx_type retval = 0;
1565 
1566  const dim_vector dv = dims ();
1567 
1568  for (int i = 0; i < dv.ndims (); i++)
1569  {
1570  if (dv(i) == 0)
1571  {
1572  retval = 0;
1573  break;
1574  }
1575 
1576  if (dv(i) > retval)
1577  retval = dv(i);
1578  }
1579 
1580  return retval;
1581 }
1582 
1583 bool
1584 octave_value::is_equal (const octave_value& test) const
1585 {
1586  bool retval = false;
1587 
1588  // If there is no op_eq for these types, we can't compare values.
1589 
1590  if (rows () == test.rows () && columns () == test.columns ())
1591  {
1593 
1594  // Empty array also means a match.
1595  if (tmp.is_defined ())
1596  {
1597  if (tmp.isempty ())
1598  retval = true;
1599  else
1600  {
1601  // Reshape into a vector and call all() explicitly,
1602  // to avoid Octave:array-as-logical warning.
1603  tmp = tmp.reshape (dim_vector (tmp.numel (), 1));
1604  retval = tmp.all ().is_true ();
1605  }
1606  }
1607  }
1608 
1609  return retval;
1610 }
1611 
1612 // Define the idx_type_value function here instead of in ov.h to avoid
1613 // needing definitions for the SIZEOF_X macros in ov.h.
1614 
1616 octave_value::idx_type_value (bool req_int, bool frc_str_conv) const
1617 {
1618 #if defined (OCTAVE_ENABLE_64)
1619  return int64_value (req_int, frc_str_conv);
1620 #else
1621  return int_value (req_int, frc_str_conv);
1622 #endif
1623 }
1624 
1625 Cell
1626 octave_value::cell_value (void) const
1627 {
1628  return rep->cell_value ();
1629 }
1630 
1631 octave_map
1632 octave_value::map_value (void) const
1633 {
1634  return rep->map_value ();
1635 }
1636 
1638 octave_value::scalar_map_value (void) const
1639 {
1640  return rep->scalar_map_value ();
1641 }
1642 
1644 octave_value::function_value (bool silent) const
1645 {
1646  return rep->function_value (silent);
1647 }
1648 
1650 octave_value::classdef_object_value (bool silent) const
1651 {
1652  return rep->classdef_object_value (silent);
1653 }
1654 
1656 octave_value::user_function_value (bool silent) const
1657 {
1658  return rep->user_function_value (silent);
1659 }
1660 
1662 octave_value::user_script_value (bool silent) const
1663 {
1664  return rep->user_script_value (silent);
1665 }
1666 
1668 octave_value::user_code_value (bool silent) const
1669 {
1670  return rep->user_code_value (silent);
1671 }
1672 
1674 octave_value::fcn_handle_value (bool silent) const
1675 {
1676  return rep->fcn_handle_value (silent);
1677 }
1678 
1680 octave_value::fcn_inline_value (bool silent) const
1681 {
1682  return rep->fcn_inline_value (silent);
1683 }
1684 
1686 octave_value::list_value (void) const
1687 {
1688  return rep->list_value ();
1689 }
1690 
1691 static dim_vector
1692 make_vector_dims (const dim_vector& dv, bool force_vector_conversion,
1693  const std::string& my_type, const std::string& wanted_type)
1694 {
1695  dim_vector retval (dv);
1696  retval.chop_trailing_singletons ();
1697  octave_idx_type nel = dv.numel ();
1698 
1699  if (retval.ndims () > 2 || (retval(0) != 1 && retval(1) != 1))
1700  {
1701  if (! force_vector_conversion)
1702  warn_implicit_conversion ("Octave:array-to-vector",
1703  my_type.c_str (), wanted_type.c_str ());
1704  retval = dim_vector (nel, 1);
1705  }
1706 
1707  return retval;
1708 }
1709 
1711 octave_value::column_vector_value (bool force_string_conv,
1712  bool frc_vec_conv) const
1713 {
1714  return ColumnVector (vector_value (force_string_conv,
1715  frc_vec_conv));
1716 }
1717 
1719 octave_value::complex_column_vector_value (bool force_string_conv,
1720  bool frc_vec_conv) const
1721 {
1722  return ComplexColumnVector (complex_vector_value (force_string_conv,
1723  frc_vec_conv));
1724 }
1725 
1726 RowVector
1727 octave_value::row_vector_value (bool force_string_conv,
1728  bool frc_vec_conv) const
1729 {
1730  return RowVector (vector_value (force_string_conv,
1731  frc_vec_conv));
1732 }
1733 
1735 octave_value::complex_row_vector_value (bool force_string_conv,
1736  bool frc_vec_conv) const
1737 {
1738  return ComplexRowVector (complex_vector_value (force_string_conv,
1739  frc_vec_conv));
1740 }
1741 
1743 octave_value::vector_value (bool force_string_conv,
1744  bool force_vector_conversion) const
1745 {
1746  Array<double> retval = array_value (force_string_conv);
1747 
1748  return retval.reshape (make_vector_dims (retval.dims (),
1749  force_vector_conversion,
1750  type_name (), "real vector"));
1751 }
1752 
1753 template <typename T>
1754 static Array<int>
1755 convert_to_int_array (const Array<octave_int<T>>& A)
1756 {
1757  Array<int> retval (A.dims ());
1758  octave_idx_type n = A.numel ();
1759 
1760  for (octave_idx_type i = 0; i < n; i++)
1761  retval.xelem (i) = octave_int<int> (A.xelem (i));
1762 
1763  return retval;
1764 }
1765 
1766 Array<int>
1767 octave_value::int_vector_value (bool require_int, bool force_string_conv,
1768  bool force_vector_conversion) const
1769 {
1771 
1772  if (isinteger ())
1773  {
1774  if (is_int32_type ())
1775  retval = convert_to_int_array (int32_array_value ());
1776  else if (is_int64_type ())
1777  retval = convert_to_int_array (int64_array_value ());
1778  else if (is_int16_type ())
1779  retval = convert_to_int_array (int16_array_value ());
1780  else if (is_int8_type ())
1781  retval = convert_to_int_array (int8_array_value ());
1782  else if (is_uint32_type ())
1783  retval = convert_to_int_array (uint32_array_value ());
1784  else if (is_uint64_type ())
1785  retval = convert_to_int_array (uint64_array_value ());
1786  else if (is_uint16_type ())
1787  retval = convert_to_int_array (uint16_array_value ());
1788  else if (is_uint8_type ())
1789  retval = convert_to_int_array (uint8_array_value ());
1790  else
1791  retval = array_value (force_string_conv);
1792  }
1793  else
1794  {
1795  const NDArray a = array_value (force_string_conv);
1796 
1797  if (require_int)
1798  {
1799  retval.resize (a.dims ());
1800  for (octave_idx_type i = 0; i < a.numel (); i++)
1801  {
1802  double ai = a.elem (i);
1803  int v = static_cast<int> (ai);
1804  if (ai == v)
1805  retval.xelem (i) = v;
1806  else
1807  {
1808  error_with_cfn ("conversion to integer value failed");
1809  break;
1810  }
1811  }
1812  }
1813  else
1814  retval = Array<int> (a);
1815  }
1816 
1817  return retval.reshape (make_vector_dims (retval.dims (),
1818  force_vector_conversion,
1819  type_name (), "integer vector"));
1820 }
1821 
1822 template <typename T>
1824 convert_to_octave_idx_type_array (const Array<octave_int<T>>& A)
1825 {
1826  Array<octave_idx_type> retval (A.dims ());
1827  octave_idx_type n = A.numel ();
1828 
1829  for (octave_idx_type i = 0; i < n; i++)
1830  retval.xelem (i) = octave_int<octave_idx_type> (A.xelem (i));
1831 
1832  return retval;
1833 }
1834 
1837  bool force_string_conv,
1838  bool force_vector_conversion) const
1839 {
1841 
1842  if (isinteger ())
1843  {
1844  if (is_int32_type ())
1845  retval = convert_to_octave_idx_type_array (int32_array_value ());
1846  else if (is_int64_type ())
1847  retval = convert_to_octave_idx_type_array (int64_array_value ());
1848  else if (is_int16_type ())
1849  retval = convert_to_octave_idx_type_array (int16_array_value ());
1850  else if (is_int8_type ())
1851  retval = convert_to_octave_idx_type_array (int8_array_value ());
1852  else if (is_uint32_type ())
1853  retval = convert_to_octave_idx_type_array (uint32_array_value ());
1854  else if (is_uint64_type ())
1855  retval = convert_to_octave_idx_type_array (uint64_array_value ());
1856  else if (is_uint16_type ())
1857  retval = convert_to_octave_idx_type_array (uint16_array_value ());
1858  else if (is_uint8_type ())
1859  retval = convert_to_octave_idx_type_array (uint8_array_value ());
1860  else
1861  retval = array_value (force_string_conv);
1862  }
1863  else
1864  {
1865  const NDArray a = array_value (force_string_conv);
1866 
1867  if (require_int)
1868  {
1869  retval.resize (a.dims ());
1870  for (octave_idx_type i = 0; i < a.numel (); i++)
1871  {
1872  double ai = a.elem (i);
1873  octave_idx_type v = static_cast<octave_idx_type> (ai);
1874  if (ai == v)
1875  retval.xelem (i) = v;
1876  else
1877  {
1878  error_with_cfn ("conversion to integer value failed");
1879  break;
1880  }
1881  }
1882  }
1883  else
1885  }
1886 
1887  return retval.reshape (make_vector_dims (retval.dims (),
1888  force_vector_conversion,
1889  type_name (), "integer vector"));
1890 }
1891 
1893 octave_value::complex_vector_value (bool force_string_conv,
1894  bool force_vector_conversion) const
1895 {
1896  Array<Complex> retval = complex_array_value (force_string_conv);
1897 
1898  return retval.reshape (make_vector_dims (retval.dims (),
1899  force_vector_conversion,
1900  type_name (), "complex vector"));
1901 }
1902 
1904 octave_value::float_column_vector_value (bool force_string_conv,
1905  bool frc_vec_conv) const
1906 {
1907  return FloatColumnVector (float_vector_value (force_string_conv,
1908  frc_vec_conv));
1909 }
1910 
1912 octave_value::float_complex_column_vector_value (bool force_string_conv,
1913  bool frc_vec_conv) const
1914 {
1915  return
1917  frc_vec_conv));
1918 }
1919 
1921 octave_value::float_row_vector_value (bool force_string_conv,
1922  bool frc_vec_conv) const
1923 {
1924  return FloatRowVector (float_vector_value (force_string_conv,
1925  frc_vec_conv));
1926 }
1927 
1929 octave_value::float_complex_row_vector_value (bool force_string_conv,
1930  bool frc_vec_conv) const
1931 {
1932  return FloatComplexRowVector (float_complex_vector_value (force_string_conv,
1933  frc_vec_conv));
1934 }
1935 
1937 octave_value::float_vector_value (bool force_string_conv,
1938  bool force_vector_conversion) const
1939 {
1940  Array<float> retval = float_array_value (force_string_conv);
1941 
1942  return retval.reshape (make_vector_dims (retval.dims (),
1943  force_vector_conversion,
1944  type_name (), "real vector"));
1945 }
1946 
1948 octave_value::float_complex_vector_value (bool force_string_conv,
1949  bool force_vector_conversion) const
1950 {
1952 
1953  return retval.reshape (make_vector_dims (retval.dims (),
1954  force_vector_conversion,
1955  type_name (), "complex vector"));
1956 }
1957 
1958 // NAME can't always be "x ## FCN" because some of the original
1959 // value extraction functions perform implicit type conversions that we
1960 // wish to avoid for these functions.
1961 
1962 #define XVALUE_EXTRACTOR(TYPE, NAME, FCN) \
1963  TYPE \
1964  octave_value::NAME (const char *fmt, ...) const \
1965  { \
1966  TYPE retval; \
1967  \
1968  try \
1969  { \
1970  retval = FCN (); \
1971  } \
1972  catch (octave::execution_exception& e) \
1973  { \
1974  if (fmt) \
1975  { \
1976  va_list args; \
1977  va_start (args, fmt); \
1978  verror (e, fmt, args); \
1979  va_end (args); \
1980  } \
1981  \
1982  throw e; \
1983  } \
1984  \
1985  return retval; \
1986  }
1987 
1988 XVALUE_EXTRACTOR (short int, xshort_value, short_value)
1989 
1990 XVALUE_EXTRACTOR (unsigned short int, xushort_value, ushort_value)
1991 
1992 XVALUE_EXTRACTOR (int, xint_value, int_value)
1993 
1994 XVALUE_EXTRACTOR (unsigned int, xuint_value, uint_value)
1995 
1996 XVALUE_EXTRACTOR (int, xnint_value, nint_value)
1997 
1998 XVALUE_EXTRACTOR (long int, xlong_value, long_value)
1999 
2000 XVALUE_EXTRACTOR (unsigned long int, xulong_value, ulong_value)
2001 
2002 XVALUE_EXTRACTOR (int64_t, xint64_value, int64_value)
2003 
2004 XVALUE_EXTRACTOR (uint64_t, xuint64_value, uint64_value)
2005 
2006 XVALUE_EXTRACTOR (octave_idx_type, xidx_type_value, idx_type_value)
2007 
2008 XVALUE_EXTRACTOR (double, xdouble_value, double_value)
2009 XVALUE_EXTRACTOR (float, xfloat_value, float_value)
2010 
2011 XVALUE_EXTRACTOR (double, xscalar_value, scalar_value)
2012 XVALUE_EXTRACTOR (float, xfloat_scalar_value, float_scalar_value)
2013 
2014 XVALUE_EXTRACTOR (Matrix, xmatrix_value, matrix_value)
2015 XVALUE_EXTRACTOR (FloatMatrix, xfloat_matrix_value, float_matrix_value)
2016 
2017 XVALUE_EXTRACTOR (NDArray, xarray_value, array_value)
2018 XVALUE_EXTRACTOR (FloatNDArray, xfloat_array_value, float_array_value)
2019 
2020 XVALUE_EXTRACTOR (Complex, xcomplex_value, complex_value)
2021 XVALUE_EXTRACTOR (FloatComplex, xfloat_complex_value, float_complex_value)
2022 
2023 XVALUE_EXTRACTOR (ComplexMatrix, xcomplex_matrix_value, complex_matrix_value)
2024 XVALUE_EXTRACTOR (FloatComplexMatrix, xfloat_complex_matrix_value, float_complex_matrix_value)
2025 
2026 XVALUE_EXTRACTOR (ComplexNDArray, xcomplex_array_value, complex_array_value)
2027 XVALUE_EXTRACTOR (FloatComplexNDArray, xfloat_complex_array_value, float_complex_array_value)
2028 
2029 XVALUE_EXTRACTOR (bool, xbool_value, bool_value)
2030 XVALUE_EXTRACTOR (boolMatrix, xbool_matrix_value, bool_matrix_value)
2031 XVALUE_EXTRACTOR (boolNDArray, xbool_array_value, bool_array_value)
2032 
2033 XVALUE_EXTRACTOR (charMatrix, xchar_matrix_value, char_matrix_value)
2034 XVALUE_EXTRACTOR (charNDArray, xchar_array_value, char_array_value)
2035 
2036 XVALUE_EXTRACTOR (SparseMatrix, xsparse_matrix_value, sparse_matrix_value)
2037 XVALUE_EXTRACTOR (SparseComplexMatrix, xsparse_complex_matrix_value, sparse_complex_matrix_value)
2038 XVALUE_EXTRACTOR (SparseBoolMatrix, xsparse_bool_matrix_value, sparse_bool_matrix_value)
2039 
2040 XVALUE_EXTRACTOR (DiagMatrix, xdiag_matrix_value, diag_matrix_value)
2041 XVALUE_EXTRACTOR (FloatDiagMatrix, xfloat_diag_matrix_value, float_diag_matrix_value)
2042 XVALUE_EXTRACTOR (ComplexDiagMatrix, xcomplex_diag_matrix_value, complex_diag_matrix_value)
2043 XVALUE_EXTRACTOR (FloatComplexDiagMatrix, xfloat_complex_diag_matrix_value, float_complex_diag_matrix_value)
2044 
2045 XVALUE_EXTRACTOR (PermMatrix, xperm_matrix_value, perm_matrix_value)
2046 
2047 XVALUE_EXTRACTOR (octave_int8, xint8_scalar_value, int8_scalar_value)
2048 XVALUE_EXTRACTOR (octave_int16, xint16_scalar_value, int16_scalar_value)
2049 XVALUE_EXTRACTOR (octave_int32, xint32_scalar_value, int32_scalar_value)
2050 XVALUE_EXTRACTOR (octave_int64, xint64_scalar_value, int64_scalar_value)
2051 
2052 XVALUE_EXTRACTOR (octave_uint8, xuint8_scalar_value, uint8_scalar_value)
2053 XVALUE_EXTRACTOR (octave_uint16, xuint16_scalar_value, uint16_scalar_value)
2054 XVALUE_EXTRACTOR (octave_uint32, xuint32_scalar_value, uint32_scalar_value)
2055 XVALUE_EXTRACTOR (octave_uint64, xuint64_scalar_value, uint64_scalar_value)
2056 
2057 XVALUE_EXTRACTOR (int8NDArray, xint8_array_value, int8_array_value)
2058 XVALUE_EXTRACTOR (int16NDArray, xint16_array_value, int16_array_value)
2059 XVALUE_EXTRACTOR (int32NDArray, xint32_array_value, int32_array_value)
2060 XVALUE_EXTRACTOR (int64NDArray, xint64_array_value, int64_array_value)
2061 
2062 XVALUE_EXTRACTOR (uint8NDArray, xuint8_array_value, uint8_array_value)
2063 XVALUE_EXTRACTOR (uint16NDArray, xuint16_array_value, uint16_array_value)
2064 XVALUE_EXTRACTOR (uint32NDArray, xuint32_array_value, uint32_array_value)
2065 XVALUE_EXTRACTOR (uint64NDArray, xuint64_array_value, uint64_array_value)
2066 
2067 XVALUE_EXTRACTOR (std::string, xstring_value, rep->xstring_value)
2068 XVALUE_EXTRACTOR (string_vector, xstring_vector_value, string_vector_value)
2069 
2070 XVALUE_EXTRACTOR (Cell, xcell_value, cell_value)
2071 XVALUE_EXTRACTOR (Array<std::string>, xcellstr_value, cellstr_value)
2072 
2073 XVALUE_EXTRACTOR (Range, xrange_value, range_value)
2074 
2075 XVALUE_EXTRACTOR (octave_map, xmap_value, map_value)
2076 XVALUE_EXTRACTOR (octave_scalar_map, xscalar_map_value, scalar_map_value)
2077 
2078 XVALUE_EXTRACTOR (ColumnVector, xcolumn_vector_value, column_vector_value)
2079 XVALUE_EXTRACTOR (ComplexColumnVector, xcomplex_column_vector_value, complex_column_vector_value)
2080 
2081 XVALUE_EXTRACTOR (RowVector, xrow_vector_value, row_vector_value)
2082 XVALUE_EXTRACTOR (ComplexRowVector, xcomplex_row_vector_value, complex_row_vector_value)
2083 
2084 XVALUE_EXTRACTOR (FloatColumnVector, xfloat_column_vector_value, float_column_vector_value)
2085 XVALUE_EXTRACTOR (FloatComplexColumnVector, xfloat_complex_column_vector_value, float_complex_column_vector_value)
2086 
2087 XVALUE_EXTRACTOR (FloatRowVector, xfloat_row_vector_value, float_row_vector_value)
2088 XVALUE_EXTRACTOR (FloatComplexRowVector, xfloat_complex_row_vector_value, float_complex_row_vector_value)
2089 
2090 XVALUE_EXTRACTOR (Array<int>, xint_vector_value, int_vector_value)
2091 XVALUE_EXTRACTOR (Array<octave_idx_type>, xoctave_idx_type_vector_value, octave_idx_type_vector_value)
2092 
2093 XVALUE_EXTRACTOR (Array<double>, xvector_value, vector_value)
2094 XVALUE_EXTRACTOR (Array<Complex>, xcomplex_vector_value, complex_vector_value)
2095 
2096 XVALUE_EXTRACTOR (Array<float>, xfloat_vector_value, float_vector_value)
2097 XVALUE_EXTRACTOR (Array<FloatComplex>, xfloat_complex_vector_value, float_complex_vector_value)
2098 
2099 XVALUE_EXTRACTOR (octave_function *, xfunction_value, function_value)
2100 XVALUE_EXTRACTOR (octave_user_function *, xuser_function_value, user_function_value)
2101 XVALUE_EXTRACTOR (octave_user_script *, xuser_script_value, user_script_value)
2102 XVALUE_EXTRACTOR (octave_user_code *, xuser_code_value, user_code_value)
2103 XVALUE_EXTRACTOR (octave_fcn_handle *, xfcn_handle_value, fcn_handle_value)
2104 XVALUE_EXTRACTOR (octave_fcn_inline *, xfcn_inline_value, fcn_inline_value)
2105 
2106 XVALUE_EXTRACTOR (octave_value_list, xlist_value, list_value)
2107 
2108 #undef XVALUE_EXTRACTOR
2109 
2111 octave_value::storable_value (void) const
2112 {
2113  octave_value retval = *this;
2114  if (isnull ())
2116  else
2118 
2119  return retval;
2120 }
2121 
2122 void
2124 {
2125  if (isnull ())
2126  {
2127  octave_base_value *rc = rep->empty_clone ();
2128  if (--rep->count == 0)
2129  delete rep;
2130  rep = rc;
2131  }
2132  else
2133  maybe_economize ();
2134 }
2135 
2138 {
2139  return rep->get_edit_display_format ();
2140 }
2141 
2142 int
2143 octave_value::write (octave::stream& os, int block_size,
2144  oct_data_conv::data_type output_type, int skip,
2146 {
2147  return rep->write (os, block_size, output_type, skip, flt_fmt);
2148 }
2149 
2150 OCTAVE_NORETURN static void
2151 err_binary_op (const std::string& on, const std::string& tn1,
2152  const std::string& tn2)
2153 {
2154  error ("binary operator '%s' not implemented for '%s' by '%s' operations",
2155  on.c_str (), tn1.c_str (), tn2.c_str ());
2156 }
2157 
2158 OCTAVE_NORETURN static void
2159 err_binary_op_conv (const std::string& on)
2160 {
2161  error ("type conversion failed for binary operator '%s'", on.c_str ());
2162 }
2163 
2166  const octave_value& v1, const octave_value& v2)
2167 {
2169 
2170  int t1 = v1.type_id ();
2171  int t2 = v2.type_id ();
2172 
2173  if (t1 == octave_class::static_type_id ()
2174  || t2 == octave_class::static_type_id ()
2176  || t2 == octave_classdef::static_type_id ())
2177  {
2179  = ti.lookup_binary_class_op (op);
2180 
2181  if (! f)
2182  err_binary_op (octave_value::binary_op_as_string (op),
2183  v1.class_name (), v2.class_name ());
2184 
2185  retval = f (v1, v2);
2186  }
2187  else
2188  {
2189  // FIXME: we need to handle overloading operators for built-in
2190  // classes (double, char, int8, etc.)
2191 
2193  = ti.lookup_binary_op (op, t1, t2);
2194 
2195  if (f)
2196  retval = f (*v1.rep, *v2.rep);
2197  else
2198  {
2199  octave_value tv1;
2202 
2203  octave_value tv2;
2206 
2207  // Try biased (one-sided) conversions first.
2208  if (cf2.type_id () >= 0
2209  && ti.lookup_binary_op (op, t1, cf2.type_id ()))
2210  cf1 = nullptr;
2211  else if (cf1.type_id () >= 0
2212  && ti.lookup_binary_op (op, cf1.type_id (), t2))
2213  cf2 = nullptr;
2214 
2215  if (cf1)
2216  {
2217  octave_base_value *tmp = cf1 (*v1.rep);
2218 
2219  if (! tmp)
2220  err_binary_op_conv (octave_value::binary_op_as_string (op));
2221 
2222  tv1 = octave_value (tmp);
2223  t1 = tv1.type_id ();
2224  }
2225  else
2226  tv1 = v1;
2227 
2228  if (cf2)
2229  {
2230  octave_base_value *tmp = cf2 (*v2.rep);
2231 
2232  if (! tmp)
2233  err_binary_op_conv (octave_value::binary_op_as_string (op));
2234 
2235  tv2 = octave_value (tmp);
2236  t2 = tv2.type_id ();
2237  }
2238  else
2239  tv2 = v2;
2240 
2241  if (cf1 || cf2)
2242  {
2243  retval = do_binary_op (op, tv1, tv2);
2244  }
2245  else
2246  {
2247  //demote double -> single and try again
2248  cf1 = tv1.numeric_demotion_function ();
2249 
2250  cf2 = tv2.numeric_demotion_function ();
2251 
2252  // Try biased (one-sided) conversions first.
2253  if (cf2.type_id () >= 0
2254  && ti.lookup_binary_op (op, t1, cf2.type_id ()))
2255  cf1 = nullptr;
2256  else if (cf1.type_id () >= 0
2257  && ti.lookup_binary_op (op, cf1.type_id (), t2))
2258  cf2 = nullptr;
2259 
2260  if (cf1)
2261  {
2262  octave_base_value *tmp = cf1 (*tv1.rep);
2263 
2264  if (! tmp)
2265  err_binary_op_conv (octave_value::binary_op_as_string (op));
2266 
2267  tv1 = octave_value (tmp);
2268  t1 = tv1.type_id ();
2269  }
2270 
2271  if (cf2)
2272  {
2273  octave_base_value *tmp = cf2 (*tv2.rep);
2274 
2275  if (! tmp)
2276  err_binary_op_conv (octave_value::binary_op_as_string (op));
2277 
2278  tv2 = octave_value (tmp);
2279  t2 = tv2.type_id ();
2280  }
2281 
2282  if (! cf1 && ! cf2)
2283  err_binary_op (octave_value::binary_op_as_string (op),
2284  v1.type_name (), v2.type_name ());
2285 
2286  f = ti.lookup_binary_op (op, t1, t2);
2287 
2288  if (! f)
2289  err_binary_op (octave_value::binary_op_as_string (op),
2290  v1.type_name (), v2.type_name ());
2291 
2292  retval = f (*tv1.rep, *tv2.rep);
2293  }
2294  }
2295  }
2296 
2297  return retval;
2298 }
2299 
2302  const octave_value& v1, const octave_value& v2)
2303 {
2304  octave::type_info& ti = octave::__get_type_info__ ("do_binary_op");
2305 
2306  return do_binary_op (ti, op, v1, v2);
2307 }
2308 
2309 static octave_value
2310 decompose_binary_op (octave::type_info& ti,
2312  const octave_value& v1, const octave_value& v2)
2313 {
2314  switch (op)
2315  {
2319 
2321  return do_binary_op (ti, octave_value::op_mul,
2323 
2325  return do_binary_op (ti, octave_value::op_mul,
2327 
2329  return do_binary_op (ti, octave_value::op_mul,
2331 
2333  return do_binary_op (ti, octave_value::op_ldiv,
2335 
2337  return do_binary_op (ti, octave_value::op_ldiv,
2339 
2343 
2347 
2351 
2355 
2356  default:
2357  error ("invalid compound operator");
2358  }
2359 }
2360 
2363  const octave_value& v1, const octave_value& v2)
2364 {
2366 
2367  int t1 = v1.type_id ();
2368  int t2 = v2.type_id ();
2369 
2370  if (t1 == octave_class::static_type_id ()
2371  || t2 == octave_class::static_type_id ()
2373  || t2 == octave_classdef::static_type_id ())
2374  {
2376 
2377  if (f)
2378  retval = f (v1, v2);
2379  else
2380  retval = decompose_binary_op (ti, op, v1, v2);
2381  }
2382  else
2383  {
2385 
2386  if (f)
2387  retval = f (*v1.rep, *v2.rep);
2388  else
2389  retval = decompose_binary_op (ti, op, v1, v2);
2390  }
2391 
2392  return retval;
2393 }
2394 
2397  const octave_value& v1, const octave_value& v2)
2398 {
2399  octave::type_info& ti = octave::__get_type_info__ ("do_binary_op");
2400 
2401  return do_binary_op (ti, op, v1, v2);
2402 }
2403 
2404 OCTAVE_NORETURN static void
2405 err_cat_op (const std::string& tn1, const std::string& tn2)
2406 {
2407  error ("concatenation operator not implemented for '%s' by '%s' operations",
2408  tn1.c_str (), tn2.c_str ());
2409 }
2410 
2411 OCTAVE_NORETURN static void
2412 err_cat_op_conv (void)
2413 {
2414  error ("type conversion failed for concatenation operator");
2415 }
2416 
2418 do_cat_op (octave::type_info& ti, const octave_value& v1,
2420 {
2422 
2423  // Can't rapid return for concatenation with an empty object here as
2424  // something like cat(1,[],single([]) must return the correct type.
2425 
2426  int t1 = v1.type_id ();
2427  int t2 = v2.type_id ();
2428 
2430 
2431  if (f)
2432  retval = f (*v1.rep, *v2.rep, ra_idx);
2433  else
2434  {
2435  octave_value tv1;
2437 
2438  octave_value tv2;
2440 
2441  // Try biased (one-sided) conversions first.
2442  if (cf2.type_id () >= 0 && ti.lookup_cat_op (t1, cf2.type_id ()))
2443  cf1 = nullptr;
2444  else if (cf1.type_id () >= 0 && ti.lookup_cat_op (cf1.type_id (), t2))
2445  cf2 = nullptr;
2446 
2447  if (cf1)
2448  {
2449  octave_base_value *tmp = cf1 (*v1.rep);
2450 
2451  if (! tmp)
2452  err_cat_op_conv ();
2453 
2454  tv1 = octave_value (tmp);
2455  t1 = tv1.type_id ();
2456  }
2457  else
2458  tv1 = v1;
2459 
2460  if (cf2)
2461  {
2462  octave_base_value *tmp = cf2 (*v2.rep);
2463 
2464  if (! tmp)
2465  err_cat_op_conv ();
2466 
2467  tv2 = octave_value (tmp);
2468  t2 = tv2.type_id ();
2469  }
2470  else
2471  tv2 = v2;
2472 
2473  if (! cf1 && ! cf2)
2474  err_cat_op (v1.type_name (), v2.type_name ());
2475 
2476  retval = do_cat_op (ti, tv1, tv2, ra_idx);
2477  }
2478 
2479  return retval;
2480 }
2481 
2483 do_cat_op (const octave_value& v1, const octave_value& v2,
2485 {
2486  octave::type_info& ti = octave::__get_type_info__ ("do_cat_op");
2487 
2488  return do_cat_op (ti, v1, v2, ra_idx);
2489 }
2490 
2492 do_colon_op (const octave_value& base, const octave_value& increment,
2493  const octave_value& limit, bool is_for_cmd_expr)
2494 {
2496 
2497  if (base.isobject () || increment.isobject () || limit.isobject ())
2498  {
2499  std::string dispatch_type;
2500 
2501  if (base.isobject ())
2502  dispatch_type = base.class_name ();
2503  else if (increment.is_defined () && increment.isobject ())
2504  dispatch_type = increment.class_name ();
2505  else
2506  dispatch_type = limit.class_name ();
2507 
2508  octave::symbol_table& symtab = octave::__get_symbol_table__ ("do_colon_op");
2509 
2510  octave_value meth = symtab.find_method ("colon", dispatch_type);
2511 
2512  if (! meth.is_defined ())
2513  error ("colon method not defined for %s class", dispatch_type.c_str ());
2514 
2515  octave_value_list args;
2516 
2517  if (increment.is_defined ())
2518  {
2519  args(2) = limit;
2520  args(1) = increment;
2521  }
2522  else
2523  args(1) = limit;
2524 
2525  args(0) = base;
2526 
2527  octave_value_list tmp = octave::feval (meth.function_value (), args, 1);
2528 
2529  if (tmp.length () > 0)
2530  retval = tmp(0);
2531  }
2532  else
2533  {
2534  bool result_is_str = (base.is_string () && limit.is_string ());
2535  bool dq_str = (base.is_dq_string () || limit.is_dq_string ());
2536 
2537  Matrix m_base, m_limit, m_increment;
2538 
2539  try
2540  {
2541  m_base = base.matrix_value (true);
2542  }
2543  catch (octave::execution_exception& e)
2544  {
2545  error (e, "invalid base value in colon expression");
2546  }
2547 
2548  try
2549  {
2550  m_limit = limit.matrix_value (true);
2551  }
2552  catch (octave::execution_exception& e)
2553  {
2554  error (e, "invalid limit value in colon expression");
2555  }
2556 
2557  try
2558  {
2559  m_increment = (increment.is_defined ()
2560  ? increment.matrix_value (true)
2561  : Matrix (1, 1, 1.0));
2562  }
2563  catch (octave::execution_exception& e)
2564  {
2565  error (e, "invalid increment value in colon expression");
2566  }
2567 
2568  bool base_empty = m_base.isempty ();
2569  bool limit_empty = m_limit.isempty ();
2570  bool increment_empty = m_increment.isempty ();
2571 
2572  if (base_empty || limit_empty || increment_empty)
2573  retval = Range ();
2574  else
2575  {
2576  Range r (m_base(0), m_limit(0), m_increment(0));
2577 
2578  // For compatibility with Matlab, don't allow the range used in
2579  // a FOR loop expression to be converted to a Matrix.
2580 
2581  retval = octave_value (r, is_for_cmd_expr);
2582 
2583  if (result_is_str)
2584  retval = (retval.convert_to_str (false, true, dq_str ? '"' : '\''));
2585  }
2586  }
2587 
2588  return retval;
2589 }
2590 
2591 void
2592 octave_value::print_info (std::ostream& os, const std::string& prefix) const
2593 {
2594  os << prefix << "type_name: " << type_name () << "\n"
2595  << prefix << "count: " << get_count () << "\n"
2596  << prefix << "rep info: ";
2597 
2598  rep->print_info (os, prefix + ' ');
2599 }
2600 
2601 OCTAVE_NORETURN static void
2603 {
2604  error ("unary operator '%s' not implemented for '%s' operands",
2605  on.c_str (), tn.c_str ());
2606 }
2607 
2608 OCTAVE_NORETURN static void
2610 {
2611  error ("type conversion failed for unary operator '%s'", on.c_str ());
2612 }
2613 
2616  const octave_value& v)
2617 {
2619 
2620  int t = v.type_id ();
2621 
2624  {
2626 
2627  if (! f)
2629 
2630  retval = f (v);
2631  }
2632  else
2633  {
2634  // FIXME: we need to handle overloading operators for built-in
2635  // classes (double, char, int8, etc.)
2636 
2638 
2639  if (f)
2640  retval = f (*v.rep);
2641  else
2642  {
2643  octave_value tv;
2646 
2647  if (! cf)
2649  v.type_name ());
2650 
2651  octave_base_value *tmp = cf (*v.rep);
2652 
2653  if (! tmp)
2655 
2656  tv = octave_value (tmp);
2657  retval = do_unary_op (op, tv);
2658  }
2659  }
2660 
2661  return retval;
2662 }
2663 
2666 {
2667  octave::type_info& ti = octave::__get_type_info__ ("do_unary_op");
2668 
2669  return do_unary_op (ti, op, v);
2670 }
2671 
2672 OCTAVE_NORETURN static void
2674  const std::string& tn)
2675 {
2676  error ("operator %s: type conversion for '%s' failed",
2677  op.c_str (), tn.c_str ());
2678 }
2679 
2680 octave_value&
2682 {
2683  if (op == op_incr || op == op_decr)
2684  {
2685  // We want the error just here, because in the other branch this should
2686  // not happen, and if it did anyway (internal error), the message would
2687  // be confusing.
2688  if (is_undefined ())
2689  {
2690  std::string op_str = unary_op_as_string (op);
2691  error ("in x%s or %sx, x must be defined first",
2692  op_str.c_str (), op_str.c_str ());
2693  return *this;
2694  }
2695 
2696  // Genuine.
2697  int t = type_id ();
2698 
2699  octave::type_info& ti
2700  = octave::__get_type_info__ ("do_non_const_unary_op");
2701 
2703  = ti.lookup_non_const_unary_op (op, t);
2704 
2705  if (f)
2706  {
2707  make_unique ();
2708 
2709  f (*rep);
2710  }
2711  else
2712  {
2714 
2715  if (! cf)
2717 
2718  octave_base_value *tmp = cf (*rep);
2719 
2720  if (! tmp)
2723 
2724  octave_base_value *old_rep = rep;
2725  rep = tmp;
2726 
2727  t = type_id ();
2728 
2729  f = ti.lookup_non_const_unary_op (op, t);
2730 
2731  if (f)
2732  {
2733  f (*rep);
2734 
2735  if (old_rep && --old_rep->count == 0)
2736  delete old_rep;
2737  }
2738  else
2739  {
2740  if (old_rep)
2741  {
2742  if (--rep->count == 0)
2743  delete rep;
2744 
2745  rep = old_rep;
2746  }
2747 
2749  type_name ());
2750  }
2751  }
2752  }
2753  else
2754  {
2755  // Non-genuine.
2756  int t = type_id ();
2757 
2759 
2760  // Only attempt to operate in-place if this variable is unshared.
2761  if (rep->count == 1)
2762  {
2763  octave::type_info& ti
2764  = octave::__get_type_info__ ("do_non_const_unary_op");
2765 
2766  f = ti.lookup_non_const_unary_op (op, t);
2767  }
2768 
2769  if (f)
2770  f (*rep);
2771  else
2772  *this = do_unary_op (op, *this);
2773  }
2774 
2775  return *this;
2776 }
2777 
2778 octave_value&
2780  const std::list<octave_value_list>& idx)
2781 {
2782  if (idx.empty ())
2783  do_non_const_unary_op (op);
2784  else
2785  {
2786  // FIXME: only do the following stuff if we can't find a
2787  // specific function to call to handle the op= operation for the
2788  // types we have.
2789 
2790  assign_op assop = unary_op_to_assign_op (op);
2791 
2792  assign (assop, type, idx, 1.0);
2793  }
2794 
2795  return *this;
2796 }
2797 
2800 {
2801  switch (op)
2802  {
2803  case op_incr:
2804  return op_add_eq;
2805 
2806  case op_decr:
2807  return op_sub_eq;
2808 
2809  default:
2810  {
2812  error ("operator %s: no assign operator found", on.c_str ());
2813  }
2814  }
2815 }
2816 
2819 {
2820  switch (op)
2821  {
2822  case op_add_eq:
2823  return op_add;
2824 
2825  case op_sub_eq:
2826  return op_sub;
2827 
2828  case op_mul_eq:
2829  return op_mul;
2830 
2831  case op_div_eq:
2832  return op_div;
2833 
2834  case op_ldiv_eq:
2835  return op_ldiv;
2836 
2837  case op_pow_eq:
2838  return op_pow;
2839 
2840  case op_el_mul_eq:
2841  return op_el_mul;
2842 
2843  case op_el_div_eq:
2844  return op_el_div;
2845 
2846  case op_el_ldiv_eq:
2847  return op_el_ldiv;
2848 
2849  case op_el_pow_eq:
2850  return op_el_pow;
2851 
2852  case op_el_and_eq:
2853  return op_el_and;
2854 
2855  case op_el_or_eq:
2856  return op_el_or;
2857 
2858  default:
2859  {
2861  error ("operator %s: no binary operator found", on.c_str ());
2862  }
2863  }
2864 }
2865 
2868 {
2869  if (type.length () > 0)
2870  {
2871  switch (type[0])
2872  {
2873  case '(':
2874  if (type.length () > 1 && type[1] == '.')
2875  return octave_map ();
2876  else
2877  return octave_value (rhs.empty_clone ());
2878 
2879  case '{':
2880  return Cell ();
2881 
2882  case '.':
2883  return octave_scalar_map ();
2884 
2885  default:
2886  panic_impossible ();
2887  }
2888  }
2889  else
2890  return octave_value (rhs.empty_clone ());
2891 }
2892 
2893 void
2895 {
2951 }
2952 
2953 DEFUN (sizeof, args, ,
2954  doc: /* -*- texinfo -*-
2955 @deftypefn {} {} sizeof (@var{val})
2956 Return the size of @var{val} in bytes.
2957 @seealso{whos}
2958 @end deftypefn */)
2959 {
2960  if (args.length () != 1)
2961  print_usage ();
2962 
2963  return ovl (args(0).byte_size ());
2964 }
2965 
2966 /*
2967 %!assert (sizeof (uint64 (ones (3))), 72)
2968 %!assert (sizeof (double (zeros (2,4))), 64)
2969 %!assert (sizeof ({"foo", "bar", "baaz"}), 10)
2970 */
2971 
2972 static void
2974  std::string& type_string,
2975  std::list<octave_value_list>& idx)
2976 {
2977  const octave_map m = arg.xmap_value ("%s: second argument must be a structure with fields 'type' and 'subs'", name);
2978 
2979  if (m.nfields () != 2 || ! m.contains ("type") || ! m.contains ("subs"))
2980  error ("%s: second argument must be a structure with fields 'type' and 'subs'",
2981  name);
2982 
2983  octave_idx_type nel = m.numel ();
2984 
2985  type_string = std::string (nel, '\0');
2986  idx = std::list<octave_value_list> ();
2987 
2988  if (nel == 0)
2989  return;
2990 
2991  const Cell type = m.contents ("type");
2992  const Cell subs = m.contents ("subs");
2993 
2994  for (int k = 0; k < nel; k++)
2995  {
2996  std::string item = type(k).xstring_value ("%s: type(%d) must be a string", name, k+1);
2997 
2998  if (item == "{}")
2999  type_string[k] = '{';
3000  else if (item == "()")
3001  type_string[k] = '(';
3002  else if (item == ".")
3003  type_string[k] = '.';
3004  else
3005  error ("%s: invalid indexing type '%s'", name, item.c_str ());
3006 
3007  octave_value_list idx_item;
3008 
3009  if (subs(k).is_string ())
3010  idx_item(0) = subs(k);
3011  else if (subs(k).iscell ())
3012  {
3013  Cell subs_cell = subs(k).cell_value ();
3014 
3015  for (int n = 0; n < subs_cell.numel (); n++)
3016  {
3017  if (subs_cell(n).is_string ()
3018  && subs_cell(n).string_value () == ":")
3020  else
3021  idx_item(n) = subs_cell(n);
3022  }
3023  }
3024  else
3025  error ("%s: subs(%d) must be a string or cell array", name, k+1);
3026 
3027  idx.push_back (idx_item);
3028  }
3029 }
3030 
3031 DEFUN (subsref, args, nargout,
3032  doc: /* -*- texinfo -*-
3033 @deftypefn {} {} subsref (@var{val}, @var{idx})
3034 Perform the subscripted element selection operation on @var{val} according
3035 to the subscript specified by @var{idx}.
3036 
3037 The subscript @var{idx} must be a structure array with fields @samp{type}
3038 and @samp{subs}. Valid values for @samp{type} are @qcode{"()"},
3039 @qcode{"@{@}"}, and @qcode{"."}. The @samp{subs} field may be either
3040 @qcode{":"} or a cell array of index values.
3041 
3042 The following example shows how to extract the first two columns of a matrix
3043 
3044 @example
3045 @group
3046 val = magic (3)
3047  @result{} val = [ 8 1 6
3048  3 5 7
3049  4 9 2 ]
3050 idx.type = "()";
3051 idx.subs = @{":", 1:2@};
3052 subsref (val, idx)
3053  @result{} [ 8 1
3054  3 5
3055  4 9 ]
3056 @end group
3057 @end example
3058 
3059 @noindent
3060 Note that this is the same as writing @code{val(:, 1:2)}.
3061 
3062 If @var{idx} is an empty structure array with fields @samp{type} and
3063 @samp{subs}, return @var{val}.
3064 @seealso{subsasgn, substruct}
3065 @end deftypefn */)
3066 {
3067  if (args.length () != 2)
3068  print_usage ();
3069 
3070  std::string type;
3071  std::list<octave_value_list> idx;
3072 
3073  decode_subscripts ("subsref", args(1), type, idx);
3074 
3075  octave_value arg0 = args(0);
3076 
3077  if (type.empty ())
3078  return ovl (arg0);
3079  else
3080  return arg0.subsref (type, idx, nargout);
3081 }
3082 
3083 DEFUN (subsasgn, args, ,
3084  doc: /* -*- texinfo -*-
3085 @deftypefn {} {} subsasgn (@var{val}, @var{idx}, @var{rhs})
3086 Perform the subscripted assignment operation according to the subscript
3087 specified by @var{idx}.
3088 
3089 The subscript @var{idx} must be a structure array with fields @samp{type}
3090 and @samp{subs}. Valid values for @samp{type} are @qcode{"()"},
3091 @qcode{"@{@}"}, and @qcode{"."}. The @samp{subs} field may be either
3092 @qcode{":"} or a cell array of index values.
3093 
3094 The following example shows how to set the two first columns of a 3-by-3
3095 matrix to zero.
3096 
3097 @example
3098 @group
3099 val = magic (3);
3100 idx.type = "()";
3101 idx.subs = @{":", 1:2@};
3102 subsasgn (val, idx, 0)
3103  @result{} [ 0 0 6
3104  0 0 7
3105  0 0 2 ]
3106 @end group
3107 @end example
3108 
3109 Note that this is the same as writing @code{val(:, 1:2) = 0}.
3110 
3111 If @var{idx} is an empty structure array with fields @samp{type} and
3112 @samp{subs}, return @var{rhs}.
3113 @seealso{subsref, substruct, optimize_subsasgn_calls}
3114 @end deftypefn */)
3115 {
3116  if (args.length () != 3)
3117  print_usage ();
3118 
3119  std::string type;
3120  std::list<octave_value_list> idx;
3121 
3122  decode_subscripts ("subsasgn", args(1), type, idx);
3123 
3124  if (type.empty ())
3125  {
3126  // Regularize a null matrix if stored into a variable.
3127  return ovl (args(2).storable_value ());
3128  }
3129  else
3130  {
3131  octave_value arg0 = args(0);
3132  octave_value arg2 = args(2);
3133 
3134  arg0.make_unique ();
3135 
3136  bool arg2_null = arg2.is_zero_by_zero () && arg2.is_double_type ();
3137 
3138  return ovl (arg0.subsasgn (type, idx, (arg2_null
3140  : arg2)));
3141  }
3142 }
3143 
3144 /*
3145 %!test
3146 %! a = reshape ([1:25], 5,5);
3147 %! idx1 = substruct ("()", {3, 3});
3148 %! idx2 = substruct ("()", {2:2:5, 2:2:5});
3149 %! idx3 = substruct ("()", {":", [1,5]});
3150 %! idx4 = struct ("type", {}, "subs", {});
3151 %! assert (subsref (a, idx1), 13);
3152 %! assert (subsref (a, idx2), [7 17; 9 19]);
3153 %! assert (subsref (a, idx3), [1:5; 21:25]');
3154 %! assert (subsref (a, idx4), a);
3155 %! a = subsasgn (a, idx1, 0);
3156 %! a = subsasgn (a, idx2, 0);
3157 %! a = subsasgn (a, idx3, 0);
3158 %!# a = subsasgn (a, idx4, 0);
3159 %! b = [0 6 11 16 0
3160 %! 0 0 12 0 0
3161 %! 0 8 0 18 0
3162 %! 0 0 14 0 0
3163 %! 0 10 15 20 0];
3164 %! assert (a, b);
3165 
3166 %!test
3167 %! x = 1:10;
3168 %! assert (subsasgn (x, substruct ("()", {1}), zeros (0, 0)), 2:10);
3169 
3170 %!test
3171 %! c = num2cell (reshape ([1:25],5,5));
3172 %! idx1 = substruct ("{}", {3, 3});
3173 %! idx2 = substruct ("()", {2:2:5, 2:2:5});
3174 %! idx3 = substruct ("()", {":", [1,5]});
3175 %! idx2p = substruct ("{}", {2:2:5, 2:2:5});
3176 %! idx3p = substruct ("{}", {":", [1,5]});
3177 %! idx4 = struct ("type", {}, "subs", {});
3178 %! assert ({ subsref(c, idx1) }, {13});
3179 %! assert ({ subsref(c, idx2p) }, {7 9 17 19});
3180 %! assert ({ subsref(c, idx3p) }, num2cell ([1:5, 21:25]));
3181 %! assert (subsref (c, idx4), c);
3182 %! c = subsasgn (c, idx1, 0);
3183 %! c = subsasgn (c, idx2, 0);
3184 %! c = subsasgn (c, idx3, 0);
3185 %!# c = subsasgn (c, idx4, 0);
3186 %! d = {0 6 11 16 0
3187 %! 0 0 12 0 0
3188 %! 0 8 0 18 0
3189 %! 0 0 14 0 0
3190 %! 0 10 15 20 0};
3191 %! assert (c, d);
3192 
3193 %!test
3194 %! s.a = "ohai";
3195 %! s.b = "dere";
3196 %! s.c = 42;
3197 %! idx1 = substruct (".", "a");
3198 %! idx2 = substruct (".", "b");
3199 %! idx3 = substruct (".", "c");
3200 %! idx4 = struct ("type", {}, "subs", {});
3201 %! assert (subsref (s, idx1), "ohai");
3202 %! assert (subsref (s, idx2), "dere");
3203 %! assert (subsref (s, idx3), 42);
3204 %! assert (subsref (s, idx4), s);
3205 %! s = subsasgn (s, idx1, "Hello");
3206 %! s = subsasgn (s, idx2, "There");
3207 %! s = subsasgn (s, idx3, 163);
3208 %!# s = subsasgn (s, idx4, 163);
3209 %! t.a = "Hello";
3210 %! t.b = "There";
3211 %! t.c = 163;
3212 %! assert (s, t);
3213 */
3214 
3215 DEFUN (is_sq_string, args, ,
3216  doc: /* -*- texinfo -*-
3217 @deftypefn {} {} is_sq_string (@var{x})
3218 Return true if @var{x} is a single-quoted character string.
3219 @seealso{is_dq_string, ischar}
3220 @end deftypefn */)
3221 {
3222  if (args.length () != 1)
3223  print_usage ();
3224 
3225  return ovl (args(0).is_sq_string ());
3226 }
3227 
3228 /*
3229 %!assert (is_sq_string ('foo'), true)
3230 %!assert (is_sq_string ("foo"), false)
3231 %!assert (is_sq_string (1.0), false)
3232 %!assert (is_sq_string ({2.0}), false)
3233 
3234 %!error is_sq_string ()
3235 %!error is_sq_string ('foo', 2)
3236 */
3237 
3238 DEFUN (is_dq_string, args, ,
3239  doc: /* -*- texinfo -*-
3240 @deftypefn {} {} is_dq_string (@var{x})
3241 Return true if @var{x} is a double-quoted character string.
3242 @seealso{is_sq_string, ischar}
3243 @end deftypefn */)
3244 {
3245  if (args.length () != 1)
3246  print_usage ();
3247 
3248  return ovl (args(0).is_dq_string ());
3249 }
3250 
3251 /*
3252 %!assert (is_dq_string ("foo"), true)
3253 %!assert (is_dq_string ('foo'), false)
3254 %!assert (is_dq_string (1.0), false)
3255 %!assert (is_dq_string ({2.0}), false)
3256 
3257 %!error is_dq_string ()
3258 %!error is_dq_string ("foo", 2)
3259 */
3260 
3261 DEFUN (disable_permutation_matrix, args, nargout,
3262  doc: /* -*- texinfo -*-
3263 @deftypefn {} {@var{val} =} disable_permutation_matrix ()
3264 @deftypefnx {} {@var{old_val} =} disable_permutation_matrix (@var{new_val})
3265 @deftypefnx {} {} disable_permutation_matrix (@var{new_val}, "local")
3266 Query or set the internal variable that controls whether permutation
3267 matrices are stored in a special space-efficient format.
3268 
3269 The default value is true. If this option is disabled Octave will store
3270 permutation matrices as full matrices.
3271 
3272 When called from inside a function with the @qcode{"local"} option, the
3273 variable is changed locally for the function and any subroutines it calls.
3274 The original variable value is restored when exiting the function.
3275 @seealso{disable_range, disable_diagonal_matrix}
3276 @end deftypefn */)
3277 {
3278  return SET_INTERNAL_VARIABLE (disable_permutation_matrix);
3279 }
3280 
3281 /*
3282 %!function p = __test_dpm__ (dpm)
3283 %! disable_permutation_matrix (dpm, "local");
3284 %! [~, ~, p] = lu ([1,2;3,4]);
3285 %!endfunction
3286 
3287 %!assert (typeinfo (__test_dpm__ (false)), "permutation matrix")
3288 %!assert (typeinfo (__test_dpm__ (true)), "matrix")
3289 */
3290 
3291 DEFUN (disable_diagonal_matrix, args, nargout,
3292  doc: /* -*- texinfo -*-
3293 @deftypefn {} {@var{val} =} disable_diagonal_matrix ()
3294 @deftypefnx {} {@var{old_val} =} disable_diagonal_matrix (@var{new_val})
3295 @deftypefnx {} {} disable_diagonal_matrix (@var{new_val}, "local")
3296 Query or set the internal variable that controls whether diagonal
3297 matrices are stored in a special space-efficient format.
3298 
3299 The default value is true. If this option is disabled Octave will store
3300 diagonal matrices as full matrices.
3301 
3302 When called from inside a function with the @qcode{"local"} option, the
3303 variable is changed locally for the function and any subroutines it calls.
3304 The original variable value is restored when exiting the function.
3305 @seealso{disable_range, disable_permutation_matrix}
3306 @end deftypefn */)
3307 {
3308  return SET_INTERNAL_VARIABLE (disable_diagonal_matrix);
3309 }
3310 
3311 /*
3312 %!function [x, xi, fx, fxi] = __test_ddm__ (ddm)
3313 %! disable_diagonal_matrix (ddm, "local");
3314 %! x = eye (2);
3315 %! xi = x*i;
3316 %! fx = single (x);
3317 %! fxi = single (xi);
3318 %!endfunction
3319 
3320 %!shared x, xi, fx, fxi
3321 %! [x, xi, fx, fxi] = __test_ddm__ (false);
3322 %!assert (typeinfo (x), "diagonal matrix")
3323 %!assert (typeinfo (xi), "complex diagonal matrix")
3324 %!assert (typeinfo (fx), "float diagonal matrix")
3325 %!assert (typeinfo (fxi), "float complex diagonal matrix")
3326 
3327 %!shared x, xi, fx, fxi
3328 %! [x, xi, fx, fxi] = __test_ddm__ (true);
3329 %!assert (typeinfo (x), "matrix")
3330 %!assert (typeinfo (xi), "complex matrix")
3331 %!assert (typeinfo (fx), "float matrix")
3332 %!assert (typeinfo (fxi), "float complex matrix")
3333 */
3334 
3335 DEFUN (disable_range, args, nargout,
3336  doc: /* -*- texinfo -*-
3337 @deftypefn {} {@var{val} =} disable_range ()
3338 @deftypefnx {} {@var{old_val} =} disable_range (@var{new_val})
3339 @deftypefnx {} {} disable_range (@var{new_val}, "local")
3340 Query or set the internal variable that controls whether ranges are stored
3341 in a special space-efficient format.
3342 
3343 The default value is true. If this option is disabled Octave will store
3344 ranges as full matrices.
3345 
3346 When called from inside a function with the @qcode{"local"} option, the
3347 variable is changed locally for the function and any subroutines it calls.
3348 The original variable value is restored when exiting the function.
3349 @seealso{disable_diagonal_matrix, disable_permutation_matrix}
3350 @end deftypefn */)
3351 {
3352  return SET_INTERNAL_VARIABLE (disable_range);
3353 }
3354 
3355 /*
3356 %!function r = __test_dr__ (dr)
3357 %! disable_range (dr, "local");
3358 %! ## Constant folding will produce range for 1:13.
3359 %! base = 1;
3360 %! limit = 13;
3361 %! r = base:limit;
3362 %!endfunction
3363 
3364 %!assert (typeinfo (__test_dr__ (false)), "range")
3365 %!assert (typeinfo (__test_dr__ (true)), "matrix")
3366 */
uint32_t id
Definition: graphics.cc:12193
OCTINTERP_API octave_value_list feval(const std::string &name, const octave_value_list &args=octave_value_list(), int nargout=0)
Array< int > int_vector_value(bool req_int=false, bool frc_str_conv=false, bool frc_vec_conv=false) const
static void register_type(void)
Definition: ov-null-mat.cc:75
octave_base_value * clone(void) const
octave_value(void)
Definition: ov.h:174
Definition: Cell.h:37
octave_idx_type idx_type_value(bool req_int=false, bool frc_str_conv=false) const
virtual octave_fcn_handle * fcn_handle_value(bool silent=false)
Definition: ov-base.cc:907
octave_value(* binary_class_op_fcn)(const octave_value &, const octave_value &)
Definition: ov-typeinfo.h:50
bool contains(const std::string &name) const
Definition: oct-map.h:336
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:810
int int_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:793
bool is_uint32_type(void) const
Definition: ov.h:681
static OCTAVE_NORETURN void err_unary_op_conv(const std::string &on)
Definition: ov.cc:2609
assign_op
Definition: ov.h:136
idx_class_type idx_class(void) const
Definition: idx-vector.h:555
#define XVALUE_EXTRACTOR(TYPE, NAME, FCN)
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov.h:418
Array< double > vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
#define C(a, b)
Definition: Faddeeva.cc:246
octave_value & operator=(const octave_value &a)
Definition: ov.h:359
unary_op_fcn lookup_unary_op(octave_value::unary_op, int)
Definition: ov-typeinfo.cc:501
const octave_base_value const Array< octave_idx_type > & ra_idx
nd group nd example oindent but is performed more efficiently If only and it is a scalar
Definition: data.cc:5264
octave_value(* cat_op_fcn)(octave_base_value &, const octave_base_value &, const Array< octave_idx_type > &ra_idx)
Definition: ov-typeinfo.h:56
octave_map map_value(void) const
static void register_type(void)
Definition: ov-builtin.cc:41
static void register_type(void)
FloatComplexColumnVector float_complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
bool isempty(void) const
Definition: Array.h:565
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
static std::string binary_op_as_string(binary_op)
Definition: ov.cc:177
octave_value(* binary_op_fcn)(const octave_base_value &, const octave_base_value &)
Definition: ov-typeinfo.h:53
static bool Vdisable_range
Definition: ov.cc:107
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
octave_base_value * empty_clone(void) const
Definition: ov.h:317
idx subsref(val, idx) esult
Definition: ov.cc:3065
void install_types(octave::type_info &ti)
Definition: ov.cc:2894
static void register_type(void)
Definition: ov-float.cc:61
static assign_op binary_op_to_assign_op(binary_op)
Definition: ov.cc:443
static void register_type(void)
Definition: ov-lazy-idx.cc:33
FloatRowVector float_row_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
int64_t int64_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:812
static void register_type(void)
Definition: ov-re-diag.cc:40
for large enough k
Definition: lu.cc:617
Definition: Range.h:33
int32NDArray int32_array_value(void) const
Definition: ov.h:937
binary_op
Definition: ov.h:94
virtual int type_id(void) const
Definition: ov-base.h:876
virtual octave_base_value * clone(void) const
Definition: ov-base.h:238
octave_user_script * user_script_value(bool silent=false) const
binary_op_fcn lookup_binary_op(octave_value::binary_op, int, int)
Definition: ov-typeinfo.cc:522
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
void(* non_const_unary_op_fcn)(octave_base_value &)
Definition: ov-typeinfo.h:47
void error(const char *fmt,...)
Definition: error.cc:578
#define SET_INTERNAL_VARIABLE(NM)
Definition: variables.h:109
static std::string unary_op_fcn_name(unary_op)
Definition: ov.cc:152
STL namespace.
int write(octave::stream &os, int block_size, oct_data_conv::data_type output_type, int skip, octave::mach_info::float_format flt_fmt) const
static void register_type(void)
Definition: ov-usr-fcn.cc:237
octave_fcn_inline * fcn_inline_value(bool silent=false) const
static void register_type(void)
Definition: ov-cell.cc:143
void make_unique(void)
Definition: ov.h:328
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:442
void unconvert(idx_class_type &iclass, double &scalar, Range &range, Array< double > &array, Array< bool > &mask) const
Definition: idx-vector.cc:1226
static void register_type(void)
Definition: ov-struct.cc:1072
static binary_op assign_op_to_binary_op(assign_op)
Definition: ov.cc:397
octave::mach_info::float_format flt_fmt
Definition: load-save.cc:736
static void register_type(void)
virtual Cell cell_value(void) const
Definition: ov-base.cc:533
bool is_defined(void) const
Definition: ov.h:523
static std::string assign_op_as_string(assign_op)
Definition: ov.cc:348
static OCTAVE_NORETURN void err_unary_op_conversion_failed(const std::string &op, const std::string &tn)
Definition: ov.cc:2673
friend OCTINTERP_API octave_value do_binary_op(octave::type_info &ti, binary_op op, const octave_value &a, const octave_value &b)
static void register_type(void)
Definition: ov-str-mat.cc:60
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:997
static void register_type(void)
binary_class_op_fcn lookup_binary_class_op(octave_value::binary_op)
Definition: ov-typeinfo.cc:515
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
s
Definition: file-io.cc:2729
FloatNDArray float_array_value(bool frc_str_conv=false) const
Definition: ov.h:843
bool isobject(void) const
Definition: ov.h:608
virtual octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition: ov-base.cc:199
void print_info(std::ostream &os, const std::string &prefix="") const
Definition: ov.cc:2592
i e
Definition: data.cc:2591
static void register_type(void)
bool is_int16_type(void) const
Definition: ov.h:666
octave_value(* unary_op_fcn)(const octave_base_value &)
Definition: ov-typeinfo.h:45
binary_op op_eq_to_binary_op(assign_op op)
Definition: ov.cc:2818
octave_value arg
Definition: pr-output.cc:3244
octave_value & do_non_const_unary_op(unary_op op)
Definition: ov.cc:2681
virtual octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: ov-base.cc:238
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
octave_base_value * rep
The real representation.
Definition: ov.h:1505
Array< FloatComplex > float_complex_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
octave_value(* assign_op_fcn)(octave_base_value &, const octave_value_list &, const octave_base_value &)
Definition: ov-typeinfo.h:60
bool is_dq_string(void) const
Definition: ov.h:583
Array< T > reshape(octave_idx_type nr, octave_idx_type nc) const
Definition: Array.h:549
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
uint32NDArray uint32_array_value(void) const
Definition: ov.h:949
static double as_double(time_t sec, long usec)
Definition: oct-time.h:34
virtual octave_map map_value(void) const
Definition: ov-base.cc:819
static bool Vdisable_permutation_matrix
Definition: ov.cc:103
virtual octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition: ov-base.cc:304
assign_op_fcn lookup_assign_op(octave_value::assign_op, int, int)
Definition: ov-typeinfo.cc:551
static void register_type(void)
Definition: ov-bool.cc:57
octave_value storable_value(void) const
octave_value single_subsref(const std::string &type, const octave_value_list &idx)
static void register_type(void)
Definition: ov-cx-sparse.cc:56
bool is_equal(const octave_value &) const
virtual octave_fcn_inline * fcn_inline_value(bool silent=false)
Definition: ov-base.cc:916
static void register_type(void)
Definition: ov-perm.cc:479
then the function must return scalars which will be concatenated into the return array(s). If code
Definition: cellfun.cc:400
int16NDArray int16_array_value(void) const
Definition: ov.h:934
symbol_table & __get_symbol_table__(const std::string &who)
virtual octave_base_value * try_narrowing_conversion(void)
Definition: ov-base.h:275
static void register_type(void)
Definition: ov-str-mat.cc:58
ComplexRowVector complex_row_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
nd deftypefn *std::string name
Definition: sysdep.cc:647
octave_value & assign(assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
static void register_type(void)
Definition: ov-oncleanup.cc:36
octave_value do_unary_op(octave::type_info &ti, octave_value::unary_op op, const octave_value &v)
Definition: ov.cc:2615
virtual octave_user_function * user_function_value(bool silent=false)
Definition: ov-base.cc:880
F77_RET_T const F77_INT F77_CMPLX * A
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:997
static void register_type(void)
Definition: ov-cx-mat.cc:67
type_info & __get_type_info__(const std::string &who)
virtual octave_value_list list_value(void) const
Definition: ov-base.cc:925
cat_op_fcn lookup_cat_op(int, int)
Definition: ov-typeinfo.cc:544
static const octave_value instance
Definition: ov-null-mat.h:49
static void register_type(void)
Definition: ov-struct.cc:53
static void register_type(void)
Definition: ov-scalar.cc:64
void error_with_cfn(const char *fmt,...)
Definition: error.cc:608
octave_base_value::type_conv_info numeric_demotion_function(void) const
Definition: ov.h:378
octave_idx_type columns(void) const
Definition: ov.h:474
bool is_uint64_type(void) const
Definition: ov.h:684
OCTINTERP_API octave_value do_binary_op(octave::type_info &ti, octave_value::binary_op op, const octave_value &a, const octave_value &b)
static void register_type(void)
Definition: ov-re-mat.cc:86
virtual float_display_format get_edit_display_format(void) const
Definition: ov-base.cc:447
void maybe_economize(void)
Definition: ov.h:1233
static std::string binary_op_fcn_name(binary_op)
Definition: ov.cc:244
static void register_type(void)
Definition: ov-re-sparse.cc:55
dim_vector dims(void) const
Definition: ov.h:469
static void register_type(void)
Definition: ov-null-mat.cc:32
bool isinteger(void) const
Definition: ov.h:687
static void register_type(void)
void resize(const dim_vector &dv, const T &rfv)
Resizing (with fill).
Definition: Array.cc:1010
ComplexColumnVector complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
octave_idx_type rows(void) const
Definition: ov.h:472
double tmp
Definition: data.cc:6252
idx subs
Definition: ov.cc:3065
octave_classdef * classdef_object_value(bool silent=false) const
#define panic_impossible()
Definition: error.h:40
uint64NDArray uint64_array_value(void) const
Definition: ov.h:952
RowVector row_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
static void register_type(void)
static int static_type_id(void)
Definition: ov-classdef.h:1548
Array< octave_idx_type > octave_idx_type_vector_value(bool req_int=false, bool frc_str_conv=false, bool frc_vec_conv=false) const
octave_function * function_value(bool silent=false) const
const Cell & contents(const_iterator p) const
Definition: oct-map.h:317
octave_user_function * user_function_value(bool silent=false) const
bool is_zero_by_zero(void) const
Definition: ov.h:483
assign_op unary_op_to_assign_op(unary_op op)
Definition: ov.cc:2799
idx type
Definition: ov.cc:3114
std::string class_name(void) const
Definition: ov.h:1291
int type_id(void) const
Definition: ov.h:1287
static void register_type(void)
Definition: ov-base.cc:97
octave_value find_method(const std::string &name, const std::string &dispatch_type)
Definition: symtab.h:200
Definition: dMatrix.h:36
bool is_int8_type(void) const
Definition: ov.h:663
virtual octave_user_code * user_code_value(bool silent=false)
Definition: ov-base.cc:898
octave_idx_type get_count(void) const
Definition: ov.h:373
FloatColumnVector float_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
octave_idx_type numel(void) const
Definition: oct-map.h:375
static void register_type(void)
Definition: ov-complex.cc:62
FloatComplexNDArray float_complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:863
void make_storable_value(void)
static void register_type(void)
bool is_int32_type(void) const
Definition: ov.h:669
FloatComplexRowVector float_complex_row_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
virtual type_conv_info numeric_conversion_function(void) const
Definition: ov-base.h:251
T & xelem(octave_idx_type n)
Definition: Array.h:458
static octave_base_value * nil_rep(void)
Definition: ov.cc:114
octave_idx_type nfields(void) const
Definition: oct-map.h:330
octave_base_value::type_conv_info numeric_conversion_function(void) const
Definition: ov.h:375
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
magic_colon
Definition: ov.h:172
octave_scalar_map scalar_map_value(void) const
static OCTAVE_NORETURN void err_unary_op(const std::string &on, const std::string &tn)
Definition: ov.cc:2602
Array< float > float_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
octave_value_list list_value(void) const
octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
octave_user_code * user_code_value(bool silent=false) const
octave_fcn_handle * fcn_handle_value(bool silent=false) const
const octave_char_matrix & v2
OCTINTERP_API octave_value do_cat_op(octave::type_info &ti, const octave_value &a, const octave_value &b, const Array< octave_idx_type > &ra_idx)
bool is_undefined(void) const
Definition: ov.h:526
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
virtual std::string class_name(void) const
Definition: ov-base.h:876
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:362
bool isnull(void) const
Definition: ov.h:628
virtual octave_classdef * classdef_object_value(bool silent=false)
Definition: ov-base.cc:861
void maybe_mutate(void)
unary_class_op_fcn lookup_unary_class_op(octave_value::unary_op)
Definition: ov-typeinfo.cc:494
uint16NDArray uint16_array_value(void) const
Definition: ov.h:946
p
Definition: lu.cc:138
int register_type(const std::string &t_name, const std::string &c_name, const octave_value &val)
Definition: ov-typeinfo.cc:762
bool is_int64_type(void) const
Definition: ov.h:672
static bool Vdisable_diagonal_matrix
Definition: ov.cc:99
ColumnVector column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:338
float_display_format get_edit_display_format(void) const
idx subsasgn(val, idx, 0) esult
Definition: ov.cc:3114
compound_binary_op
Definition: ov.h:119
octave_idx_type length(void) const
Definition: ovl.h:96
int64NDArray int64_array_value(void) const
Definition: ov.h:940
friend OCTINTERP_API octave_value do_unary_op(octave::type_info &ti, unary_op op, const octave_value &a)
Definition: ov.cc:2615
int8NDArray int8_array_value(void) const
Definition: ov.h:931
virtual std::string type_name(void) const
Definition: ov-base.h:876
b
Definition: cellfun.cc:400
static void register_type(void)
Definition: ov-cs-list.cc:39
virtual int write(octave::stream &os, int block_size, oct_data_conv::data_type output_type, int skip, octave::mach_info::float_format flt_fmt) const
Definition: ov-base.cc:968
octave_map xmap_value(const char *fmt,...) const
octave::refcount< octave_idx_type > count
Definition: ov-base.h:862
octave_value(* unary_class_op_fcn)(const octave_value &)
Definition: ov-typeinfo.h:43
for i
Definition: data.cc:5264
static void decode_subscripts(const char *name, const octave_value &arg, std::string &type_string, std::list< octave_value_list > &idx)
Definition: ov.cc:2973
bool is_string(void) const
Definition: ov.h:577
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
bool is_double_type(void) const
Definition: ov.h:648
void maybe_economize(void)
Definition: Array.h:690
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:295
std::complex< double > Complex
Definition: oct-cmplx.h:31
virtual void print_info(std::ostream &os, const std::string &prefix) const
Definition: ov-base.cc:453
OCTAVE_EXPORT octave_value_list or cell arrays Arguments are concatenated vertically The returned values are padded with blanks as needed to make each row of the string array have the same length Empty input strings are significant and will concatenated in the output For numerical each element is converted to the corresponding ASCII character A range error results if an input is outside the ASCII range(0-255). For cell arrays
virtual octave_function * function_value(bool silent=false)
Definition: ov-base.cc:871
non_const_unary_op_fcn lookup_non_const_unary_op(octave_value::unary_op, int)
Definition: ov-typeinfo.cc:508
static std::string unary_op_as_string(unary_op)
Definition: ov.cc:121
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
octave_idx_type length(void) const
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:859
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
static void register_type(void)
Definition: ov-colon.cc:35
bool is_uint8_type(void) const
Definition: ov.h:675
unary_op
Definition: ov.h:81
static void register_type(void)
Definition: ov-dld-fcn.cc:40
std::string type_name(void) const
Definition: ov.h:1289
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
virtual octave_user_script * user_script_value(bool silent=false)
Definition: ov-base.cc:889
static int static_type_id(void)
Definition: ov-class.h:211
dim_vector dv
Definition: sub2ind.cc:263
OCTINTERP_API octave_value do_colon_op(const octave_value &base, const octave_value &limit, bool is_for_cmd_expr=false)
Definition: ov.h:1315
octave_base_value *(* type_conv_fcn)(const octave_base_value &)
Definition: ov-base.h:207
static void register_type(void)
Definition: ov-null-mat.cc:53
octave_value next_subsref(const std::string &type, const std::list< octave_value_list > &idx, size_t skip=1)
octave::stream os
Definition: file-io.cc:627
Cell cell_value(void) const
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:840
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:834
more on
Definition: toplev.cc:236
uint8NDArray uint8_array_value(void) const
Definition: ov.h:943
static octave_value empty_conv(const std::string &type, const octave_value &rhs=octave_value())
Definition: ov.cc:2867
virtual octave_base_value * empty_clone(void) const
Definition: ov-base.cc:104
static void register_type(void)
Definition: ov-range.cc:61
static void register_type(void)
Definition: ov-cx-diag.cc:41
int ndims(void) const
Definition: Array.h:590
Array< Complex > complex_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
virtual octave_scalar_map scalar_map_value(void) const
Definition: ov-base.cc:825
bool is_uint16_type(void) const
Definition: ov.h:678
static void register_type(void)
Definition: ov-bool-mat.cc:68