00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include "data-conv.h"
00029 #include "quit.h"
00030 #include "str-vec.h"
00031
00032 #include "oct-obj.h"
00033 #include "oct-stream.h"
00034 #include "ov.h"
00035 #include "ov-base.h"
00036 #include "ov-bool.h"
00037 #include "ov-bool-mat.h"
00038 #include "ov-cell.h"
00039 #include "ov-scalar.h"
00040 #include "ov-float.h"
00041 #include "ov-re-mat.h"
00042 #include "ov-flt-re-mat.h"
00043 #include "ov-re-diag.h"
00044 #include "ov-flt-re-diag.h"
00045 #include "ov-perm.h"
00046 #include "ov-bool-sparse.h"
00047 #include "ov-cx-sparse.h"
00048 #include "ov-re-sparse.h"
00049 #include "ov-int8.h"
00050 #include "ov-int16.h"
00051 #include "ov-int32.h"
00052 #include "ov-int64.h"
00053 #include "ov-uint8.h"
00054 #include "ov-uint16.h"
00055 #include "ov-uint32.h"
00056 #include "ov-uint64.h"
00057 #include "ov-complex.h"
00058 #include "ov-flt-complex.h"
00059 #include "ov-cx-mat.h"
00060 #include "ov-flt-cx-mat.h"
00061 #include "ov-cx-diag.h"
00062 #include "ov-flt-cx-diag.h"
00063 #include "ov-ch-mat.h"
00064 #include "ov-str-mat.h"
00065 #include "ov-range.h"
00066 #include "ov-struct.h"
00067 #include "ov-class.h"
00068 #include "ov-oncleanup.h"
00069 #include "ov-cs-list.h"
00070 #include "ov-colon.h"
00071 #include "ov-builtin.h"
00072 #include "ov-dld-fcn.h"
00073 #include "ov-usr-fcn.h"
00074 #include "ov-fcn-handle.h"
00075 #include "ov-fcn-inline.h"
00076 #include "ov-typeinfo.h"
00077 #include "ov-null-mat.h"
00078 #include "ov-lazy-idx.h"
00079
00080 #include "defun.h"
00081 #include "error.h"
00082 #include "gripes.h"
00083 #include "pager.h"
00084 #include "parse.h"
00085 #include "pr-output.h"
00086 #include "symtab.h"
00087 #include "utils.h"
00088 #include "variables.h"
00089
00090
00091
00092 DEFINE_OCTAVE_ALLOCATOR2(octave_value, 1024);
00093
00094
00095
00096
00097
00098 std::string
00099 octave_value::unary_op_as_string (unary_op op)
00100 {
00101 std::string retval;
00102
00103 switch (op)
00104 {
00105 case op_not:
00106 retval = "!";
00107 break;
00108
00109 case op_uplus:
00110 retval = "+";
00111 break;
00112
00113 case op_uminus:
00114 retval = "-";
00115 break;
00116
00117 case op_transpose:
00118 retval = ".'";
00119 break;
00120
00121 case op_hermitian:
00122 retval = "'";
00123 break;
00124
00125 case op_incr:
00126 retval = "++";
00127 break;
00128
00129 case op_decr:
00130 retval = "--";
00131 break;
00132
00133 default:
00134 retval = "<unknown>";
00135 }
00136
00137 return retval;
00138 }
00139
00140 std::string
00141 octave_value::unary_op_fcn_name (unary_op op)
00142 {
00143 std::string retval;
00144
00145 switch (op)
00146 {
00147 case op_not:
00148 retval = "not";
00149 break;
00150
00151 case op_uplus:
00152 retval = "uplus";
00153 break;
00154
00155 case op_uminus:
00156 retval = "uminus";
00157 break;
00158
00159 case op_transpose:
00160 retval = "transpose";
00161 break;
00162
00163 case op_hermitian:
00164 retval = "ctranspose";
00165 break;
00166
00167 default:
00168 break;
00169 }
00170
00171 return retval;
00172 }
00173
00174 std::string
00175 octave_value::binary_op_as_string (binary_op op)
00176 {
00177 std::string retval;
00178
00179 switch (op)
00180 {
00181 case op_add:
00182 retval = "+";
00183 break;
00184
00185 case op_sub:
00186 retval = "-";
00187 break;
00188
00189 case op_mul:
00190 retval = "*";
00191 break;
00192
00193 case op_div:
00194 retval = "/";
00195 break;
00196
00197 case op_pow:
00198 retval = "^";
00199 break;
00200
00201 case op_ldiv:
00202 retval = "\\";
00203 break;
00204
00205 case op_lshift:
00206 retval = "<<";
00207 break;
00208
00209 case op_rshift:
00210 retval = ">>";
00211 break;
00212
00213 case op_lt:
00214 retval = "<";
00215 break;
00216
00217 case op_le:
00218 retval = "<=";
00219 break;
00220
00221 case op_eq:
00222 retval = "==";
00223 break;
00224
00225 case op_ge:
00226 retval = ">=";
00227 break;
00228
00229 case op_gt:
00230 retval = ">";
00231 break;
00232
00233 case op_ne:
00234 retval = "!=";
00235 break;
00236
00237 case op_el_mul:
00238 retval = ".*";
00239 break;
00240
00241 case op_el_div:
00242 retval = "./";
00243 break;
00244
00245 case op_el_pow:
00246 retval = ".^";
00247 break;
00248
00249 case op_el_ldiv:
00250 retval = ".\\";
00251 break;
00252
00253 case op_el_and:
00254 retval = "&";
00255 break;
00256
00257 case op_el_or:
00258 retval = "|";
00259 break;
00260
00261 case op_struct_ref:
00262 retval = ".";
00263 break;
00264
00265 default:
00266 retval = "<unknown>";
00267 }
00268
00269 return retval;
00270 }
00271
00272 std::string
00273 octave_value::binary_op_fcn_name (binary_op op)
00274 {
00275 std::string retval;
00276
00277 switch (op)
00278 {
00279 case op_add:
00280 retval = "plus";
00281 break;
00282
00283 case op_sub:
00284 retval = "minus";
00285 break;
00286
00287 case op_mul:
00288 retval = "mtimes";
00289 break;
00290
00291 case op_div:
00292 retval = "mrdivide";
00293 break;
00294
00295 case op_pow:
00296 retval = "mpower";
00297 break;
00298
00299 case op_ldiv:
00300 retval = "mldivide";
00301 break;
00302
00303 case op_lt:
00304 retval = "lt";
00305 break;
00306
00307 case op_le:
00308 retval = "le";
00309 break;
00310
00311 case op_eq:
00312 retval = "eq";
00313 break;
00314
00315 case op_ge:
00316 retval = "ge";
00317 break;
00318
00319 case op_gt:
00320 retval = "gt";
00321 break;
00322
00323 case op_ne:
00324 retval = "ne";
00325 break;
00326
00327 case op_el_mul:
00328 retval = "times";
00329 break;
00330
00331 case op_el_div:
00332 retval = "rdivide";
00333 break;
00334
00335 case op_el_pow:
00336 retval = "power";
00337 break;
00338
00339 case op_el_ldiv:
00340 retval = "ldivide";
00341 break;
00342
00343 case op_el_and:
00344 retval = "and";
00345 break;
00346
00347 case op_el_or:
00348 retval = "or";
00349 break;
00350
00351 default:
00352 break;
00353 }
00354
00355 return retval;
00356 }
00357
00358 std::string
00359 octave_value::binary_op_fcn_name (compound_binary_op op)
00360 {
00361 std::string retval;
00362
00363 switch (op)
00364 {
00365 case op_trans_mul:
00366 retval = "transtimes";
00367 break;
00368
00369 case op_mul_trans:
00370 retval = "timestrans";
00371 break;
00372
00373 case op_herm_mul:
00374 retval = "hermtimes";
00375 break;
00376
00377 case op_mul_herm:
00378 retval = "timesherm";
00379 break;
00380
00381 case op_trans_ldiv:
00382 retval = "transldiv";
00383 break;
00384
00385 case op_herm_ldiv:
00386 retval = "hermldiv";
00387 break;
00388
00389 case op_el_and_not:
00390 retval = "andnot";
00391 break;
00392
00393 case op_el_or_not:
00394 retval = "ornot";
00395 break;
00396
00397 case op_el_not_and:
00398 retval = "notand";
00399 break;
00400
00401 case op_el_not_or:
00402 retval = "notor";
00403 break;
00404
00405 default:
00406 break;
00407 }
00408
00409 return retval;
00410 }
00411
00412 std::string
00413 octave_value::assign_op_as_string (assign_op op)
00414 {
00415 std::string retval;
00416
00417 switch (op)
00418 {
00419 case op_asn_eq:
00420 retval = "=";
00421 break;
00422
00423 case op_add_eq:
00424 retval = "+=";
00425 break;
00426
00427 case op_sub_eq:
00428 retval = "-=";
00429 break;
00430
00431 case op_mul_eq:
00432 retval = "*=";
00433 break;
00434
00435 case op_div_eq:
00436 retval = "/=";
00437 break;
00438
00439 case op_ldiv_eq:
00440 retval = "\\=";
00441 break;
00442
00443 case op_pow_eq:
00444 retval = "^=";
00445 break;
00446
00447 case op_lshift_eq:
00448 retval = "<<=";
00449 break;
00450
00451 case op_rshift_eq:
00452 retval = ">>=";
00453 break;
00454
00455 case op_el_mul_eq:
00456 retval = ".*=";
00457 break;
00458
00459 case op_el_div_eq:
00460 retval = "./=";
00461 break;
00462
00463 case op_el_ldiv_eq:
00464 retval = ".\\=";
00465 break;
00466
00467 case op_el_pow_eq:
00468 retval = ".^=";
00469 break;
00470
00471 case op_el_and_eq:
00472 retval = "&=";
00473 break;
00474
00475 case op_el_or_eq:
00476 retval = "|=";
00477 break;
00478
00479 default:
00480 retval = "<unknown>";
00481 }
00482
00483 return retval;
00484 }
00485
00486 octave_value::assign_op
00487 octave_value::binary_op_to_assign_op (binary_op op)
00488 {
00489 assign_op retval;
00490
00491 switch (op)
00492 {
00493 case op_add:
00494 retval = op_add_eq;
00495 break;
00496 case op_sub:
00497 retval = op_sub_eq;
00498 break;
00499 case op_mul:
00500 retval = op_mul_eq;
00501 break;
00502 case op_div:
00503 retval = op_div_eq;
00504 break;
00505 case op_el_mul:
00506 retval = op_el_mul_eq;
00507 break;
00508 case op_el_div:
00509 retval = op_el_div_eq;
00510 break;
00511 case op_el_and:
00512 retval = op_el_and_eq;
00513 break;
00514 case op_el_or:
00515 retval = op_el_or_eq;
00516 break;
00517 default:
00518 retval = unknown_assign_op;
00519 }
00520
00521 return retval;
00522 }
00523
00524 octave_value::octave_value (short int i)
00525 : rep (new octave_scalar (i))
00526 {
00527 }
00528
00529 octave_value::octave_value (unsigned short int i)
00530 : rep (new octave_scalar (i))
00531 {
00532 }
00533
00534 octave_value::octave_value (int i)
00535 : rep (new octave_scalar (i))
00536 {
00537 }
00538
00539 octave_value::octave_value (unsigned int i)
00540 : rep (new octave_scalar (i))
00541 {
00542 }
00543
00544 octave_value::octave_value (long int i)
00545 : rep (new octave_scalar (i))
00546 {
00547 }
00548
00549 octave_value::octave_value (unsigned long int i)
00550 : rep (new octave_scalar (i))
00551 {
00552 }
00553
00554 #if defined (HAVE_LONG_LONG_INT)
00555 octave_value::octave_value (long long int i)
00556 : rep (new octave_scalar (i))
00557 {
00558 }
00559 #endif
00560
00561 #if defined (HAVE_UNSIGNED_LONG_LONG_INT)
00562 octave_value::octave_value (unsigned long long int i)
00563 : rep (new octave_scalar (i))
00564 {
00565 }
00566 #endif
00567
00568 octave_value::octave_value (octave_time t)
00569 : rep (new octave_scalar (t.double_value ()))
00570 {
00571 }
00572
00573 octave_value::octave_value (double d)
00574 : rep (new octave_scalar (d))
00575 {
00576 }
00577
00578 octave_value::octave_value (float d)
00579 : rep (new octave_float_scalar (d))
00580 {
00581 }
00582
00583 octave_value::octave_value (const Cell& c, bool is_csl)
00584 : rep (is_csl
00585 ? dynamic_cast<octave_base_value *> (new octave_cs_list (c))
00586 : dynamic_cast<octave_base_value *> (new octave_cell (c)))
00587 {
00588 }
00589
00590 octave_value::octave_value (const Array<octave_value>& a, bool is_csl)
00591 : rep (is_csl
00592 ? dynamic_cast<octave_base_value *> (new octave_cs_list (Cell (a)))
00593 : dynamic_cast<octave_base_value *> (new octave_cell (Cell (a))))
00594 {
00595 }
00596
00597 octave_value::octave_value (const Matrix& m, const MatrixType& t)
00598 : rep (new octave_matrix (m, t))
00599 {
00600 maybe_mutate ();
00601 }
00602
00603 octave_value::octave_value (const FloatMatrix& m, const MatrixType& t)
00604 : rep (new octave_float_matrix (m, t))
00605 {
00606 maybe_mutate ();
00607 }
00608
00609 octave_value::octave_value (const NDArray& a)
00610 : rep (new octave_matrix (a))
00611 {
00612 maybe_mutate ();
00613 }
00614
00615 octave_value::octave_value (const FloatNDArray& a)
00616 : rep (new octave_float_matrix (a))
00617 {
00618 maybe_mutate ();
00619 }
00620
00621 octave_value::octave_value (const Array<double>& a)
00622 : rep (new octave_matrix (a))
00623 {
00624 maybe_mutate ();
00625 }
00626
00627 octave_value::octave_value (const Array<float>& a)
00628 : rep (new octave_float_matrix (a))
00629 {
00630 maybe_mutate ();
00631 }
00632
00633 octave_value::octave_value (const DiagArray2<double>& d)
00634 : rep (new octave_diag_matrix (d))
00635 {
00636 maybe_mutate ();
00637 }
00638
00639 octave_value::octave_value (const DiagArray2<float>& d)
00640 : rep (new octave_float_diag_matrix (d))
00641 {
00642 maybe_mutate ();
00643 }
00644
00645 octave_value::octave_value (const DiagArray2<Complex>& d)
00646 : rep (new octave_complex_diag_matrix (d))
00647 {
00648 maybe_mutate ();
00649 }
00650
00651 octave_value::octave_value (const DiagArray2<FloatComplex>& d)
00652 : rep (new octave_float_complex_diag_matrix (d))
00653 {
00654 maybe_mutate ();
00655 }
00656
00657 octave_value::octave_value (const DiagMatrix& d)
00658 : rep (new octave_diag_matrix (d))
00659 {
00660 maybe_mutate ();
00661 }
00662
00663 octave_value::octave_value (const FloatDiagMatrix& d)
00664 : rep (new octave_float_diag_matrix (d))
00665 {
00666 maybe_mutate ();
00667 }
00668
00669 octave_value::octave_value (const RowVector& v)
00670 : rep (new octave_matrix (v))
00671 {
00672 maybe_mutate ();
00673 }
00674
00675 octave_value::octave_value (const FloatRowVector& v)
00676 : rep (new octave_float_matrix (v))
00677 {
00678 maybe_mutate ();
00679 }
00680
00681 octave_value::octave_value (const ColumnVector& v)
00682 : rep (new octave_matrix (v))
00683 {
00684 maybe_mutate ();
00685 }
00686
00687 octave_value::octave_value (const FloatColumnVector& v)
00688 : rep (new octave_float_matrix (v))
00689 {
00690 maybe_mutate ();
00691 }
00692
00693 octave_value::octave_value (const Complex& C)
00694 : rep (new octave_complex (C))
00695 {
00696 maybe_mutate ();
00697 }
00698
00699 octave_value::octave_value (const FloatComplex& C)
00700 : rep (new octave_float_complex (C))
00701 {
00702 maybe_mutate ();
00703 }
00704
00705 octave_value::octave_value (const ComplexMatrix& m, const MatrixType& t)
00706 : rep (new octave_complex_matrix (m, t))
00707 {
00708 maybe_mutate ();
00709 }
00710
00711 octave_value::octave_value (const FloatComplexMatrix& m, const MatrixType& t)
00712 : rep (new octave_float_complex_matrix (m, t))
00713 {
00714 maybe_mutate ();
00715 }
00716
00717 octave_value::octave_value (const ComplexNDArray& a)
00718 : rep (new octave_complex_matrix (a))
00719 {
00720 maybe_mutate ();
00721 }
00722
00723 octave_value::octave_value (const FloatComplexNDArray& a)
00724 : rep (new octave_float_complex_matrix (a))
00725 {
00726 maybe_mutate ();
00727 }
00728
00729 octave_value::octave_value (const Array<Complex>& a)
00730 : rep (new octave_complex_matrix (a))
00731 {
00732 maybe_mutate ();
00733 }
00734
00735 octave_value::octave_value (const Array<FloatComplex>& a)
00736 : rep (new octave_float_complex_matrix (a))
00737 {
00738 maybe_mutate ();
00739 }
00740
00741 octave_value::octave_value (const ComplexDiagMatrix& d)
00742 : rep (new octave_complex_diag_matrix (d))
00743 {
00744 maybe_mutate ();
00745 }
00746
00747 octave_value::octave_value (const FloatComplexDiagMatrix& d)
00748 : rep (new octave_float_complex_diag_matrix (d))
00749 {
00750 maybe_mutate ();
00751 }
00752
00753 octave_value::octave_value (const ComplexRowVector& v)
00754 : rep (new octave_complex_matrix (v))
00755 {
00756 maybe_mutate ();
00757 }
00758
00759 octave_value::octave_value (const FloatComplexRowVector& v)
00760 : rep (new octave_float_complex_matrix (v))
00761 {
00762 maybe_mutate ();
00763 }
00764
00765 octave_value::octave_value (const ComplexColumnVector& v)
00766 : rep (new octave_complex_matrix (v))
00767 {
00768 maybe_mutate ();
00769 }
00770
00771 octave_value::octave_value (const FloatComplexColumnVector& v)
00772 : rep (new octave_float_complex_matrix (v))
00773 {
00774 maybe_mutate ();
00775 }
00776
00777 octave_value::octave_value (const PermMatrix& p)
00778 : rep (new octave_perm_matrix (p))
00779 {
00780 maybe_mutate ();
00781 }
00782
00783 octave_value::octave_value (bool b)
00784 : rep (new octave_bool (b))
00785 {
00786 }
00787
00788 octave_value::octave_value (const boolMatrix& bm, const MatrixType& t)
00789 : rep (new octave_bool_matrix (bm, t))
00790 {
00791 maybe_mutate ();
00792 }
00793
00794 octave_value::octave_value (const boolNDArray& bnda)
00795 : rep (new octave_bool_matrix (bnda))
00796 {
00797 maybe_mutate ();
00798 }
00799
00800 octave_value::octave_value (const Array<bool>& bnda)
00801 : rep (new octave_bool_matrix (bnda))
00802 {
00803 maybe_mutate ();
00804 }
00805
00806 octave_value::octave_value (char c, char type)
00807 : rep (type == '"'
00808 ? new octave_char_matrix_dq_str (c)
00809 : new octave_char_matrix_sq_str (c))
00810 {
00811 maybe_mutate ();
00812 }
00813
00814 octave_value::octave_value (const char *s, char type)
00815 : rep (type == '"'
00816 ? new octave_char_matrix_dq_str (s)
00817 : new octave_char_matrix_sq_str (s))
00818 {
00819 maybe_mutate ();
00820 }
00821
00822 octave_value::octave_value (const std::string& s, char type)
00823 : rep (type == '"'
00824 ? new octave_char_matrix_dq_str (s)
00825 : new octave_char_matrix_sq_str (s))
00826 {
00827 maybe_mutate ();
00828 }
00829
00830 octave_value::octave_value (const string_vector& s, char type)
00831 : rep (type == '"'
00832 ? new octave_char_matrix_dq_str (s)
00833 : new octave_char_matrix_sq_str (s))
00834 {
00835 maybe_mutate ();
00836 }
00837
00838 octave_value::octave_value (const charMatrix& chm, char type)
00839 : rep (type == '"'
00840 ? new octave_char_matrix_dq_str (chm)
00841 : new octave_char_matrix_sq_str (chm))
00842 {
00843 maybe_mutate ();
00844 }
00845
00846 octave_value::octave_value (const charNDArray& chm, char type)
00847 : rep (type == '"'
00848 ? new octave_char_matrix_dq_str (chm)
00849 : new octave_char_matrix_sq_str (chm))
00850 {
00851 maybe_mutate ();
00852 }
00853
00854 octave_value::octave_value (const Array<char>& chm, char type)
00855 : rep (type == '"'
00856 ? new octave_char_matrix_dq_str (chm)
00857 : new octave_char_matrix_sq_str (chm))
00858 {
00859 maybe_mutate ();
00860 }
00861
00862 octave_value::octave_value (const charMatrix& chm, bool, char type)
00863 : rep (type == '"'
00864 ? new octave_char_matrix_dq_str (chm)
00865 : new octave_char_matrix_sq_str (chm))
00866 {
00867 maybe_mutate ();
00868 }
00869
00870 octave_value::octave_value (const charNDArray& chm, bool, char type)
00871 : rep (type == '"'
00872 ? new octave_char_matrix_dq_str (chm)
00873 : new octave_char_matrix_sq_str (chm))
00874 {
00875 maybe_mutate ();
00876 }
00877
00878 octave_value::octave_value (const Array<char>& chm, bool, char type)
00879 : rep (type == '"'
00880 ? new octave_char_matrix_dq_str (chm)
00881 : new octave_char_matrix_sq_str (chm))
00882 {
00883 maybe_mutate ();
00884 }
00885
00886 octave_value::octave_value (const SparseMatrix& m, const MatrixType &t)
00887 : rep (new octave_sparse_matrix (m, t))
00888 {
00889 maybe_mutate ();
00890 }
00891
00892 octave_value::octave_value (const Sparse<double>& m, const MatrixType &t)
00893 : rep (new octave_sparse_matrix (m, t))
00894 {
00895 maybe_mutate ();
00896 }
00897
00898 octave_value::octave_value (const SparseComplexMatrix& m, const MatrixType &t)
00899 : rep (new octave_sparse_complex_matrix (m, t))
00900 {
00901 maybe_mutate ();
00902 }
00903
00904 octave_value::octave_value (const Sparse<Complex>& m, const MatrixType &t)
00905 : rep (new octave_sparse_complex_matrix (m, t))
00906 {
00907 maybe_mutate ();
00908 }
00909
00910 octave_value::octave_value (const SparseBoolMatrix& bm, const MatrixType &t)
00911 : rep (new octave_sparse_bool_matrix (bm, t))
00912 {
00913 maybe_mutate ();
00914 }
00915
00916 octave_value::octave_value (const Sparse<bool>& bm, const MatrixType &t)
00917 : rep (new octave_sparse_bool_matrix (bm, t))
00918 {
00919 maybe_mutate ();
00920 }
00921
00922 octave_value::octave_value (const octave_int8& i)
00923 : rep (new octave_int8_scalar (i))
00924 {
00925 maybe_mutate ();
00926 }
00927
00928 octave_value::octave_value (const octave_uint8& i)
00929 : rep (new octave_uint8_scalar (i))
00930 {
00931 maybe_mutate ();
00932 }
00933
00934 octave_value::octave_value (const octave_int16& i)
00935 : rep (new octave_int16_scalar (i))
00936 {
00937 maybe_mutate ();
00938 }
00939
00940 octave_value::octave_value (const octave_uint16& i)
00941 : rep (new octave_uint16_scalar (i))
00942 {
00943 maybe_mutate ();
00944 }
00945
00946 octave_value::octave_value (const octave_int32& i)
00947 : rep (new octave_int32_scalar (i))
00948 {
00949 maybe_mutate ();
00950 }
00951
00952 octave_value::octave_value (const octave_uint32& i)
00953 : rep (new octave_uint32_scalar (i))
00954 {
00955 maybe_mutate ();
00956 }
00957
00958 octave_value::octave_value (const octave_int64& i)
00959 : rep (new octave_int64_scalar (i))
00960 {
00961 maybe_mutate ();
00962 }
00963
00964 octave_value::octave_value (const octave_uint64& i)
00965 : rep (new octave_uint64_scalar (i))
00966 {
00967 maybe_mutate ();
00968 }
00969
00970 octave_value::octave_value (const int8NDArray& inda)
00971 : rep (new octave_int8_matrix (inda))
00972 {
00973 maybe_mutate ();
00974 }
00975
00976 octave_value::octave_value (const Array<octave_int8>& inda)
00977 : rep (new octave_int8_matrix (inda))
00978 {
00979 maybe_mutate ();
00980 }
00981
00982 octave_value::octave_value (const uint8NDArray& inda)
00983 : rep (new octave_uint8_matrix (inda))
00984 {
00985 maybe_mutate ();
00986 }
00987
00988 octave_value::octave_value (const Array<octave_uint8>& inda)
00989 : rep (new octave_uint8_matrix (inda))
00990 {
00991 maybe_mutate ();
00992 }
00993
00994 octave_value::octave_value (const int16NDArray& inda)
00995 : rep (new octave_int16_matrix (inda))
00996 {
00997 maybe_mutate ();
00998 }
00999
01000 octave_value::octave_value (const Array<octave_int16>& inda)
01001 : rep (new octave_int16_matrix (inda))
01002 {
01003 maybe_mutate ();
01004 }
01005
01006 octave_value::octave_value (const uint16NDArray& inda)
01007 : rep (new octave_uint16_matrix (inda))
01008 {
01009 maybe_mutate ();
01010 }
01011
01012 octave_value::octave_value (const Array<octave_uint16>& inda)
01013 : rep (new octave_uint16_matrix (inda))
01014 {
01015 maybe_mutate ();
01016 }
01017
01018 octave_value::octave_value (const int32NDArray& inda)
01019 : rep (new octave_int32_matrix (inda))
01020 {
01021 maybe_mutate ();
01022 }
01023
01024 octave_value::octave_value (const Array<octave_int32>& inda)
01025 : rep (new octave_int32_matrix (inda))
01026 {
01027 maybe_mutate ();
01028 }
01029
01030 octave_value::octave_value (const uint32NDArray& inda)
01031 : rep (new octave_uint32_matrix (inda))
01032 {
01033 maybe_mutate ();
01034 }
01035
01036 octave_value::octave_value (const Array<octave_uint32>& inda)
01037 : rep (new octave_uint32_matrix (inda))
01038 {
01039 maybe_mutate ();
01040 }
01041
01042 octave_value::octave_value (const int64NDArray& inda)
01043 : rep (new octave_int64_matrix (inda))
01044 {
01045 maybe_mutate ();
01046 }
01047
01048 octave_value::octave_value (const Array<octave_int64>& inda)
01049 : rep (new octave_int64_matrix (inda))
01050 {
01051 maybe_mutate ();
01052 }
01053
01054 octave_value::octave_value (const uint64NDArray& inda)
01055 : rep (new octave_uint64_matrix (inda))
01056 {
01057 maybe_mutate ();
01058 }
01059
01060 octave_value::octave_value (const Array<octave_uint64>& inda)
01061 : rep (new octave_uint64_matrix (inda))
01062 {
01063 maybe_mutate ();
01064 }
01065
01066 octave_value::octave_value (const Array<octave_idx_type>& inda, bool zero_based,
01067 bool cache_index)
01068 : rep (new octave_matrix (inda, zero_based, cache_index))
01069 {
01070 maybe_mutate ();
01071 }
01072
01073 octave_value::octave_value (const idx_vector& idx, bool lazy)
01074 : rep ()
01075 {
01076 double scalar;
01077 Range range;
01078 NDArray array;
01079 boolNDArray mask;
01080 idx_vector::idx_class_type idx_class;
01081
01082 if (lazy)
01083 {
01084
01085 switch (idx.idx_class ())
01086 {
01087 case idx_vector::class_range:
01088 case idx_vector::class_vector:
01089 rep = new octave_lazy_index (idx);
01090 maybe_mutate ();
01091 return;
01092 default:
01093 break;
01094 }
01095 }
01096
01097 idx.unconvert (idx_class, scalar, range, array, mask);
01098
01099 switch (idx_class)
01100 {
01101 case idx_vector::class_colon:
01102 rep = new octave_magic_colon ();
01103 break;
01104 case idx_vector::class_range:
01105 rep = new octave_range (range, idx);
01106 break;
01107 case idx_vector::class_scalar:
01108 rep = new octave_scalar (scalar);
01109 break;
01110 case idx_vector::class_vector:
01111 rep = new octave_matrix (array, idx);
01112 break;
01113 case idx_vector::class_mask:
01114 rep = new octave_bool_matrix (mask, idx);
01115 break;
01116 default:
01117 assert (false);
01118 break;
01119 }
01120
01121
01122 maybe_mutate ();
01123 }
01124
01125 octave_value::octave_value (const Array<std::string>& cellstr)
01126 : rep (new octave_cell (cellstr))
01127 {
01128 maybe_mutate ();
01129 }
01130
01131 octave_value::octave_value (double base, double limit, double inc)
01132 : rep (new octave_range (base, limit, inc))
01133 {
01134 maybe_mutate ();
01135 }
01136
01137 octave_value::octave_value (const Range& r)
01138 : rep (new octave_range (r))
01139 {
01140 maybe_mutate ();
01141 }
01142
01143 octave_value::octave_value (const octave_map& m)
01144 : rep (new octave_struct (m))
01145 {
01146 maybe_mutate ();
01147 }
01148
01149 octave_value::octave_value (const octave_scalar_map& m)
01150 : rep (new octave_scalar_struct (m))
01151 {
01152 }
01153
01154 octave_value::octave_value (const Octave_map& m)
01155 : rep (new octave_struct (m))
01156 {
01157 maybe_mutate ();
01158 }
01159
01160 octave_value::octave_value (const Octave_map& m, const std::string& id,
01161 const std::list<std::string>& plist)
01162 : rep (new octave_class (m, id, plist))
01163 {
01164 }
01165
01166 octave_value::octave_value (const octave_value_list& l, bool)
01167 : rep (new octave_cs_list (l))
01168 {
01169 }
01170
01171 octave_value::octave_value (octave_value::magic_colon)
01172 : rep (new octave_magic_colon ())
01173 {
01174 }
01175
01176 octave_value::octave_value (octave_base_value *new_rep, bool borrow)
01177 : rep (new_rep)
01178 {
01179 if (borrow)
01180 rep->count++;
01181 }
01182
01183 octave_value::octave_value (octave_base_value *new_rep, int xcount)
01184 : rep (new_rep)
01185 {
01186 rep->count = xcount;
01187 }
01188
01189 octave_base_value *
01190 octave_value::clone (void) const
01191 {
01192 return rep->clone ();
01193 }
01194
01195 void
01196 octave_value::maybe_mutate (void)
01197 {
01198 octave_base_value *tmp = rep->try_narrowing_conversion ();
01199
01200 if (tmp && tmp != rep)
01201 {
01202 if (--rep->count == 0)
01203 delete rep;
01204
01205 rep = tmp;
01206 }
01207 }
01208
01209 octave_value
01210 octave_value::single_subsref (const std::string& type,
01211 const octave_value_list& idx)
01212 {
01213 std::list<octave_value_list> i;
01214
01215 i.push_back (idx);
01216
01217 return rep->subsref (type, i);
01218 }
01219
01220 octave_value_list
01221 octave_value::subsref (const std::string& type,
01222 const std::list<octave_value_list>& idx, int nargout)
01223 {
01224 if (nargout == 1)
01225 return rep->subsref (type, idx);
01226 else
01227 return rep->subsref (type, idx, nargout);
01228 }
01229
01230 octave_value_list
01231 octave_value::subsref (const std::string& type,
01232 const std::list<octave_value_list>& idx, int nargout,
01233 const std::list<octave_lvalue> *lvalue_list)
01234 {
01235 if (lvalue_list)
01236 return rep->subsref (type, idx, nargout, lvalue_list);
01237 else
01238 return subsref (type, idx, nargout);
01239 }
01240
01241 octave_value
01242 octave_value::next_subsref (const std::string& type,
01243 const std::list<octave_value_list>& idx,
01244 size_t skip)
01245 {
01246 if (! error_state && idx.size () > skip)
01247 {
01248 std::list<octave_value_list> new_idx (idx);
01249 for (size_t i = 0; i < skip; i++)
01250 new_idx.erase (new_idx.begin ());
01251 return subsref (type.substr (skip), new_idx);
01252 }
01253 else
01254 return *this;
01255 }
01256
01257 octave_value_list
01258 octave_value::next_subsref (int nargout, const std::string& type,
01259 const std::list<octave_value_list>& idx,
01260 size_t skip)
01261 {
01262 if (! error_state && idx.size () > skip)
01263 {
01264 std::list<octave_value_list> new_idx (idx);
01265 for (size_t i = 0; i < skip; i++)
01266 new_idx.erase (new_idx.begin ());
01267 return subsref (type.substr (skip), new_idx, nargout);
01268 }
01269 else
01270 return *this;
01271 }
01272
01273 octave_value
01274 octave_value::next_subsref (bool auto_add, const std::string& type,
01275 const std::list<octave_value_list>& idx,
01276 size_t skip)
01277 {
01278 if (! error_state && idx.size () > skip)
01279 {
01280 std::list<octave_value_list> new_idx (idx);
01281 for (size_t i = 0; i < skip; i++)
01282 new_idx.erase (new_idx.begin ());
01283 return subsref (type.substr (skip), new_idx, auto_add);
01284 }
01285 else
01286 return *this;
01287 }
01288
01289 octave_value_list
01290 octave_value::do_multi_index_op (int nargout, const octave_value_list& idx)
01291 {
01292 return rep->do_multi_index_op (nargout, idx);
01293 }
01294
01295 octave_value_list
01296 octave_value::do_multi_index_op (int nargout, const octave_value_list& idx,
01297 const std::list<octave_lvalue> *lvalue_list)
01298 {
01299 return rep->do_multi_index_op (nargout, idx, lvalue_list);
01300 }
01301
01302 #if 0
01303 static void
01304 gripe_assign_failed (const std::string& on, const std::string& tn1,
01305 const std::string& tn2)
01306 {
01307 error ("assignment failed for '%s %s %s'",
01308 tn1.c_str (), on.c_str (), tn2.c_str ());
01309 }
01310 #endif
01311
01312 static void
01313 gripe_assign_failed_or_no_method (const std::string& on,
01314 const std::string& tn1,
01315 const std::string& tn2)
01316 {
01317 error ("assignment failed, or no method for '%s %s %s'",
01318 tn1.c_str (), on.c_str (), tn2.c_str ());
01319 }
01320
01321 octave_value
01322 octave_value::subsasgn (const std::string& type,
01323 const std::list<octave_value_list>& idx,
01324 const octave_value& rhs)
01325 {
01326 return rep->subsasgn (type, idx, rhs);
01327 }
01328
01329 octave_value
01330 octave_value::undef_subsasgn (const std::string& type,
01331 const std::list<octave_value_list>& idx,
01332 const octave_value& rhs)
01333 {
01334 return rep->undef_subsasgn (type, idx, rhs);
01335 }
01336
01337 octave_value&
01338 octave_value::assign (assign_op op, const std::string& type,
01339 const std::list<octave_value_list>& idx,
01340 const octave_value& rhs)
01341 {
01342 octave_value retval;
01343
01344 make_unique ();
01345
01346 octave_value t_rhs = rhs;
01347
01348 if (op != op_asn_eq)
01349 {
01350 if (is_defined ())
01351 {
01352 octave_value t = subsref (type, idx);
01353
01354 if (! error_state)
01355 {
01356 binary_op binop = op_eq_to_binary_op (op);
01357
01358 if (! error_state)
01359 t_rhs = do_binary_op (binop, t, rhs);
01360 }
01361 }
01362 else
01363 error ("in computed assignment A(index) OP= X, A must be defined first");
01364 }
01365
01366 if (! error_state)
01367 {
01368 octave_value tmp = subsasgn (type, idx, t_rhs);
01369
01370 if (error_state)
01371 gripe_assign_failed_or_no_method (assign_op_as_string (op_asn_eq),
01372 type_name (), rhs.type_name ());
01373 else
01374 *this = tmp;
01375 }
01376
01377 return *this;
01378 }
01379
01380 octave_value&
01381 octave_value::assign (assign_op op, const octave_value& rhs)
01382 {
01383 if (op == op_asn_eq)
01384
01385 operator = (rhs.storable_value ());
01386 else if (is_defined ())
01387 {
01388 octave_value_typeinfo::assign_op_fcn f = 0;
01389
01390
01391 if (rep->count == 1)
01392 {
01393 int tthis = this->type_id ();
01394 int trhs = rhs.type_id ();
01395
01396 f = octave_value_typeinfo::lookup_assign_op (op, tthis, trhs);
01397 }
01398
01399 if (f)
01400 {
01401 try
01402 {
01403 f (*rep, octave_value_list (), *rhs.rep);
01404 maybe_mutate ();
01405 }
01406 catch (octave_execution_exception)
01407 {
01408 gripe_library_execution_error ();
01409 }
01410 }
01411 else
01412 {
01413
01414 binary_op binop = op_eq_to_binary_op (op);
01415
01416 if (! error_state)
01417 {
01418 octave_value t = do_binary_op (binop, *this, rhs);
01419
01420 if (! error_state)
01421 operator = (t);
01422 }
01423 }
01424 }
01425 else
01426 error ("in computed assignment A OP= X, A must be defined first");
01427
01428 return *this;
01429 }
01430
01431 octave_idx_type
01432 octave_value::length (void) const
01433 {
01434 octave_idx_type retval = 0;
01435
01436 const dim_vector dv = dims ();
01437
01438 for (int i = 0; i < dv.length (); i++)
01439 {
01440 if (dv(i) == 0)
01441 {
01442 retval = 0;
01443 break;
01444 }
01445
01446 if (dv(i) > retval)
01447 retval = dv(i);
01448 }
01449
01450 return retval;
01451 }
01452
01453 bool
01454 octave_value::is_equal (const octave_value& test) const
01455 {
01456 bool retval = false;
01457
01458
01459
01460 if (rows () == test.rows () && columns () == test.columns ())
01461 {
01462 octave_value tmp = do_binary_op (octave_value::op_eq, *this, test);
01463
01464
01465 if (! error_state && tmp.is_defined ())
01466 retval = tmp.is_true () || tmp.is_empty ();
01467 }
01468
01469 return retval;
01470 }
01471
01472 Cell
01473 octave_value::cell_value (void) const
01474 {
01475 return rep->cell_value ();
01476 }
01477
01478
01479
01480
01481 octave_idx_type
01482 octave_value::idx_type_value (bool req_int, bool frc_str_conv) const
01483 {
01484 #if SIZEOF_OCTAVE_IDX_TYPE == SIZEOF_LONG
01485 return long_value (req_int, frc_str_conv);
01486 #elif SIZEOF_OCTAVE_IDX_TYPE == SIZEOF_INT
01487 return int_value (req_int, frc_str_conv);
01488 #else
01489 #error "no octave_value extractor for octave_idx_type"
01490 #endif
01491 }
01492
01493 octave_map
01494 octave_value::map_value (void) const
01495 {
01496 return rep->map_value ();
01497 }
01498
01499 octave_scalar_map
01500 octave_value::scalar_map_value (void) const
01501 {
01502 return rep->scalar_map_value ();
01503 }
01504
01505 octave_function *
01506 octave_value::function_value (bool silent) const
01507 {
01508 return rep->function_value (silent);
01509 }
01510
01511 octave_user_function *
01512 octave_value::user_function_value (bool silent) const
01513 {
01514 return rep->user_function_value (silent);
01515 }
01516
01517 octave_user_script *
01518 octave_value::user_script_value (bool silent) const
01519 {
01520 return rep->user_script_value (silent);
01521 }
01522
01523 octave_user_code *
01524 octave_value::user_code_value (bool silent) const
01525 {
01526 return rep->user_code_value (silent);
01527 }
01528
01529 octave_fcn_handle *
01530 octave_value::fcn_handle_value (bool silent) const
01531 {
01532 return rep->fcn_handle_value (silent);
01533 }
01534
01535 octave_fcn_inline *
01536 octave_value::fcn_inline_value (bool silent) const
01537 {
01538 return rep->fcn_inline_value (silent);
01539 }
01540
01541 octave_value_list
01542 octave_value::list_value (void) const
01543 {
01544 return rep->list_value ();
01545 }
01546
01547 static dim_vector
01548 make_vector_dims (const dim_vector& dv, bool force_vector_conversion,
01549 const std::string& my_type, const std::string& wanted_type)
01550 {
01551 dim_vector retval (dv);
01552 retval.chop_trailing_singletons ();
01553 octave_idx_type nel = dv.numel ();
01554
01555 if (retval.length () > 2 || (retval(0) != 1 && retval(1) != 1))
01556 {
01557 if (!force_vector_conversion)
01558 gripe_implicit_conversion ("Octave:array-as-vector",
01559 my_type.c_str (), wanted_type.c_str ());
01560 retval = dim_vector (nel, 1);
01561 }
01562
01563 return retval;
01564 }
01565
01566 ColumnVector
01567 octave_value::column_vector_value (bool force_string_conv,
01568 bool frc_vec_conv) const
01569 {
01570 return ColumnVector (vector_value (force_string_conv,
01571 frc_vec_conv));
01572 }
01573
01574 ComplexColumnVector
01575 octave_value::complex_column_vector_value (bool force_string_conv,
01576 bool frc_vec_conv) const
01577 {
01578 return ComplexColumnVector (complex_vector_value (force_string_conv,
01579 frc_vec_conv));
01580 }
01581
01582 RowVector
01583 octave_value::row_vector_value (bool force_string_conv,
01584 bool frc_vec_conv) const
01585 {
01586 return RowVector (vector_value (force_string_conv,
01587 frc_vec_conv));
01588 }
01589
01590 ComplexRowVector
01591 octave_value::complex_row_vector_value (bool force_string_conv,
01592 bool frc_vec_conv) const
01593 {
01594 return ComplexRowVector (complex_vector_value (force_string_conv,
01595 frc_vec_conv));
01596 }
01597
01598 Array<double>
01599 octave_value::vector_value (bool force_string_conv,
01600 bool force_vector_conversion) const
01601 {
01602 Array<double> retval = array_value (force_string_conv);
01603
01604 if (error_state)
01605 return retval;
01606 else
01607 return retval.reshape (make_vector_dims (retval.dims (),
01608 force_vector_conversion,
01609 type_name (), "real vector"));
01610 }
01611
01612 template <class T>
01613 static Array<int>
01614 convert_to_int_array (const Array<octave_int<T> >& A)
01615 {
01616 Array<int> retval (A.dims ());
01617 octave_idx_type n = A.numel ();
01618
01619 for (octave_idx_type i = 0; i < n; i++)
01620 retval.xelem (i) = octave_int<int> (A.xelem (i));
01621
01622 return retval;
01623 }
01624
01625 Array<int>
01626 octave_value::int_vector_value (bool force_string_conv, bool require_int,
01627 bool force_vector_conversion) const
01628 {
01629 Array<int> retval;
01630
01631 if (is_integer_type ())
01632 {
01633 if (is_int32_type ())
01634 retval = convert_to_int_array (int32_array_value ());
01635 else if (is_int64_type ())
01636 retval = convert_to_int_array (int64_array_value ());
01637 else if (is_int16_type ())
01638 retval = convert_to_int_array (int16_array_value ());
01639 else if (is_int8_type ())
01640 retval = convert_to_int_array (int8_array_value ());
01641 else if (is_uint32_type ())
01642 retval = convert_to_int_array (uint32_array_value ());
01643 else if (is_uint64_type ())
01644 retval = convert_to_int_array (uint64_array_value ());
01645 else if (is_uint16_type ())
01646 retval = convert_to_int_array (uint16_array_value ());
01647 else if (is_uint8_type ())
01648 retval = convert_to_int_array (uint8_array_value ());
01649 else
01650 retval = array_value (force_string_conv);
01651 }
01652 else
01653 {
01654 const NDArray a = array_value (force_string_conv);
01655 if (! error_state)
01656 {
01657 if (require_int)
01658 {
01659 retval.resize (a.dims ());
01660 for (octave_idx_type i = 0; i < a.numel (); i++)
01661 {
01662 double ai = a.elem (i);
01663 int v = static_cast<int> (ai);
01664 if (ai == v)
01665 retval.xelem (i) = v;
01666 else
01667 {
01668 error_with_cfn ("conversion to integer value failed");
01669 break;
01670 }
01671 }
01672 }
01673 else
01674 retval = Array<int> (a);
01675 }
01676 }
01677
01678
01679 if (error_state)
01680 return retval;
01681 else
01682 return retval.reshape (make_vector_dims (retval.dims (),
01683 force_vector_conversion,
01684 type_name (), "integer vector"));
01685 }
01686
01687 template <class T>
01688 static Array<octave_idx_type>
01689 convert_to_octave_idx_type_array (const Array<octave_int<T> >& A)
01690 {
01691 Array<octave_idx_type> retval (A.dims ());
01692 octave_idx_type n = A.numel ();
01693
01694 for (octave_idx_type i = 0; i < n; i++)
01695 retval.xelem (i) = octave_int<octave_idx_type> (A.xelem (i));
01696
01697 return retval;
01698 }
01699
01700 Array<octave_idx_type>
01701 octave_value::octave_idx_type_vector_value (bool require_int,
01702 bool force_string_conv,
01703 bool force_vector_conversion) const
01704 {
01705 Array<octave_idx_type> retval;
01706
01707 if (is_integer_type ())
01708 {
01709 if (is_int32_type ())
01710 retval = convert_to_octave_idx_type_array (int32_array_value ());
01711 else if (is_int64_type ())
01712 retval = convert_to_octave_idx_type_array (int64_array_value ());
01713 else if (is_int16_type ())
01714 retval = convert_to_octave_idx_type_array (int16_array_value ());
01715 else if (is_int8_type ())
01716 retval = convert_to_octave_idx_type_array (int8_array_value ());
01717 else if (is_uint32_type ())
01718 retval = convert_to_octave_idx_type_array (uint32_array_value ());
01719 else if (is_uint64_type ())
01720 retval = convert_to_octave_idx_type_array (uint64_array_value ());
01721 else if (is_uint16_type ())
01722 retval = convert_to_octave_idx_type_array (uint16_array_value ());
01723 else if (is_uint8_type ())
01724 retval = convert_to_octave_idx_type_array (uint8_array_value ());
01725 else
01726 retval = array_value (force_string_conv);
01727 }
01728 else
01729 {
01730 const NDArray a = array_value (force_string_conv);
01731 if (! error_state)
01732 {
01733 if (require_int)
01734 {
01735 retval.resize (a.dims ());
01736 for (octave_idx_type i = 0; i < a.numel (); i++)
01737 {
01738 double ai = a.elem (i);
01739 octave_idx_type v = static_cast<octave_idx_type> (ai);
01740 if (ai == v)
01741 retval.xelem (i) = v;
01742 else
01743 {
01744 error_with_cfn ("conversion to integer value failed");
01745 break;
01746 }
01747 }
01748 }
01749 else
01750 retval = Array<octave_idx_type> (a);
01751 }
01752 }
01753
01754
01755 if (error_state)
01756 return retval;
01757 else
01758 return retval.reshape (make_vector_dims (retval.dims (),
01759 force_vector_conversion,
01760 type_name (), "integer vector"));
01761 }
01762
01763 Array<Complex>
01764 octave_value::complex_vector_value (bool force_string_conv,
01765 bool force_vector_conversion) const
01766 {
01767 Array<Complex> retval = complex_array_value (force_string_conv);
01768
01769 if (error_state)
01770 return retval;
01771 else
01772 return retval.reshape (make_vector_dims (retval.dims (),
01773 force_vector_conversion,
01774 type_name (), "complex vector"));
01775 }
01776
01777 FloatColumnVector
01778 octave_value::float_column_vector_value (bool force_string_conv,
01779 bool frc_vec_conv) const
01780 {
01781 return FloatColumnVector (float_vector_value (force_string_conv,
01782 frc_vec_conv));
01783 }
01784
01785 FloatComplexColumnVector
01786 octave_value::float_complex_column_vector_value (bool force_string_conv,
01787 bool frc_vec_conv) const
01788 {
01789 return FloatComplexColumnVector (float_complex_vector_value (force_string_conv,
01790 frc_vec_conv));
01791 }
01792
01793 FloatRowVector
01794 octave_value::float_row_vector_value (bool force_string_conv,
01795 bool frc_vec_conv) const
01796 {
01797 return FloatRowVector (float_vector_value (force_string_conv,
01798 frc_vec_conv));
01799 }
01800
01801 FloatComplexRowVector
01802 octave_value::float_complex_row_vector_value (bool force_string_conv,
01803 bool frc_vec_conv) const
01804 {
01805 return FloatComplexRowVector (float_complex_vector_value (force_string_conv,
01806 frc_vec_conv));
01807 }
01808
01809 Array<float>
01810 octave_value::float_vector_value (bool force_string_conv,
01811 bool force_vector_conversion) const
01812 {
01813 Array<float> retval = float_array_value (force_string_conv);
01814
01815 if (error_state)
01816 return retval;
01817 else
01818 return retval.reshape (make_vector_dims (retval.dims (),
01819 force_vector_conversion,
01820 type_name (), "real vector"));
01821 }
01822
01823 Array<FloatComplex>
01824 octave_value::float_complex_vector_value (bool force_string_conv,
01825 bool force_vector_conversion) const
01826 {
01827 Array<FloatComplex> retval = float_complex_array_value (force_string_conv);
01828
01829 if (error_state)
01830 return retval;
01831 else
01832 return retval.reshape (make_vector_dims (retval.dims (),
01833 force_vector_conversion,
01834 type_name (), "complex vector"));
01835 }
01836
01837 octave_value
01838 octave_value::storable_value (void) const
01839 {
01840 octave_value retval = *this;
01841 if (is_null_value ())
01842 retval = octave_value (rep->empty_clone ());
01843 else
01844 retval.maybe_economize ();
01845
01846 return retval;
01847 }
01848
01849 void
01850 octave_value::make_storable_value (void)
01851 {
01852 if (is_null_value ())
01853 {
01854 octave_base_value *rc = rep->empty_clone ();
01855 if (--rep->count == 0)
01856 delete rep;
01857 rep = rc;
01858 }
01859 else
01860 maybe_economize ();
01861 }
01862
01863 int
01864 octave_value::write (octave_stream& os, int block_size,
01865 oct_data_conv::data_type output_type, int skip,
01866 oct_mach_info::float_format flt_fmt) const
01867 {
01868 return rep->write (os, block_size, output_type, skip, flt_fmt);
01869 }
01870
01871 static void
01872 gripe_binary_op (const std::string& on, const std::string& tn1,
01873 const std::string& tn2)
01874 {
01875 error ("binary operator '%s' not implemented for '%s' by '%s' operations",
01876 on.c_str (), tn1.c_str (), tn2.c_str ());
01877 }
01878
01879 static void
01880 gripe_binary_op_conv (const std::string& on)
01881 {
01882 error ("type conversion failed for binary operator '%s'", on.c_str ());
01883 }
01884
01885 octave_value
01886 do_binary_op (octave_value::binary_op op,
01887 const octave_value& v1, const octave_value& v2)
01888 {
01889 octave_value retval;
01890
01891 int t1 = v1.type_id ();
01892 int t2 = v2.type_id ();
01893
01894 if (t1 == octave_class::static_type_id ()
01895 || t2 == octave_class::static_type_id ())
01896 {
01897 octave_value_typeinfo::binary_class_op_fcn f
01898 = octave_value_typeinfo::lookup_binary_class_op (op);
01899
01900 if (f)
01901 {
01902 try
01903 {
01904 retval = f (v1, v2);
01905 }
01906 catch (octave_execution_exception)
01907 {
01908 gripe_library_execution_error ();
01909 }
01910 }
01911 else
01912 gripe_binary_op (octave_value::binary_op_as_string (op),
01913 v1.class_name (), v2.class_name ());
01914 }
01915 else
01916 {
01917
01918
01919
01920 octave_value_typeinfo::binary_op_fcn f
01921 = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
01922
01923 if (f)
01924 {
01925 try
01926 {
01927 retval = f (*v1.rep, *v2.rep);
01928 }
01929 catch (octave_execution_exception)
01930 {
01931 gripe_library_execution_error ();
01932 }
01933 }
01934 else
01935 {
01936 octave_value tv1;
01937 octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
01938
01939 octave_value tv2;
01940 octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
01941
01942
01943 if (cf2.type_id () >= 0 &&
01944 octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
01945 cf1 = 0;
01946 else if (cf1.type_id () >= 0 &&
01947 octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
01948 cf2 = 0;
01949
01950 if (cf1)
01951 {
01952 octave_base_value *tmp = cf1 (*v1.rep);
01953
01954 if (tmp)
01955 {
01956 tv1 = octave_value (tmp);
01957 t1 = tv1.type_id ();
01958 }
01959 else
01960 {
01961 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
01962 return retval;
01963 }
01964 }
01965 else
01966 tv1 = v1;
01967
01968 if (cf2)
01969 {
01970 octave_base_value *tmp = cf2 (*v2.rep);
01971
01972 if (tmp)
01973 {
01974 tv2 = octave_value (tmp);
01975 t2 = tv2.type_id ();
01976 }
01977 else
01978 {
01979 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
01980 return retval;
01981 }
01982 }
01983 else
01984 tv2 = v2;
01985
01986 if (cf1 || cf2)
01987 {
01988 retval = do_binary_op (op, tv1, tv2);
01989 }
01990 else
01991 {
01992
01993 cf1 = tv1.numeric_demotion_function ();
01994
01995 cf2 = tv2.numeric_demotion_function ();
01996
01997
01998 if (cf2.type_id () >= 0
01999 && octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
02000 cf1 = 0;
02001 else if (cf1.type_id () >= 0
02002 && octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
02003 cf2 = 0;
02004
02005 if (cf1)
02006 {
02007 octave_base_value *tmp = cf1 (*tv1.rep);
02008
02009 if (tmp)
02010 {
02011 tv1 = octave_value (tmp);
02012 t1 = tv1.type_id ();
02013 }
02014 else
02015 {
02016 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
02017 return retval;
02018 }
02019 }
02020
02021 if (cf2)
02022 {
02023 octave_base_value *tmp = cf2 (*tv2.rep);
02024
02025 if (tmp)
02026 {
02027 tv2 = octave_value (tmp);
02028 t2 = tv2.type_id ();
02029 }
02030 else
02031 {
02032 gripe_binary_op_conv (octave_value::binary_op_as_string (op));
02033 return retval;
02034 }
02035 }
02036
02037 if (cf1 || cf2)
02038 {
02039 f = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
02040
02041 if (f)
02042 {
02043 try
02044 {
02045 retval = f (*tv1.rep, *tv2.rep);
02046 }
02047 catch (octave_execution_exception)
02048 {
02049 gripe_library_execution_error ();
02050 }
02051 }
02052 else
02053 gripe_binary_op (octave_value::binary_op_as_string (op),
02054 v1.type_name (), v2.type_name ());
02055 }
02056 else
02057 gripe_binary_op (octave_value::binary_op_as_string (op),
02058 v1.type_name (), v2.type_name ());
02059 }
02060 }
02061 }
02062
02063 return retval;
02064 }
02065
02066 static octave_value
02067 decompose_binary_op (octave_value::compound_binary_op op,
02068 const octave_value& v1, const octave_value& v2)
02069 {
02070 octave_value retval;
02071
02072 switch (op)
02073 {
02074 case octave_value::op_trans_mul:
02075 retval = do_binary_op (octave_value::op_mul,
02076 do_unary_op (octave_value::op_transpose, v1),
02077 v2);
02078 break;
02079 case octave_value::op_mul_trans:
02080 retval = do_binary_op (octave_value::op_mul,
02081 v1,
02082 do_unary_op (octave_value::op_transpose, v2));
02083 break;
02084 case octave_value::op_herm_mul:
02085 retval = do_binary_op (octave_value::op_mul,
02086 do_unary_op (octave_value::op_hermitian, v1),
02087 v2);
02088 break;
02089 case octave_value::op_mul_herm:
02090 retval = do_binary_op (octave_value::op_mul,
02091 v1,
02092 do_unary_op (octave_value::op_hermitian, v2));
02093 break;
02094 case octave_value::op_trans_ldiv:
02095 retval = do_binary_op (octave_value::op_ldiv,
02096 do_unary_op (octave_value::op_transpose, v1),
02097 v2);
02098 break;
02099 case octave_value::op_herm_ldiv:
02100 retval = do_binary_op (octave_value::op_ldiv,
02101 do_unary_op (octave_value::op_hermitian, v1),
02102 v2);
02103 break;
02104 case octave_value::op_el_not_and:
02105 retval = do_binary_op (octave_value::op_el_and,
02106 do_unary_op (octave_value::op_not, v1),
02107 v2);
02108 break;
02109 case octave_value::op_el_not_or:
02110 retval = do_binary_op (octave_value::op_el_or,
02111 do_unary_op (octave_value::op_not, v1),
02112 v2);
02113 break;
02114 case octave_value::op_el_and_not:
02115 retval = do_binary_op (octave_value::op_el_and,
02116 v1,
02117 do_unary_op (octave_value::op_not, v2));
02118 break;
02119 case octave_value::op_el_or_not:
02120 retval = do_binary_op (octave_value::op_el_or,
02121 v1,
02122 do_unary_op (octave_value::op_not, v2));
02123 break;
02124 default:
02125 error ("invalid compound operator");
02126 break;
02127 }
02128
02129 return retval;
02130 }
02131
02132 octave_value
02133 do_binary_op (octave_value::compound_binary_op op,
02134 const octave_value& v1, const octave_value& v2)
02135 {
02136 octave_value retval;
02137
02138 int t1 = v1.type_id ();
02139 int t2 = v2.type_id ();
02140
02141 if (t1 == octave_class::static_type_id ()
02142 || t2 == octave_class::static_type_id ())
02143 {
02144 octave_value_typeinfo::binary_class_op_fcn f
02145 = octave_value_typeinfo::lookup_binary_class_op (op);
02146
02147 if (f)
02148 {
02149 try
02150 {
02151 retval = f (v1, v2);
02152 }
02153 catch (octave_execution_exception)
02154 {
02155 gripe_library_execution_error ();
02156 }
02157 }
02158 else
02159 retval = decompose_binary_op (op, v1, v2);
02160 }
02161 else
02162 {
02163 octave_value_typeinfo::binary_op_fcn f
02164 = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
02165
02166 if (f)
02167 {
02168 try
02169 {
02170 retval = f (*v1.rep, *v2.rep);
02171 }
02172 catch (octave_execution_exception)
02173 {
02174 gripe_library_execution_error ();
02175 }
02176 }
02177 else
02178 retval = decompose_binary_op (op, v1, v2);
02179 }
02180
02181 return retval;
02182 }
02183
02184 static void
02185 gripe_cat_op (const std::string& tn1, const std::string& tn2)
02186 {
02187 error ("concatenation operator not implemented for '%s' by '%s' operations",
02188 tn1.c_str (), tn2.c_str ());
02189 }
02190
02191 static void
02192 gripe_cat_op_conv (void)
02193 {
02194 error ("type conversion failed for concatenation operator");
02195 }
02196
02197 octave_value
02198 do_cat_op (const octave_value& v1, const octave_value& v2,
02199 const Array<octave_idx_type>& ra_idx)
02200 {
02201 octave_value retval;
02202
02203
02204
02205
02206 int t1 = v1.type_id ();
02207 int t2 = v2.type_id ();
02208
02209 octave_value_typeinfo::cat_op_fcn f
02210 = octave_value_typeinfo::lookup_cat_op (t1, t2);
02211
02212 if (f)
02213 {
02214 try
02215 {
02216 retval = f (*v1.rep, *v2.rep, ra_idx);
02217 }
02218 catch (octave_execution_exception)
02219 {
02220 gripe_library_execution_error ();
02221 }
02222 }
02223 else
02224 {
02225 octave_value tv1;
02226 octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
02227
02228 octave_value tv2;
02229 octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
02230
02231
02232 if (cf2.type_id () >= 0
02233 && octave_value_typeinfo::lookup_cat_op (t1, cf2.type_id ()))
02234 cf1 = 0;
02235 else if (cf1.type_id () >= 0
02236 && octave_value_typeinfo::lookup_cat_op (cf1.type_id (), t2))
02237 cf2 = 0;
02238
02239 if (cf1)
02240 {
02241 octave_base_value *tmp = cf1 (*v1.rep);
02242
02243 if (tmp)
02244 {
02245 tv1 = octave_value (tmp);
02246 t1 = tv1.type_id ();
02247 }
02248 else
02249 {
02250 gripe_cat_op_conv ();
02251 return retval;
02252 }
02253 }
02254 else
02255 tv1 = v1;
02256
02257 if (cf2)
02258 {
02259 octave_base_value *tmp = cf2 (*v2.rep);
02260
02261 if (tmp)
02262 {
02263 tv2 = octave_value (tmp);
02264 t2 = tv2.type_id ();
02265 }
02266 else
02267 {
02268 gripe_cat_op_conv ();
02269 return retval;
02270 }
02271 }
02272 else
02273 tv2 = v2;
02274
02275 if (cf1 || cf2)
02276 {
02277 retval = do_cat_op (tv1, tv2, ra_idx);
02278 }
02279 else
02280 gripe_cat_op (v1.type_name (), v2.type_name ());
02281 }
02282
02283 return retval;
02284 }
02285
02286 void
02287 octave_value::print_info (std::ostream& os, const std::string& prefix) const
02288 {
02289 os << prefix << "type_name: " << type_name () << "\n"
02290 << prefix << "count: " << get_count () << "\n"
02291 << prefix << "rep info: ";
02292
02293 rep->print_info (os, prefix + " ");
02294 }
02295
02296 static void
02297 gripe_unary_op (const std::string& on, const std::string& tn)
02298 {
02299 error ("unary operator '%s' not implemented for '%s' operands",
02300 on.c_str (), tn.c_str ());
02301 }
02302
02303 static void
02304 gripe_unary_op_conv (const std::string& on)
02305 {
02306 error ("type conversion failed for unary operator '%s'", on.c_str ());
02307 }
02308
02309 octave_value
02310 do_unary_op (octave_value::unary_op op, const octave_value& v)
02311 {
02312 octave_value retval;
02313
02314 int t = v.type_id ();
02315
02316 if (t == octave_class::static_type_id ())
02317 {
02318 octave_value_typeinfo::unary_class_op_fcn f
02319 = octave_value_typeinfo::lookup_unary_class_op (op);
02320
02321 if (f)
02322 {
02323 try
02324 {
02325 retval = f (v);
02326 }
02327 catch (octave_execution_exception)
02328 {
02329 gripe_library_execution_error ();
02330 }
02331 }
02332 else
02333 gripe_unary_op (octave_value::unary_op_as_string (op),
02334 v.class_name ());
02335 }
02336 else
02337 {
02338
02339
02340
02341 octave_value_typeinfo::unary_op_fcn f
02342 = octave_value_typeinfo::lookup_unary_op (op, t);
02343
02344 if (f)
02345 {
02346 try
02347 {
02348 retval = f (*v.rep);
02349 }
02350 catch (octave_execution_exception)
02351 {
02352 gripe_library_execution_error ();
02353 }
02354 }
02355 else
02356 {
02357 octave_value tv;
02358 octave_base_value::type_conv_fcn cf
02359 = v.numeric_conversion_function ();
02360
02361 if (cf)
02362 {
02363 octave_base_value *tmp = cf (*v.rep);
02364
02365 if (tmp)
02366 {
02367 tv = octave_value (tmp);
02368 retval = do_unary_op (op, tv);
02369 }
02370 else
02371 gripe_unary_op_conv (octave_value::unary_op_as_string (op));
02372 }
02373 else
02374 gripe_unary_op (octave_value::unary_op_as_string (op),
02375 v.type_name ());
02376 }
02377 }
02378
02379 return retval;
02380 }
02381
02382 static void
02383 gripe_unary_op_conversion_failed (const std::string& op,
02384 const std::string& tn)
02385 {
02386 error ("operator %s: type conversion for '%s' failed",
02387 op.c_str (), tn.c_str ());
02388 }
02389
02390 octave_value&
02391 octave_value::do_non_const_unary_op (unary_op op)
02392 {
02393 if (op == op_incr || op == op_decr)
02394 {
02395
02396
02397
02398 if (is_undefined ())
02399 {
02400 std::string op_str = unary_op_as_string (op);
02401 error ("in x%s or %sx, x must be defined first",
02402 op_str.c_str (), op_str.c_str ());
02403 return *this;
02404 }
02405
02406
02407 int t = type_id ();
02408
02409 octave_value_typeinfo::non_const_unary_op_fcn f
02410 = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
02411
02412 if (f)
02413 {
02414 make_unique ();
02415
02416 try
02417 {
02418 f (*rep);
02419 }
02420 catch (octave_execution_exception)
02421 {
02422 gripe_library_execution_error ();
02423 }
02424 }
02425 else
02426 {
02427 octave_base_value::type_conv_fcn cf = numeric_conversion_function ();
02428
02429 if (cf)
02430 {
02431 octave_base_value *tmp = cf (*rep);
02432
02433 if (tmp)
02434 {
02435 octave_base_value *old_rep = rep;
02436 rep = tmp;
02437
02438 t = type_id ();
02439
02440 f = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
02441
02442 if (f)
02443 {
02444 try
02445 {
02446 f (*rep);
02447 }
02448 catch (octave_execution_exception)
02449 {
02450 gripe_library_execution_error ();
02451 }
02452
02453 if (old_rep && --old_rep->count == 0)
02454 delete old_rep;
02455 }
02456 else
02457 {
02458 if (old_rep)
02459 {
02460 if (--rep->count == 0)
02461 delete rep;
02462
02463 rep = old_rep;
02464 }
02465
02466 gripe_unary_op (octave_value::unary_op_as_string (op),
02467 type_name ());
02468 }
02469 }
02470 else
02471 gripe_unary_op_conversion_failed
02472 (octave_value::unary_op_as_string (op), type_name ());
02473 }
02474 else
02475 gripe_unary_op (octave_value::unary_op_as_string (op), type_name ());
02476 }
02477 }
02478 else
02479 {
02480
02481 int t = type_id ();
02482
02483 octave_value_typeinfo::non_const_unary_op_fcn f = 0;
02484
02485
02486 if (rep->count == 1)
02487 f = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
02488
02489 if (f)
02490 {
02491 try
02492 {
02493 f (*rep);
02494 }
02495 catch (octave_execution_exception)
02496 {
02497 gripe_library_execution_error ();
02498 }
02499 }
02500 else
02501 *this = do_unary_op (op, *this);
02502 }
02503
02504 return *this;
02505 }
02506
02507 octave_value&
02508 octave_value::do_non_const_unary_op (unary_op op, const std::string& type,
02509 const std::list<octave_value_list>& idx)
02510 {
02511 if (idx.empty ())
02512 do_non_const_unary_op (op);
02513 else
02514 {
02515
02516
02517
02518
02519 assign_op assop = unary_op_to_assign_op (op);
02520
02521 assign (assop, type, idx, 1.0);
02522 }
02523
02524 return *this;
02525 }
02526
02527 octave_value::assign_op
02528 octave_value::unary_op_to_assign_op (unary_op op)
02529 {
02530 assign_op binop = unknown_assign_op;
02531
02532 switch (op)
02533 {
02534 case op_incr:
02535 binop = op_add_eq;
02536 break;
02537
02538 case op_decr:
02539 binop = op_sub_eq;
02540 break;
02541
02542 default:
02543 {
02544 std::string on = unary_op_as_string (op);
02545 error ("operator %s: no assign operator found", on.c_str ());
02546 }
02547 }
02548
02549 return binop;
02550 }
02551
02552 octave_value::binary_op
02553 octave_value::op_eq_to_binary_op (assign_op op)
02554 {
02555 binary_op binop = unknown_binary_op;
02556
02557 switch (op)
02558 {
02559 case op_add_eq:
02560 binop = op_add;
02561 break;
02562
02563 case op_sub_eq:
02564 binop = op_sub;
02565 break;
02566
02567 case op_mul_eq:
02568 binop = op_mul;
02569 break;
02570
02571 case op_div_eq:
02572 binop = op_div;
02573 break;
02574
02575 case op_ldiv_eq:
02576 binop = op_ldiv;
02577 break;
02578
02579 case op_pow_eq:
02580 binop = op_pow;
02581 break;
02582
02583 case op_lshift_eq:
02584 binop = op_lshift;
02585 break;
02586
02587 case op_rshift_eq:
02588 binop = op_rshift;
02589 break;
02590
02591 case op_el_mul_eq:
02592 binop = op_el_mul;
02593 break;
02594
02595 case op_el_div_eq:
02596 binop = op_el_div;
02597 break;
02598
02599 case op_el_ldiv_eq:
02600 binop = op_el_ldiv;
02601 break;
02602
02603 case op_el_pow_eq:
02604 binop = op_el_pow;
02605 break;
02606
02607 case op_el_and_eq:
02608 binop = op_el_and;
02609 break;
02610
02611 case op_el_or_eq:
02612 binop = op_el_or;
02613 break;
02614
02615 default:
02616 {
02617 std::string on = assign_op_as_string (op);
02618 error ("operator %s: no binary operator found", on.c_str ());
02619 }
02620 }
02621
02622 return binop;
02623 }
02624
02625 octave_value
02626 octave_value::empty_conv (const std::string& type, const octave_value& rhs)
02627 {
02628 octave_value retval;
02629
02630 if (type.length () > 0)
02631 {
02632 switch (type[0])
02633 {
02634 case '(':
02635 {
02636 if (type.length () > 1 && type[1] == '.')
02637 retval = octave_map ();
02638 else
02639 retval = octave_value (rhs.empty_clone ());
02640 }
02641 break;
02642
02643 case '{':
02644 retval = Cell ();
02645 break;
02646
02647 case '.':
02648 retval = octave_scalar_map ();
02649 break;
02650
02651 default:
02652 panic_impossible ();
02653 }
02654 }
02655 else
02656 retval = octave_value (rhs.empty_clone ());
02657
02658 return retval;
02659 }
02660
02661 void
02662 install_types (void)
02663 {
02664 octave_base_value::register_type ();
02665 octave_cell::register_type ();
02666 octave_scalar::register_type ();
02667 octave_complex::register_type ();
02668 octave_matrix::register_type ();
02669 octave_diag_matrix::register_type ();
02670 octave_complex_matrix::register_type ();
02671 octave_complex_diag_matrix::register_type ();
02672 octave_range::register_type ();
02673 octave_bool::register_type ();
02674 octave_bool_matrix::register_type ();
02675 octave_char_matrix_str::register_type ();
02676 octave_char_matrix_sq_str::register_type ();
02677 octave_int8_scalar::register_type ();
02678 octave_int16_scalar::register_type ();
02679 octave_int32_scalar::register_type ();
02680 octave_int64_scalar::register_type ();
02681 octave_uint8_scalar::register_type ();
02682 octave_uint16_scalar::register_type ();
02683 octave_uint32_scalar::register_type ();
02684 octave_uint64_scalar::register_type ();
02685 octave_int8_matrix::register_type ();
02686 octave_int16_matrix::register_type ();
02687 octave_int32_matrix::register_type ();
02688 octave_int64_matrix::register_type ();
02689 octave_uint8_matrix::register_type ();
02690 octave_uint16_matrix::register_type ();
02691 octave_uint32_matrix::register_type ();
02692 octave_uint64_matrix::register_type ();
02693 octave_sparse_bool_matrix::register_type ();
02694 octave_sparse_matrix::register_type ();
02695 octave_sparse_complex_matrix::register_type ();
02696 octave_struct::register_type ();
02697 octave_scalar_struct::register_type ();
02698 octave_class::register_type ();
02699 octave_cs_list::register_type ();
02700 octave_magic_colon::register_type ();
02701 octave_builtin::register_type ();
02702 octave_user_function::register_type ();
02703 octave_dld_function::register_type ();
02704 octave_fcn_handle::register_type ();
02705 octave_fcn_inline::register_type ();
02706 octave_float_scalar::register_type ();
02707 octave_float_complex::register_type ();
02708 octave_float_matrix::register_type ();
02709 octave_float_diag_matrix::register_type ();
02710 octave_float_complex_matrix::register_type ();
02711 octave_float_complex_diag_matrix::register_type ();
02712 octave_perm_matrix::register_type ();
02713 octave_null_matrix::register_type ();
02714 octave_null_str::register_type ();
02715 octave_null_sq_str::register_type ();
02716 octave_lazy_index::register_type ();
02717 octave_oncleanup::register_type ();
02718 }
02719
02720 DEFUN (sizeof, args, ,
02721 "-*- texinfo -*-\n\
02722 @deftypefn {Built-in Function} {} sizeof (@var{val})\n\
02723 Return the size of @var{val} in bytes.\n\
02724 @seealso{whos}\n\
02725 @end deftypefn")
02726 {
02727 octave_value retval;
02728
02729 if (args.length () == 1)
02730 retval = args(0).byte_size ();
02731 else
02732 print_usage ();
02733
02734 return retval;
02735 }
02736
02737
02738
02739
02740
02741
02742
02743 static void
02744 decode_subscripts (const char* name, const octave_value& arg,
02745 std::string& type_string,
02746 std::list<octave_value_list>& idx)
02747 {
02748 const octave_map m = arg.map_value ();
02749
02750 if (! error_state
02751 && m.nfields () == 2 && m.contains ("type") && m.contains ("subs"))
02752 {
02753 octave_idx_type nel = m.numel ();
02754
02755 type_string = std::string (nel, '\0');
02756 idx = std::list<octave_value_list> ();
02757
02758 if (nel == 0)
02759 return;
02760
02761 const Cell type = m.contents ("type");
02762 const Cell subs = m.contents ("subs");
02763
02764 for (int k = 0; k < nel; k++)
02765 {
02766 std::string item = type(k).string_value ();
02767
02768 if (! error_state)
02769 {
02770 if (item == "{}")
02771 type_string[k] = '{';
02772 else if (item == "()")
02773 type_string[k] = '(';
02774 else if (item == ".")
02775 type_string[k] = '.';
02776 else
02777 {
02778 error("%s: invalid indexing type '%s'", name, item.c_str ());
02779 return;
02780 }
02781 }
02782 else
02783 {
02784 error ("%s: expecting type(%d) to be a character string",
02785 name, k+1);
02786 return;
02787 }
02788
02789 octave_value_list idx_item;
02790
02791 if (subs(k).is_string ())
02792 idx_item(0) = subs(k);
02793 else if (subs(k).is_cell ())
02794 {
02795 Cell subs_cell = subs(k).cell_value ();
02796
02797 for (int n = 0; n < subs_cell.length (); n++)
02798 {
02799 if (subs_cell(n).is_string ()
02800 && subs_cell(n).string_value () == ":")
02801 idx_item(n) = octave_value(octave_value::magic_colon_t);
02802 else
02803 idx_item(n) = subs_cell(n);
02804 }
02805 }
02806 else
02807 {
02808 error ("%s: expecting subs(%d) to be a character string or cell array",
02809 name, k+1);
02810 return;
02811 }
02812
02813 idx.push_back (idx_item);
02814 }
02815 }
02816 else
02817 error ("%s: second argument must be a structure with fields 'type' and 'subs'", name);
02818 }
02819
02820 DEFUN (subsref, args, nargout,
02821 "-*- texinfo -*-\n\
02822 @deftypefn {Built-in Function} {} subsref (@var{val}, @var{idx})\n\
02823 Perform the subscripted element selection operation according to\n\
02824 the subscript specified by @var{idx}.\n\
02825 \n\
02826 The subscript @var{idx} is expected to be a structure array with\n\
02827 fields @samp{type} and @samp{subs}. Valid values for @samp{type}\n\
02828 are @samp{\"()\"}, @samp{\"@{@}\"}, and @samp{\".\"}.\n\
02829 The @samp{subs} field may be either @samp{\":\"} or a cell array\n\
02830 of index values.\n\
02831 \n\
02832 The following example shows how to extract the two first columns of\n\
02833 a matrix\n\
02834 \n\
02835 @example\n\
02836 @group\n\
02837 val = magic(3)\n\
02838 @result{} val = [ 8 1 6\n\
02839 3 5 7\n\
02840 4 9 2 ]\n\
02841 idx.type = \"()\";\n\
02842 idx.subs = @{\":\", 1:2@};\n\
02843 subsref(val, idx)\n\
02844 @result{} [ 8 1\n\
02845 3 5\n\
02846 4 9 ]\n\
02847 @end group\n\
02848 @end example\n\
02849 \n\
02850 @noindent\n\
02851 Note that this is the same as writing @code{val(:,1:2)}.\n\
02852 \n\
02853 If @var{idx} is an empty structure array with fields @samp{type}\n\
02854 and @samp{subs}, return @var{val}.\n\
02855 @seealso{subsasgn, substruct}\n\
02856 @end deftypefn")
02857 {
02858 octave_value_list retval;
02859
02860 if (args.length () == 2)
02861 {
02862 std::string type;
02863 std::list<octave_value_list> idx;
02864
02865 decode_subscripts ("subsref", args(1), type, idx);
02866
02867 if (! error_state)
02868 {
02869 octave_value arg0 = args(0);
02870
02871 if (type.empty ())
02872 retval = arg0;
02873 else
02874 retval = arg0.subsref (type, idx, nargout);
02875 }
02876 }
02877 else
02878 print_usage ();
02879
02880 return retval;
02881 }
02882
02883 DEFUN (subsasgn, args, ,
02884 "-*- texinfo -*-\n\
02885 @deftypefn {Built-in Function} {} subsasgn (@var{val}, @var{idx}, @var{rhs})\n\
02886 Perform the subscripted assignment operation according to\n\
02887 the subscript specified by @var{idx}.\n\
02888 \n\
02889 The subscript @var{idx} is expected to be a structure array with\n\
02890 fields @samp{type} and @samp{subs}. Valid values for @samp{type}\n\
02891 are @samp{\"()\"}, @samp{\"@{@}\"}, and @samp{\".\"}.\n\
02892 The @samp{subs} field may be either @samp{\":\"} or a cell array\n\
02893 of index values.\n\
02894 \n\
02895 The following example shows how to set the two first columns of a\n\
02896 3-by-3 matrix to zero.\n\
02897 \n\
02898 @example\n\
02899 @group\n\
02900 val = magic(3);\n\
02901 idx.type = \"()\";\n\
02902 idx.subs = @{\":\", 1:2@};\n\
02903 subsasgn (val, idx, 0)\n\
02904 @result{} [ 0 0 6\n\
02905 0 0 7\n\
02906 0 0 2 ]\n\
02907 @end group\n\
02908 @end example\n\
02909 \n\
02910 Note that this is the same as writing @code{val(:,1:2) = 0}.\n\
02911 \n\
02912 If @var{idx} is an empty structure array with fields @samp{type}\n\
02913 and @samp{subs}, return @var{rhs}.\n\
02914 @seealso{subsref, substruct}\n\
02915 @end deftypefn")
02916 {
02917 octave_value retval;
02918
02919 if (args.length () == 3)
02920 {
02921 std::string type;
02922 std::list<octave_value_list> idx;
02923
02924 decode_subscripts ("subsasgn", args(1), type, idx);
02925
02926 if (! error_state)
02927 {
02928 if (type.empty ())
02929 {
02930
02931
02932 retval = args(2).storable_value ();
02933 }
02934 else
02935 {
02936 octave_value arg0 = args(0);
02937
02938 arg0.make_unique ();
02939
02940 if (! error_state)
02941 retval= arg0.subsasgn (type, idx, args(2));
02942 }
02943 }
02944 }
02945 else
02946 print_usage ();
02947
02948 return retval;
02949 }
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019 DEFUN (is_sq_string, args, ,
03020 "-*- texinfo -*-\n\
03021 @deftypefn {Built-in Function} {} is_sq_string (@var{x})\n\
03022 Return true if @var{x} is a single-quoted character string.\n\
03023 @seealso{is_dq_string, ischar}\n\
03024 @end deftypefn")
03025 {
03026 octave_value retval;
03027
03028 if (args.length () == 1)
03029 retval = args(0).is_sq_string ();
03030 else
03031 print_usage ();
03032
03033 return retval;
03034 }
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045 DEFUN (is_dq_string, args, ,
03046 "-*- texinfo -*-\n\
03047 @deftypefn {Built-in Function} {} is_dq_string (@var{x})\n\
03048 Return true if @var{x} is a double-quoted character string.\n\
03049 @seealso{is_sq_string, ischar}\n\
03050 @end deftypefn")
03051 {
03052 octave_value retval;
03053
03054 if (args.length () == 1)
03055 retval = args(0).is_dq_string ();
03056 else
03057 print_usage ();
03058
03059 return retval;
03060 }
03061
03062
03063
03064
03065
03066
03067
03068
03069