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