3Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008, 2009 John W. Eaton
6This file is part of Octave.
8Octave is free software; you can redistribute it and/or modify it
9under the terms of the GNU General Public License as published by the
10Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
13Octave is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18You should have received a copy of the GNU General Public License
19along with Octave; see the file COPYING. If not, see
20<http://www.gnu.org/licenses/>.
33#include "oct-stream.h"
37#include "ov-bool-mat.h"
42#include "ov-flt-re-mat.h"
43#include "ov-re-diag.h"
44#include "ov-flt-re-diag.h"
46#include "ov-bool-sparse.h"
47#include "ov-cx-sparse.h"
48#include "ov-re-sparse.h"
57#include "ov-complex.h"
58#include "ov-flt-complex.h"
60#include "ov-flt-cx-mat.h"
61#include "ov-cx-diag.h"
62#include "ov-flt-cx-diag.h"
64#include "ov-str-mat.h"
68#include "ov-cs-list.h"
70#include "ov-builtin.h"
71#include "ov-dld-fcn.h"
72#include "ov-usr-fcn.h"
73#include "ov-fcn-handle.h"
74#include "ov-fcn-inline.h"
75#include "ov-typeinfo.h"
76#include "ov-null-mat.h"
88// We are likely to have a lot of octave_value objects to allocate, so
89// make the grow_size large.
90DEFINE_OCTAVE_ALLOCATOR2(octave_value, 1024);
94// Octave's value type.
97octave_value::unary_op_as_string (unary_op op)
132 retval = "<unknown>";
139octave_value::unary_op_fcn_name (unary_op op)
158 retval = "transpose";
162 retval = "ctranspose";
173octave_value::binary_op_as_string (binary_op op)
264 retval = "<unknown>";
271octave_value::binary_op_fcn_name (binary_op op)
357octave_value::binary_op_fcn_name (compound_binary_op op)
364 retval = "transtimes";
368 retval = "timestrans";
372 retval = "hermtimes";
376 retval = "timesherm";
380 retval = "transldiv";
411octave_value::assign_op_as_string (assign_op op)
478 retval = "<unknown>";
484octave_value::assign_op
485octave_value::binary_op_to_assign_op (binary_op op)
504 retval = op_el_mul_eq;
507 retval = op_el_div_eq;
510 retval = op_el_and_eq;
513 retval = op_el_or_eq;
516 retval = unknown_assign_op;
522octave_value::octave_value (short int i)
523 : rep (new octave_scalar (i))
527octave_value::octave_value (unsigned short int i)
528 : rep (new octave_scalar (i))
532octave_value::octave_value (int i)
533 : rep (new octave_scalar (i))
537octave_value::octave_value (unsigned int i)
538 : rep (new octave_scalar (i))
542octave_value::octave_value (long int i)
543 : rep (new octave_scalar (i))
547octave_value::octave_value (unsigned long int i)
548 : rep (new octave_scalar (i))
552#if defined (HAVE_LONG_LONG_INT)
553octave_value::octave_value (long long int i)
554 : rep (new octave_scalar (i))
559#if defined (HAVE_UNSIGNED_LONG_LONG_INT)
560octave_value::octave_value (unsigned long long int i)
561 : rep (new octave_scalar (i))
566octave_value::octave_value (octave_time t)
567 : rep (new octave_scalar (t.double_value ()))
571octave_value::octave_value (double d)
572 : rep (new octave_scalar (d))
576octave_value::octave_value (float d)
577 : rep (new octave_float_scalar (d))
581octave_value::octave_value (const Cell& c, bool is_csl)
583 ? dynamic_cast<octave_base_value *> (new octave_cs_list (c))
584 : dynamic_cast<octave_base_value *> (new octave_cell (c)))
588octave_value::octave_value (const Array<octave_value>& a, bool is_csl)
590 ? dynamic_cast<octave_base_value *> (new octave_cs_list (Cell (a)))
591 : dynamic_cast<octave_base_value *> (new octave_cell (Cell (a))))
595octave_value::octave_value (const Matrix& m, const MatrixType& t)
596 : rep (new octave_matrix (m, t))
601octave_value::octave_value (const FloatMatrix& m, const MatrixType& t)
602 : rep (new octave_float_matrix (m, t))
607octave_value::octave_value (const NDArray& a)
608 : rep (new octave_matrix (a))
613octave_value::octave_value (const FloatNDArray& a)
614 : rep (new octave_float_matrix (a))
619octave_value::octave_value (const Array<double>& a)
620 : rep (new octave_matrix (a))
625octave_value::octave_value (const Array<float>& a)
626 : rep (new octave_float_matrix (a))
631octave_value::octave_value (const DiagMatrix& d)
632 : rep (new octave_diag_matrix (d))
637octave_value::octave_value (const FloatDiagMatrix& d)
638 : rep (new octave_float_diag_matrix (d))
643octave_value::octave_value (const RowVector& v)
644 : rep (new octave_matrix (v))
649octave_value::octave_value (const FloatRowVector& v)
650 : rep (new octave_float_matrix (v))
655octave_value::octave_value (const ColumnVector& v)
656 : rep (new octave_matrix (v))
661octave_value::octave_value (const FloatColumnVector& v)
662 : rep (new octave_float_matrix (v))
667octave_value::octave_value (const Complex& C)
668 : rep (new octave_complex (C))
673octave_value::octave_value (const FloatComplex& C)
674 : rep (new octave_float_complex (C))
679octave_value::octave_value (const ComplexMatrix& m, const MatrixType& t)
680 : rep (new octave_complex_matrix (m, t))
685octave_value::octave_value (const FloatComplexMatrix& m, const MatrixType& t)
686 : rep (new octave_float_complex_matrix (m, t))
691octave_value::octave_value (const ComplexNDArray& a)
692 : rep (new octave_complex_matrix (a))
697octave_value::octave_value (const FloatComplexNDArray& a)
698 : rep (new octave_float_complex_matrix (a))
703octave_value::octave_value (const Array<Complex>& a)
704 : rep (new octave_complex_matrix (a))
709octave_value::octave_value (const Array<FloatComplex>& a)
710 : rep (new octave_float_complex_matrix (a))
715octave_value::octave_value (const ComplexDiagMatrix& d)
716 : rep (new octave_complex_diag_matrix (d))
721octave_value::octave_value (const FloatComplexDiagMatrix& d)
722 : rep (new octave_float_complex_diag_matrix (d))
727octave_value::octave_value (const ComplexRowVector& v)
728 : rep (new octave_complex_matrix (v))
733octave_value::octave_value (const FloatComplexRowVector& v)
734 : rep (new octave_float_complex_matrix (v))
739octave_value::octave_value (const ComplexColumnVector& v)
740 : rep (new octave_complex_matrix (v))
745octave_value::octave_value (const FloatComplexColumnVector& v)
746 : rep (new octave_float_complex_matrix (v))
751octave_value::octave_value (const PermMatrix& p)
752 : rep (new octave_perm_matrix (p))
757octave_value::octave_value (bool b)
758 : rep (new octave_bool (b))
762octave_value::octave_value (const boolMatrix& bm, const MatrixType& t)
763 : rep (new octave_bool_matrix (bm, t))
768octave_value::octave_value (const boolNDArray& bnda)
769 : rep (new octave_bool_matrix (bnda))
774octave_value::octave_value (const Array<bool>& bnda)
775 : rep (new octave_bool_matrix (bnda))
780octave_value::octave_value (char c, char type)
782 ? new octave_char_matrix_dq_str (c)
783 : new octave_char_matrix_sq_str (c))
788octave_value::octave_value (const char *s, char type)
790 ? new octave_char_matrix_dq_str (s)
791 : new octave_char_matrix_sq_str (s))
796octave_value::octave_value (const std::string& s, char type)
798 ? new octave_char_matrix_dq_str (s)
799 : new octave_char_matrix_sq_str (s))
804octave_value::octave_value (const string_vector& s, char type)
806 ? new octave_char_matrix_dq_str (s)
807 : new octave_char_matrix_sq_str (s))
812octave_value::octave_value (const charMatrix& chm, char type)
814 ? new octave_char_matrix_dq_str (chm)
815 : new octave_char_matrix_sq_str (chm))
820octave_value::octave_value (const charNDArray& chm, char type)
822 ? new octave_char_matrix_dq_str (chm)
823 : new octave_char_matrix_sq_str (chm))
828octave_value::octave_value (const Array<char>& chm, char type)
830 ? new octave_char_matrix_dq_str (chm)
831 : new octave_char_matrix_sq_str (chm))
836octave_value::octave_value (const charMatrix& chm, bool, char type)
838 ? new octave_char_matrix_dq_str (chm)
839 : new octave_char_matrix_sq_str (chm))
844octave_value::octave_value (const charNDArray& chm, bool, char type)
846 ? new octave_char_matrix_dq_str (chm)
847 : new octave_char_matrix_sq_str (chm))
852octave_value::octave_value (const Array<char>& chm, bool, char type)
854 ? new octave_char_matrix_dq_str (chm)
855 : new octave_char_matrix_sq_str (chm))
860octave_value::octave_value (const SparseMatrix& m, const MatrixType &t)
861 : rep (new octave_sparse_matrix (m, t))
866octave_value::octave_value (const Sparse<double>& m, const MatrixType &t)
867 : rep (new octave_sparse_matrix (m, t))
872octave_value::octave_value (const SparseComplexMatrix& m, const MatrixType &t)
873 : rep (new octave_sparse_complex_matrix (m, t))
878octave_value::octave_value (const Sparse<Complex>& m, const MatrixType &t)
879 : rep (new octave_sparse_complex_matrix (m, t))
884octave_value::octave_value (const SparseBoolMatrix& bm, const MatrixType &t)
885 : rep (new octave_sparse_bool_matrix (bm, t))
890octave_value::octave_value (const Sparse<bool>& bm, const MatrixType &t)
891 : rep (new octave_sparse_bool_matrix (bm, t))
896octave_value::octave_value (const octave_int8& i)
897 : rep (new octave_int8_scalar (i))
902octave_value::octave_value (const octave_uint8& i)
903 : rep (new octave_uint8_scalar (i))
908octave_value::octave_value (const octave_int16& i)
909 : rep (new octave_int16_scalar (i))
914octave_value::octave_value (const octave_uint16& i)
915 : rep (new octave_uint16_scalar (i))
920octave_value::octave_value (const octave_int32& i)
921 : rep (new octave_int32_scalar (i))
926octave_value::octave_value (const octave_uint32& i)
927 : rep (new octave_uint32_scalar (i))
932octave_value::octave_value (const octave_int64& i)
933 : rep (new octave_int64_scalar (i))
938octave_value::octave_value (const octave_uint64& i)
939 : rep (new octave_uint64_scalar (i))
944octave_value::octave_value (const int8NDArray& inda)
945 : rep (new octave_int8_matrix (inda))
950octave_value::octave_value (const Array<octave_int8>& inda)
951 : rep (new octave_int8_matrix (inda))
956octave_value::octave_value (const uint8NDArray& inda)
957 : rep (new octave_uint8_matrix (inda))
962octave_value::octave_value (const Array<octave_uint8>& inda)
963 : rep (new octave_uint8_matrix (inda))
968octave_value::octave_value (const int16NDArray& inda)
969 : rep (new octave_int16_matrix (inda))
974octave_value::octave_value (const Array<octave_int16>& inda)
975 : rep (new octave_int16_matrix (inda))
980octave_value::octave_value (const uint16NDArray& inda)
981 : rep (new octave_uint16_matrix (inda))
986octave_value::octave_value (const Array<octave_uint16>& inda)
987 : rep (new octave_uint16_matrix (inda))
992octave_value::octave_value (const int32NDArray& inda)
993 : rep (new octave_int32_matrix (inda))
998octave_value::octave_value (const Array<octave_int32>& inda)
999 : rep (new octave_int32_matrix (inda))
1004octave_value::octave_value (const uint32NDArray& inda)
1005 : rep (new octave_uint32_matrix (inda))
1010octave_value::octave_value (const Array<octave_uint32>& inda)
1011 : rep (new octave_uint32_matrix (inda))
1016octave_value::octave_value (const int64NDArray& inda)
1017 : rep (new octave_int64_matrix (inda))
1022octave_value::octave_value (const Array<octave_int64>& inda)
1023 : rep (new octave_int64_matrix (inda))
1028octave_value::octave_value (const uint64NDArray& inda)
1029 : rep (new octave_uint64_matrix (inda))
1034octave_value::octave_value (const Array<octave_uint64>& inda)
1035 : rep (new octave_uint64_matrix (inda))
1040octave_value::octave_value (const Array<octave_idx_type>& inda, bool zero_based,
1042 : rep (new octave_matrix (inda, zero_based, cache_index))
1047octave_value::octave_value (const idx_vector& idx)
1054 idx_vector::idx_class_type idx_class;
1056 idx.unconvert (idx_class, scalar, range, array, mask);
1060 case idx_vector::class_colon:
1061 rep = new octave_magic_colon ();
1063 case idx_vector::class_range:
1064 rep = new octave_range (range, idx);
1066 case idx_vector::class_scalar:
1067 rep = new octave_scalar (scalar);
1069 case idx_vector::class_vector:
1070 rep = new octave_matrix (array, idx);
1072 case idx_vector::class_mask:
1073 rep = new octave_bool_matrix (mask, idx);
1084octave_value::octave_value (const Array<std::string>& cellstr)
1085 : rep (new octave_cell (cellstr))
1090octave_value::octave_value (double base, double limit, double inc)
1091 : rep (new octave_range (base, limit, inc))
1096octave_value::octave_value (const Range& r)
1097 : rep (new octave_range (r))
1102octave_value::octave_value (const Octave_map& m)
1103 : rep (new octave_struct (m))
1107octave_value::octave_value (const Octave_map& m, const std::string& id)
1108 : rep (new octave_class (m, id))
1112octave_value::octave_value (const octave_value_list& l, bool)
1113 : rep (new octave_cs_list (l))
1117octave_value::octave_value (octave_value::magic_colon)
1118 : rep (new octave_magic_colon ())
1122octave_value::octave_value (octave_base_value *new_rep, bool borrow)
1129octave_value::octave_value (octave_base_value *new_rep, int xcount)
1132 rep->count = xcount;
1136octave_value::clone (void) const
1138 panic_impossible ();
1143octave_value::maybe_mutate (void)
1145 octave_base_value *tmp = rep->try_narrowing_conversion ();
1147 if (tmp && tmp != rep)
1149 if (--rep->count == 0)
1157octave_value::single_subsref (const std::string& type,
1158 const octave_value_list& idx)
1160 std::list<octave_value_list> i;
1164 return rep->subsref (type, i);
1168octave_value::subsref (const std::string& type,
1169 const std::list<octave_value_list>& idx, int nargout)
1172 return rep->subsref (type, idx);
1174 return rep->subsref (type, idx, nargout);
1178octave_value::next_subsref (const std::string& type,
1179 const std::list<octave_value_list>& idx,
1182 if (! error_state && idx.size () > skip)
1184 std::list<octave_value_list> new_idx (idx);
1185 for (size_t i = 0; i < skip; i++)
1186 new_idx.erase (new_idx.begin ());
1187 return subsref (type.substr (skip), new_idx);
1194octave_value::next_subsref (int nargout, const std::string& type,
1195 const std::list<octave_value_list>& idx,
1198 if (! error_state && idx.size () > skip)
1200 std::list<octave_value_list> new_idx (idx);
1201 for (size_t i = 0; i < skip; i++)
1202 new_idx.erase (new_idx.begin ());
1203 return subsref (type.substr (skip), new_idx, nargout);
1210octave_value::next_subsref (bool auto_add, const std::string& type,
1211 const std::list<octave_value_list>& idx,
1214 if (! error_state && idx.size () > skip)
1216 std::list<octave_value_list> new_idx (idx);
1217 for (size_t i = 0; i < skip; i++)
1218 new_idx.erase (new_idx.begin ());
1219 return subsref (type.substr (skip), new_idx, auto_add);
1226octave_value::do_multi_index_op (int nargout, const octave_value_list& idx)
1228 return rep->do_multi_index_op (nargout, idx);
1233gripe_assign_failed (const std::string& on, const std::string& tn1,
1234 const std::string& tn2)
1236 error ("assignment failed for `%s %s %s'",
1237 tn1.c_str (), on.c_str (), tn2.c_str ());
1242gripe_assign_failed_or_no_method (const std::string& on,
1243 const std::string& tn1,
1244 const std::string& tn2)
1246 error ("assignment failed, or no method for `%s %s %s'",
1247 tn1.c_str (), on.c_str (), tn2.c_str ());
1251octave_value::subsasgn (const std::string& type,
1252 const std::list<octave_value_list>& idx,
1253 const octave_value& rhs)
1255 return rep->subsasgn (type, idx, rhs);
1259octave_value::assign (assign_op op, const std::string& type,
1260 const std::list<octave_value_list>& idx,
1261 const octave_value& rhs)
1263 octave_value retval;
1267 octave_value t_rhs = rhs;
1269 if (op != op_asn_eq)
1271 octave_value t = subsref (type, idx);
1275 binary_op binop = op_eq_to_binary_op (op);
1278 t_rhs = do_binary_op (binop, t, rhs);
1284 if (type[0] == '.' && ! (is_map () || is_object ()))
1286 octave_value tmp = Octave_map ();
1287 retval = tmp.subsasgn (type, idx, t_rhs);
1290 retval = subsasgn (type, idx, t_rhs);
1293 gripe_assign_failed_or_no_method (assign_op_as_string (op_asn_eq),
1294 type_name (), rhs.type_name ());
1301octave_value::assign (assign_op op, const octave_value& rhs)
1303 if (op == op_asn_eq)
1304 // Regularize a null matrix if stored into a variable.
1305 operator = (rhs.storable_value ());
1308 octave_value_typeinfo::assign_op_fcn f = 0;
1310 // Only attempt to operate in-place if this variable is unshared.
1311 if (rep->count == 1)
1313 int tthis = this->type_id ();
1314 int trhs = rhs.type_id ();
1316 f = octave_value_typeinfo::lookup_assign_op (op, tthis, trhs);
1323 f (*rep, octave_value_list (), *rhs.rep);
1324 maybe_mutate (); // Usually unnecessary, but may be needed (complex arrays).
1326 catch (octave_execution_exception)
1328 gripe_library_execution_error ();
1334 binary_op binop = op_eq_to_binary_op (op);
1338 octave_value t = do_binary_op (binop, *this, rhs);
1350octave_value::length (void) const
1354 dim_vector dv = dims ();
1356 for (int i = 0; i < dv.length (); i++)
1378octave_value::is_equal (const octave_value& test) const
1380 bool retval = false;
1382 // If there is no op_eq for these types, we can't compare values.
1384 if (rows () == test.rows () && columns () == test.columns ())
1386 octave_value tmp = do_binary_op (octave_value::op_eq, *this, test);
1388 // Empty array also means a match.
1389 if (! error_state && tmp.is_defined ())
1390 retval = tmp.is_true () || tmp.is_empty ();
1397octave_value::cell_value (void) const
1399 return rep->cell_value ();
1402// Define the idx_type_value function here instead of in ov.h to avoid
1403// needing definitions for the SIZEOF_X macros in ov.h.
1406octave_value::idx_type_value (bool req_int, bool frc_str_conv) const
1408#if SIZEOF_OCTAVE_IDX_TYPE == SIZEOF_LONG
1409 return long_value (req_int, frc_str_conv);
1410#elif SIZEOF_OCTAVE_IDX_TYPE == SIZEOF_INT
1411 return int_value (req_int, frc_str_conv);
1413#error "no octave_value extractor for octave_idx_type"
1418octave_value::map_value (void) const
1420 return rep->map_value ();
1424octave_value::function_value (bool silent) const
1426 return rep->function_value (silent);
1429octave_user_function *
1430octave_value::user_function_value (bool silent) const
1432 return rep->user_function_value (silent);
1436octave_value::user_script_value (bool silent) const
1438 return rep->user_script_value (silent);
1442octave_value::user_code_value (bool silent) const
1444 return rep->user_code_value (silent);
1448octave_value::fcn_handle_value (bool silent) const
1450 return rep->fcn_handle_value (silent);
1454octave_value::fcn_inline_value (bool silent) const
1456 return rep->fcn_inline_value (silent);
1460octave_value::list_value (void) const
1462 return rep->list_value ();
1466make_vector_dims (const dim_vector& dv, bool force_vector_conversion,
1467 const std::string& my_type, const std::string& wanted_type)
1469 dim_vector retval (dv);
1470 retval.chop_trailing_singletons ();
1471 octave_idx_type nel = dv.numel ();
1473 if (retval.length () > 2 || (retval(0) != 1 && retval(1) != 1))
1475 if (!force_vector_conversion)
1476 gripe_implicit_conversion ("Octave:array-as-vector",
1477 my_type.c_str (), wanted_type.c_str ());
1478 retval = dim_vector (nel);
1485octave_value::column_vector_value (bool force_string_conv,
1486 bool frc_vec_conv) const
1488 return ColumnVector (vector_value (force_string_conv,
1493octave_value::complex_column_vector_value (bool force_string_conv,
1494 bool frc_vec_conv) const
1496 return ComplexColumnVector (complex_vector_value (force_string_conv,
1501octave_value::row_vector_value (bool force_string_conv,
1502 bool frc_vec_conv) const
1504 return RowVector (vector_value (force_string_conv,
1509octave_value::complex_row_vector_value (bool force_string_conv,
1510 bool frc_vec_conv) const
1512 return ComplexRowVector (complex_vector_value (force_string_conv,
1517octave_value::vector_value (bool force_string_conv,
1518 bool force_vector_conversion) const
1520 Array<double> retval = array_value (force_string_conv);
1525 return retval.reshape (make_vector_dims (retval.dims (),
1526 force_vector_conversion,
1527 type_name (), "real vector"));
1532convert_to_int_array (const Array<octave_int<T> >& A)
1534 Array<int> retval (A.dims ());
1535 octave_idx_type n = A.numel ();
1537 octave_int<int>::clear_conv_flag ();
1538 for (octave_idx_type i = 0; i < n; i++)
1539 retval.xelem (i) = octave_int<int> (A.xelem (i));
1541 if (octave_int<int>::get_trunc_flag ())
1542 gripe_truncated_conversion (octave_int<T>::type_name (), "int");
1544 octave_int<int>::clear_conv_flag ();
1550octave_value::int_vector_value (bool force_string_conv, bool require_int,
1551 bool force_vector_conversion) const
1555 if (is_integer_type ())
1557 if (is_int32_type ())
1558 retval = convert_to_int_array (int32_array_value ());
1559 else if (is_int64_type ())
1560 retval = convert_to_int_array (int64_array_value ());
1561 else if (is_int16_type ())
1562 retval = convert_to_int_array (int16_array_value ());
1563 else if (is_int8_type ())
1564 retval = convert_to_int_array (int8_array_value ());
1565 else if (is_uint32_type ())
1566 retval = convert_to_int_array (uint32_array_value ());
1567 else if (is_uint64_type ())
1568 retval = convert_to_int_array (uint64_array_value ());
1569 else if (is_uint16_type ())
1570 retval = convert_to_int_array (uint16_array_value ());
1571 else if (is_uint8_type ())
1572 retval = convert_to_int_array (uint8_array_value ());
1574 retval = array_value (force_string_conv);
1578 const NDArray a = array_value (force_string_conv);
1583 retval.resize (a.dims ());
1584 for (octave_idx_type i = 0; i < a.numel (); i++)
1586 double ai = a.elem (i);
1587 int v = static_cast<int> (ai);
1589 retval.xelem (i) = v;
1592 error_with_cfn ("conversion to integer value failed");
1598 retval = Array<int> (a);
1606 return retval.reshape (make_vector_dims (retval.dims (),
1607 force_vector_conversion,
1608 type_name (), "integer vector"));
1612static Array<octave_idx_type>
1613convert_to_octave_idx_type_array (const Array<octave_int<T> >& A)
1615 Array<octave_idx_type> retval (A.dims ());
1616 octave_idx_type n = A.numel ();
1618 octave_int<int>::clear_conv_flag ();
1619 for (octave_idx_type i = 0; i < n; i++)
1620 retval.xelem (i) = octave_int<octave_idx_type> (A.xelem (i));
1622 if (octave_int<int>::get_trunc_flag ())
1623 gripe_truncated_conversion (octave_int<T>::type_name (), "int");
1625 octave_int<int>::clear_conv_flag ();
1630Array<octave_idx_type>
1631octave_value::octave_idx_type_vector_value (bool require_int,
1632 bool force_string_conv,
1633 bool force_vector_conversion) const
1635 Array<octave_idx_type> retval;
1637 if (is_integer_type ())
1639 if (is_int32_type ())
1640 retval = convert_to_octave_idx_type_array (int32_array_value ());
1641 else if (is_int64_type ())
1642 retval = convert_to_octave_idx_type_array (int64_array_value ());
1643 else if (is_int16_type ())
1644 retval = convert_to_octave_idx_type_array (int16_array_value ());
1645 else if (is_int8_type ())
1646 retval = convert_to_octave_idx_type_array (int8_array_value ());
1647 else if (is_uint32_type ())
1648 retval = convert_to_octave_idx_type_array (uint32_array_value ());
1649 else if (is_uint64_type ())
1650 retval = convert_to_octave_idx_type_array (uint64_array_value ());
1651 else if (is_uint16_type ())
1652 retval = convert_to_octave_idx_type_array (uint16_array_value ());
1653 else if (is_uint8_type ())
1654 retval = convert_to_octave_idx_type_array (uint8_array_value ());
1656 retval = array_value (force_string_conv);
1660 const NDArray a = array_value (force_string_conv);
1665 retval.resize (a.dims ());
1666 for (octave_idx_type i = 0; i < a.numel (); i++)
1668 double ai = a.elem (i);
1669 octave_idx_type v = static_cast<octave_idx_type> (ai);
1671 retval.xelem (i) = v;
1674 error_with_cfn ("conversion to integer value failed");
1680 retval = Array<octave_idx_type> (a);
1688 return retval.reshape (make_vector_dims (retval.dims (),
1689 force_vector_conversion,
1690 type_name (), "integer vector"));
1694octave_value::complex_vector_value (bool force_string_conv,
1695 bool force_vector_conversion) const
1697 Array<Complex> retval = complex_array_value (force_string_conv);
1702 return retval.reshape (make_vector_dims (retval.dims (),
1703 force_vector_conversion,
1704 type_name (), "complex vector"));
1708octave_value::float_column_vector_value (bool force_string_conv,
1709 bool frc_vec_conv) const
1711 return FloatColumnVector (float_vector_value (force_string_conv,
1715FloatComplexColumnVector
1716octave_value::float_complex_column_vector_value (bool force_string_conv,
1717 bool frc_vec_conv) const
1719 return FloatComplexColumnVector (float_complex_vector_value (force_string_conv,
1724octave_value::float_row_vector_value (bool force_string_conv,
1725 bool frc_vec_conv) const
1727 return FloatRowVector (float_vector_value (force_string_conv,
1731FloatComplexRowVector
1732octave_value::float_complex_row_vector_value (bool force_string_conv,
1733 bool frc_vec_conv) const
1735 return FloatComplexRowVector (float_complex_vector_value (force_string_conv,
1740octave_value::float_vector_value (bool force_string_conv,
1741 bool force_vector_conversion) const
1743 Array<float> retval = float_array_value (force_string_conv);
1748 return retval.reshape (make_vector_dims (retval.dims (),
1749 force_vector_conversion,
1750 type_name (), "real vector"));
1754octave_value::float_complex_vector_value (bool force_string_conv,
1755 bool force_vector_conversion) const
1757 Array<FloatComplex> retval = float_complex_array_value (force_string_conv);
1762 return retval.reshape (make_vector_dims (retval.dims (),
1763 force_vector_conversion,
1764 type_name (), "complex vector"));
1768octave_value::storable_value (void) const
1770 octave_value retval = *this;
1771 if (is_null_value ())
1772 retval = octave_value (rep->empty_clone ());
1774 retval.maybe_economize ();
1780octave_value::make_storable_value (void)
1782 if (is_null_value ())
1784 octave_base_value *rc = rep->empty_clone ();
1785 if (--rep->count == 0)
1794octave_value::write (octave_stream& os, int block_size,
1795 oct_data_conv::data_type output_type, int skip,
1796 oct_mach_info::float_format flt_fmt) const
1798 return rep->write (os, block_size, output_type, skip, flt_fmt);
1802gripe_binary_op (const std::string& on, const std::string& tn1,
1803 const std::string& tn2)
1805 error ("binary operator `%s' not implemented for `%s' by `%s' operations",
1806 on.c_str (), tn1.c_str (), tn2.c_str ());
1810gripe_binary_op_conv (const std::string& on)
1812 error ("type conversion failed for binary operator `%s'", on.c_str ());
1816do_binary_op (octave_value::binary_op op,
1817 const octave_value& v1, const octave_value& v2)
1819 octave_value retval;
1821 int t1 = v1.type_id ();
1822 int t2 = v2.type_id ();
1824 if (t1 == octave_class::static_type_id ()
1825 || t2 == octave_class::static_type_id ())
1827 octave_value_typeinfo::binary_class_op_fcn f
1828 = octave_value_typeinfo::lookup_binary_class_op (op);
1834 retval = f (v1, v2);
1836 catch (octave_execution_exception)
1838 gripe_library_execution_error ();
1842 gripe_binary_op (octave_value::binary_op_as_string (op),
1843 v1.class_name (), v2.class_name ());
1847 // FIXME -- we need to handle overloading operators for built-in
1848 // classes (double, char, int8, etc.)
1850 octave_value_typeinfo::binary_op_fcn f
1851 = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
1857 retval = f (*v1.rep, *v2.rep);
1859 catch (octave_execution_exception)
1861 gripe_library_execution_error ();
1867 octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
1870 octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
1872 // Try biased (one-sided) conversions first.
1873 if (cf2.type_id () >= 0 &&
1874 octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
1876 else if (cf1.type_id () >= 0 &&
1877 octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
1882 octave_base_value *tmp = cf1 (*v1.rep);
1886 tv1 = octave_value (tmp);
1887 t1 = tv1.type_id ();
1891 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
1900 octave_base_value *tmp = cf2 (*v2.rep);
1904 tv2 = octave_value (tmp);
1905 t2 = tv2.type_id ();
1909 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
1918 retval = do_binary_op (op, tv1, tv2);
1922 //demote double -> single and try again
1923 cf1 = tv1.numeric_demotion_function ();
1925 cf2 = tv2.numeric_demotion_function ();
1927 // Try biased (one-sided) conversions first.
1928 if (cf2.type_id () >= 0
1929 && octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
1931 else if (cf1.type_id () >= 0
1932 && octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
1937 octave_base_value *tmp = cf1 (*tv1.rep);
1941 tv1 = octave_value (tmp);
1942 t1 = tv1.type_id ();
1946 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
1953 octave_base_value *tmp = cf2 (*tv2.rep);
1957 tv2 = octave_value (tmp);
1958 t2 = tv2.type_id ();
1962 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
1969 f = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
1975 retval = f (*tv1.rep, *tv2.rep);
1977 catch (octave_execution_exception)
1979 gripe_library_execution_error ();
1983 gripe_binary_op (octave_value::binary_op_as_string (op),
1984 v1.type_name (), v2.type_name ());
1987 gripe_binary_op (octave_value::binary_op_as_string (op),
1988 v1.type_name (), v2.type_name ());
1997decompose_binary_op (octave_value::compound_binary_op op,
1998 const octave_value& v1, const octave_value& v2)
2000 octave_value retval;
2004 case octave_value::op_trans_mul:
2005 retval = do_binary_op (octave_value::op_mul,
2006 do_unary_op (octave_value::op_transpose, v1),
2009 case octave_value::op_mul_trans:
2010 retval = do_binary_op (octave_value::op_mul,
2012 do_unary_op (octave_value::op_transpose, v2));
2014 case octave_value::op_herm_mul:
2015 retval = do_binary_op (octave_value::op_mul,
2016 do_unary_op (octave_value::op_hermitian, v1),
2019 case octave_value::op_mul_herm:
2020 retval = do_binary_op (octave_value::op_mul,
2022 do_unary_op (octave_value::op_hermitian, v2));
2024 case octave_value::op_trans_ldiv:
2025 retval = do_binary_op (octave_value::op_ldiv,
2026 do_unary_op (octave_value::op_transpose, v1),
2029 case octave_value::op_herm_ldiv:
2030 retval = do_binary_op (octave_value::op_ldiv,
2031 do_unary_op (octave_value::op_hermitian, v1),
2034 case octave_value::op_el_not_and:
2035 retval = do_binary_op (octave_value::op_el_and,
2036 do_unary_op (octave_value::op_not, v1),
2039 case octave_value::op_el_not_or:
2040 retval = do_binary_op (octave_value::op_el_or,
2041 do_unary_op (octave_value::op_not, v1),
2044 case octave_value::op_el_and_not:
2045 retval = do_binary_op (octave_value::op_el_and,
2047 do_unary_op (octave_value::op_not, v2));
2049 case octave_value::op_el_or_not:
2050 retval = do_binary_op (octave_value::op_el_or,
2052 do_unary_op (octave_value::op_not, v2));
2055 error ("invalid compound operator");
2063do_binary_op (octave_value::compound_binary_op op,
2064 const octave_value& v1, const octave_value& v2)
2066 octave_value retval;
2068 int t1 = v1.type_id ();
2069 int t2 = v2.type_id ();
2071 if (t1 == octave_class::static_type_id ()
2072 || t2 == octave_class::static_type_id ())
2074 octave_value_typeinfo::binary_class_op_fcn f
2075 = octave_value_typeinfo::lookup_binary_class_op (op);
2081 retval = f (v1, v2);
2083 catch (octave_execution_exception)
2085 gripe_library_execution_error ();
2089 retval = decompose_binary_op (op, v1, v2);
2093 octave_value_typeinfo::binary_op_fcn f
2094 = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
2100 retval = f (*v1.rep, *v2.rep);
2102 catch (octave_execution_exception)
2104 gripe_library_execution_error ();
2108 retval = decompose_binary_op (op, v1, v2);
2115gripe_cat_op (const std::string& tn1, const std::string& tn2)
2117 error ("concatenation operator not implemented for `%s' by `%s' operations",
2118 tn1.c_str (), tn2.c_str ());
2122gripe_cat_op_conv (void)
2124 error ("type conversion failed for concatenation operator");
2128do_cat_op (const octave_value& v1, const octave_value& v2,
2129 const Array<octave_idx_type>& ra_idx)
2131 octave_value retval;
2133 // Can't rapid return for concatenation with an empty object here as
2134 // something like cat(1,[],single([]) must return the correct type.
2136 int t1 = v1.type_id ();
2137 int t2 = v2.type_id ();
2139 octave_value_typeinfo::cat_op_fcn f
2140 = octave_value_typeinfo::lookup_cat_op (t1, t2);
2146 retval = f (*v1.rep, *v2.rep, ra_idx);
2148 catch (octave_execution_exception)
2150 gripe_library_execution_error ();
2156 octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
2159 octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
2161 // Try biased (one-sided) conversions first.
2162 if (cf2.type_id () >= 0
2163 && octave_value_typeinfo::lookup_cat_op (t1, cf2.type_id ()))
2165 else if (cf1.type_id () >= 0
2166 && octave_value_typeinfo::lookup_cat_op (cf1.type_id (), t2))
2171 octave_base_value *tmp = cf1 (*v1.rep);
2175 tv1 = octave_value (tmp);
2176 t1 = tv1.type_id ();
2180 gripe_cat_op_conv ();
2189 octave_base_value *tmp = cf2 (*v2.rep);
2193 tv2 = octave_value (tmp);
2194 t2 = tv2.type_id ();
2198 gripe_cat_op_conv ();
2207 retval = do_cat_op (tv1, tv2, ra_idx);
2210 gripe_cat_op (v1.type_name (), v2.type_name ());
2217octave_value::print_info (std::ostream& os, const std::string& prefix) const
2219 os << prefix << "type_name: " << type_name () << "\n"
2220 << prefix << "count: " << get_count () << "\n"
2221 << prefix << "rep info: ";
2223 rep->print_info (os, prefix + " ");
2227gripe_unary_op (const std::string& on, const std::string& tn)
2229 error ("unary operator `%s' not implemented for `%s' operands",
2230 on.c_str (), tn.c_str ());
2234gripe_unary_op_conv (const std::string& on)
2236 error ("type conversion failed for unary operator `%s'", on.c_str ());
2240do_unary_op (octave_value::unary_op op, const octave_value& v)
2242 octave_value retval;
2244 int t = v.type_id ();
2246 if (t == octave_class::static_type_id ())
2248 octave_value_typeinfo::unary_class_op_fcn f
2249 = octave_value_typeinfo::lookup_unary_class_op (op);
2257 catch (octave_execution_exception)
2259 gripe_library_execution_error ();
2263 gripe_unary_op (octave_value::unary_op_as_string (op),
2268 // FIXME -- we need to handle overloading operators for built-in
2269 // classes (double, char, int8, etc.)
2271 octave_value_typeinfo::unary_op_fcn f
2272 = octave_value_typeinfo::lookup_unary_op (op, t);
2278 retval = f (*v.rep);
2280 catch (octave_execution_exception)
2282 gripe_library_execution_error ();
2288 octave_base_value::type_conv_fcn cf
2289 = v.numeric_conversion_function ();
2293 octave_base_value *tmp = cf (*v.rep);
2297 tv = octave_value (tmp);
2298 retval = do_unary_op (op, tv);
2301 gripe_unary_op_conv (octave_value::unary_op_as_string (op));
2304 gripe_unary_op (octave_value::unary_op_as_string (op),
2313gripe_unary_op_conversion_failed (const std::string& op,
2314 const std::string& tn)
2316 error ("operator %s: type conversion for `%s' failed",
2317 op.c_str (), tn.c_str ());
2321octave_value::do_non_const_unary_op (unary_op op)
2323 if (op == op_incr || op == op_decr)
2328 octave_value_typeinfo::non_const_unary_op_fcn f
2329 = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
2339 catch (octave_execution_exception)
2341 gripe_library_execution_error ();
2346 octave_base_value::type_conv_fcn cf = numeric_conversion_function ();
2350 octave_base_value *tmp = cf (*rep);
2354 octave_base_value *old_rep = rep;
2359 f = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
2367 catch (octave_execution_exception)
2369 gripe_library_execution_error ();
2372 if (old_rep && --old_rep->count == 0)
2379 if (--rep->count == 0)
2385 gripe_unary_op (octave_value::unary_op_as_string (op),
2390 gripe_unary_op_conversion_failed
2391 (octave_value::unary_op_as_string (op), type_name ());
2394 gripe_unary_op (octave_value::unary_op_as_string (op), type_name ());
2402 octave_value_typeinfo::non_const_unary_op_fcn f = 0;
2404 // Only attempt to operate in-place if this variable is unshared.
2405 if (rep->count == 1)
2406 f = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
2414 catch (octave_execution_exception)
2416 gripe_library_execution_error ();
2420 *this = do_unary_op (op, *this);
2428gripe_unary_op_failed_or_no_method (const std::string& on,
2429 const std::string& tn)
2431 error ("operator %s: no method, or unable to evaluate for %s operand",
2432 on.c_str (), tn.c_str ());
2437octave_value::do_non_const_unary_op (unary_op, const octave_value_list&)
2443octave_value::do_non_const_unary_op (unary_op op, const std::string& type,
2444 const std::list<octave_value_list>& idx)
2446 octave_value retval;
2450 do_non_const_unary_op (op);
2456 // FIXME -- only do the following stuff if we can't find a
2457 // specific function to call to handle the op= operation for the
2460 assign_op assop = unary_op_to_assign_op (op);
2462 retval = assign (assop, type, idx, 1.0);
2468octave_value::assign_op
2469octave_value::unary_op_to_assign_op (unary_op op)
2471 assign_op binop = unknown_assign_op;
2485 std::string on = unary_op_as_string (op);
2486 error ("operator %s: no assign operator found", on.c_str ());
2493octave_value::binary_op
2494octave_value::op_eq_to_binary_op (assign_op op)
2496 binary_op binop = unknown_binary_op;
2558 std::string on = assign_op_as_string (op);
2559 error ("operator %s: no binary operator found", on.c_str ());
2567octave_value::empty_conv (const std::string& type, const octave_value& rhs)
2569 octave_value retval;
2571 if (type.length () > 0)
2577 if (type.length () > 1 && type[1] == '.')
2578 retval = Octave_map ();
2580 retval = octave_value (rhs.empty_clone ());
2589 retval = Octave_map ();
2593 panic_impossible ();
2597 retval = octave_value (rhs.empty_clone ());
2605 octave_base_value::register_type ();
2606 octave_cell::register_type ();
2607 octave_scalar::register_type ();
2608 octave_complex::register_type ();
2609 octave_matrix::register_type ();
2610 octave_diag_matrix::register_type ();
2611 octave_complex_matrix::register_type ();
2612 octave_complex_diag_matrix::register_type ();
2613 octave_range::register_type ();
2614 octave_bool::register_type ();
2615 octave_bool_matrix::register_type ();
2616 octave_char_matrix_str::register_type ();
2617 octave_char_matrix_sq_str::register_type ();
2618 octave_int8_scalar::register_type ();
2619 octave_int16_scalar::register_type ();
2620 octave_int32_scalar::register_type ();
2621 octave_int64_scalar::register_type ();
2622 octave_uint8_scalar::register_type ();
2623 octave_uint16_scalar::register_type ();
2624 octave_uint32_scalar::register_type ();
2625 octave_uint64_scalar::register_type ();
2626 octave_int8_matrix::register_type ();
2627 octave_int16_matrix::register_type ();
2628 octave_int32_matrix::register_type ();
2629 octave_int64_matrix::register_type ();
2630 octave_uint8_matrix::register_type ();
2631 octave_uint16_matrix::register_type ();
2632 octave_uint32_matrix::register_type ();
2633 octave_uint64_matrix::register_type ();
2634 octave_sparse_bool_matrix::register_type ();
2635 octave_sparse_matrix::register_type ();
2636 octave_sparse_complex_matrix::register_type ();
2637 octave_struct::register_type ();
2638 octave_class::register_type ();
2639 octave_cs_list::register_type ();
2640 octave_magic_colon::register_type ();
2641 octave_builtin::register_type ();
2642 octave_user_function::register_type ();
2643 octave_dld_function::register_type ();
2644 octave_fcn_handle::register_type ();
2645 octave_fcn_inline::register_type ();
2646 octave_float_scalar::register_type ();
2647 octave_float_complex::register_type ();
2648 octave_float_matrix::register_type ();
2649 octave_float_diag_matrix::register_type ();
2650 octave_float_complex_matrix::register_type ();
2651 octave_float_complex_diag_matrix::register_type ();
2652 octave_perm_matrix::register_type ();
2653 octave_null_matrix::register_type ();
2654 octave_null_str::register_type ();
2655 octave_null_sq_str::register_type ();
2661@deftypefn {Built-in Function} {} cast (@var{val}, @var{type})\n\
2662Convert @var{val} to the new data type @var{type}.\n\
2663@seealso{class, typeinfo}\n\
2666 octave_value retval;
2668 if (args.length () == 2)
2669 error ("cast: not implemented");
2677DEFUN (sizeof, args, ,
2679@deftypefn {Built-in Function} {} sizeof (@var{val})\n\
2680Return the size of @var{val} in bytes\n\
2683 octave_value retval;
2685 if (args.length () == 1)
2686 retval = args(0).byte_size ();
2693DEFUN (subsref, args, nargout,
2695@deftypefn {Built-in Function} {} subsref (@var{val}, @var{idx})\n\
2696Perform the subscripted element selection operation according to\n\
2697the subscript specified by @var{idx}.\n\
2699The subscript @var{idx} is expected to be a structure array with\n\
2700fields @samp{type} and @samp{subs}. Valid values for @samp{type}\n\
2701are @samp{\"()\"}, @samp{\"@{@}\"}, and @samp{\".\"}.\n\
2702The @samp{subs} field may be either @samp{\":\"} or a cell array\n\
2705The following example shows how to extract the two first columns of\n\
2711 @result{} val = [ 8 1 6\n\
2714idx.type = \"()\";\n\
2715idx.subs = @{\":\", 1:2@};\n\
2724Note that this is the same as writing @code{val(:,1:2)}.\n\
2725@seealso{subsasgn, substruct}\n\
2728 octave_value_list retval;
2730 if (args.length () == 2)
2733 std::list<octave_value_list> idx;
2735 decode_subscripts ("subsref", args(1), type, idx);
2739 octave_value tmp = args(0);
2740 retval = tmp.subsref (type, idx, nargout);
2749DEFUN (subsasgn, args, ,
2751@deftypefn {Built-in Function} {} subsasgn (@var{val}, @var{idx}, @var{rhs})\n\
2752Perform the subscripted assignment operation according to\n\
2753the subscript specified by @var{idx}.\n\
2755The subscript @var{idx} is expected to be a structure array with\n\
2756fields @samp{type} and @samp{subs}. Valid values for @samp{type}\n\
2757are @samp{\"()\"}, @samp{\"@{@}\"}, and @samp{\".\"}.\n\
2758The @samp{subs} field may be either @samp{\":\"} or a cell array\n\
2761The following example shows how to set the two first columns of a\n\
27623-by-3 matrix to zero.\n\
2767idx.type = \"()\";\n\
2768idx.subs = @{\":\", 1:2@};\n\
2769subsasgn (val, idx, 0)\n\
2770 @result{} [ 0 0 6\n\
2776Note that this is the same as writing @code{val(:,1:2) = 0}.\n\
2777@seealso{subsref, substruct}\n\
2780 octave_value retval;
2782 if (args.length () == 3)
2785 std::list<octave_value_list> idx;
2787 decode_subscripts ("subsasgn", args(1), type, idx);
2789 octave_value arg0 = args(0);
2791 arg0.make_unique ();
2794 retval = arg0.subsasgn (type, idx, args(2));