ov-base.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 Copyright (C) 2009-2010 VZLU Prague
00005 
00006 This file is part of Octave.
00007 
00008 Octave is free software; you can redistribute it and/or modify it
00009 under the terms of the GNU General Public License as published by the
00010 Free Software Foundation; either version 3 of the License, or (at your
00011 option) any later version.
00012 
00013 Octave is distributed in the hope that it will be useful, but WITHOUT
00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Octave; see the file COPYING.  If not, see
00020 <http://www.gnu.org/licenses/>.
00021 
00022 */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027 
00028 #include <climits>
00029 
00030 #include <iostream>
00031 
00032 #include "lo-ieee.h"
00033 #include "lo-mappers.h"
00034 
00035 #include "defun.h"
00036 #include "gripes.h"
00037 #include "oct-map.h"
00038 #include "oct-obj.h"
00039 #include "oct-lvalue.h"
00040 #include "oct-stream.h"
00041 #include "ops.h"
00042 #include "ov-base.h"
00043 #include "ov-cell.h"
00044 #include "ov-ch-mat.h"
00045 #include "ov-complex.h"
00046 #include "ov-cx-mat.h"
00047 #include "ov-range.h"
00048 #include "ov-re-mat.h"
00049 #include "ov-scalar.h"
00050 #include "ov-str-mat.h"
00051 #include "ov-fcn-handle.h"
00052 #include "parse.h"
00053 #include "pr-output.h"
00054 #include "utils.h"
00055 #include "variables.h"
00056 
00057 builtin_type_t btyp_mixed_numeric (builtin_type_t x, builtin_type_t y)
00058 {
00059   builtin_type_t retval = btyp_unknown;
00060 
00061   if (x == btyp_bool)
00062     x = btyp_double;
00063   if (y == btyp_bool)
00064     y = btyp_double;
00065 
00066   if (x <= btyp_float_complex && y <= btyp_float_complex)
00067     retval = static_cast<builtin_type_t> (x | y);
00068   else if (x <= btyp_uint64 && y <= btyp_float)
00069     retval = x;
00070   else if (x <= btyp_float && y <= btyp_uint64)
00071     retval = y;
00072   else if ((x >= btyp_int8 && x <= btyp_int64
00073             && y >= btyp_int8 && y <= btyp_int64)
00074            || (x >= btyp_uint8 && x <= btyp_uint64
00075                && y >= btyp_uint8 && y <= btyp_uint64))
00076     retval = (x > y) ? x : y;
00077 
00078   return retval;
00079 }
00080 
00081 std::string btyp_class_name[btyp_num_types] =
00082 {
00083   "double", "single", "double", "single",
00084   "int8", "int16", "int32", "int64",
00085   "uint8", "uint16", "uint32", "uint64",
00086   "logical", "char",
00087   "struct", "cell", "function_handle"
00088 };
00089 
00090 string_vector
00091 get_builtin_classes (void)
00092 {
00093   static string_vector retval;
00094 
00095   if (retval.is_empty ())
00096     {
00097       int n = btyp_num_types - 2;
00098       retval = string_vector (n);
00099       int j = 0;
00100       for (int i = 0; i < btyp_num_types; i++)
00101         {
00102           builtin_type_t ityp = static_cast<builtin_type_t> (i);
00103           if (ityp != btyp_complex && ityp != btyp_float_complex)
00104             retval(j++) = btyp_class_name[i];
00105         }
00106     }
00107 
00108   return retval;
00109 }
00110 
00111 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_base_value,
00112                                      "<unknown type>", "unknown");
00113 
00114 // TRUE means to perform automatic sparse to real mutation if there
00115 // is memory to be saved
00116 bool Vsparse_auto_mutate = false;
00117 
00118 octave_base_value *
00119 octave_base_value::empty_clone (void) const
00120 {
00121   return resize (dim_vector ()).clone ();
00122 }
00123 
00124 octave_value
00125 octave_base_value::squeeze (void) const
00126 {
00127   std::string nm = type_name ();
00128   error ("squeeze: invalid operation for %s type", nm.c_str ());
00129   return octave_value ();
00130 }
00131 
00132 octave_value
00133 octave_base_value::full_value (void) const
00134 {
00135   gripe_wrong_type_arg ("full: invalid operation for %s type", type_name ());
00136   return octave_value ();
00137 }
00138 
00139 Matrix
00140 octave_base_value::size (void)
00141 {
00142   const dim_vector dv = dims ();
00143   Matrix mdv (1, dv.length ());
00144   for (octave_idx_type i = 0; i < dv.length (); i++)
00145     mdv(i) = dv(i);
00146   return mdv;
00147 }
00148 
00149 octave_idx_type
00150 octave_base_value::numel (const octave_value_list& idx)
00151 {
00152   return dims_to_numel (dims (), idx);
00153 }
00154 
00155 octave_value
00156 octave_base_value::subsref (const std::string&,
00157                             const std::list<octave_value_list>&)
00158 {
00159   std::string nm = type_name ();
00160   error ("can't perform indexing operations for %s type", nm.c_str ());
00161   return octave_value ();
00162 }
00163 
00164 octave_value_list
00165 octave_base_value::subsref (const std::string&,
00166                             const std::list<octave_value_list>&, int)
00167 {
00168   std::string nm = type_name ();
00169   error ("can't perform indexing operations for %s type", nm.c_str ());
00170   return octave_value ();
00171 }
00172 
00173 octave_value
00174 octave_base_value::subsref (const std::string& type,
00175                             const std::list<octave_value_list>& idx,
00176                             bool /* auto_add */)
00177 {
00178   // This way we may get a more meaningful error message.
00179   return subsref (type, idx);
00180 }
00181 
00182 octave_value_list
00183 octave_base_value::subsref (const std::string& type,
00184                             const std::list<octave_value_list>& idx,
00185                             int nargout,
00186                             const std::list<octave_lvalue> *)
00187 {
00188   // Fall back to call without passing lvalue list.
00189   return subsref (type, idx, nargout);
00190 }
00191 
00192 octave_value
00193 octave_base_value::do_index_op (const octave_value_list&, bool)
00194 {
00195   std::string nm = type_name ();
00196   error ("can't perform indexing operations for %s type", nm.c_str ());
00197   return octave_value ();
00198 }
00199 
00200 octave_value_list
00201 octave_base_value::do_multi_index_op (int, const octave_value_list&)
00202 {
00203   std::string nm = type_name ();
00204   error ("can't perform indexing operations for %s type", nm.c_str ());
00205   return octave_value ();
00206 }
00207 
00208 octave_value_list
00209 octave_base_value::do_multi_index_op (int nargout, const octave_value_list& idx,
00210                                       const std::list<octave_lvalue> *)
00211 {
00212   // Fall back.
00213   return do_multi_index_op (nargout, idx);
00214 }
00215 
00216 idx_vector
00217 octave_base_value::index_vector (void) const
00218 {
00219   std::string nm = type_name ();
00220   error ("%s type invalid as index value", nm.c_str ());
00221   return idx_vector ();
00222 }
00223 
00224 octave_value
00225 octave_base_value::subsasgn (const std::string& type,
00226                              const std::list<octave_value_list>& idx,
00227                              const octave_value& rhs)
00228 {
00229   octave_value retval;
00230 
00231   if (is_defined ())
00232     {
00233       if (is_numeric_type ())
00234         {
00235           switch (type[0])
00236             {
00237             case '(':
00238               {
00239                 if (type.length () == 1)
00240                   retval = numeric_assign (type, idx, rhs);
00241                 else if (is_empty ())
00242                   {
00243                     // Allow conversion of empty matrix to some other
00244                     // type in cases like
00245                     //
00246                     //  x = []; x(i).f = rhs
00247 
00248                     octave_value tmp = octave_value::empty_conv (type, rhs);
00249 
00250                     retval = tmp.subsasgn (type, idx, rhs);
00251                   }
00252                 else
00253                   {
00254                     std::string nm = type_name ();
00255                     error ("in indexed assignment of %s, last rhs index must be ()",
00256                            nm.c_str ());
00257                   }
00258               }
00259               break;
00260 
00261             case '{':
00262             case '.':
00263               {
00264                 std::string nm = type_name ();
00265                 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00266               }
00267               break;
00268 
00269             default:
00270               panic_impossible ();
00271             }
00272         }
00273       else
00274         {
00275           std::string nm = type_name ();
00276           error ("can't perform indexed assignment for %s type", nm.c_str ());
00277         }
00278     }
00279   else
00280     {
00281       // Create new object of appropriate type for given index and rhs
00282       // types and then call undef_subsasgn for that object.
00283 
00284       octave_value tmp = octave_value::empty_conv (type, rhs);
00285 
00286       retval = tmp.undef_subsasgn (type, idx, rhs);
00287     }
00288 
00289   return retval;
00290 }
00291 
00292 octave_value
00293 octave_base_value::undef_subsasgn (const std::string& type,
00294                                    const std::list<octave_value_list>& idx,
00295                                    const octave_value& rhs)
00296 {
00297   // In most cases, undef_subsasgn is handled the sams as subsasgn.  One
00298   // exception is octave_class objects.
00299 
00300   return subsasgn (type, idx, rhs);
00301 }
00302 
00303 octave_idx_type
00304 octave_base_value::nnz (void) const
00305 {
00306   gripe_wrong_type_arg ("octave_base_value::nnz ()", type_name ());
00307   return -1;
00308 }
00309 
00310 octave_idx_type
00311 octave_base_value::nzmax (void) const
00312 {
00313   return numel ();
00314 }
00315 
00316 octave_idx_type
00317 octave_base_value::nfields (void) const
00318 {
00319   gripe_wrong_type_arg ("octave_base_value::nfields ()", type_name ());
00320   return -1;
00321 }
00322 
00323 octave_value
00324 octave_base_value::reshape (const dim_vector&) const
00325 {
00326   gripe_wrong_type_arg ("octave_base_value::reshape ()", type_name ());
00327   return octave_value ();
00328 }
00329 
00330 octave_value
00331 octave_base_value::permute (const Array<int>&, bool) const
00332 {
00333   gripe_wrong_type_arg ("octave_base_value::permute ()", type_name ());
00334   return octave_value ();
00335 }
00336 
00337 octave_value
00338 octave_base_value::resize (const dim_vector&, bool) const
00339 {
00340   gripe_wrong_type_arg ("octave_base_value::resize ()", type_name ());
00341   return octave_value ();
00342 }
00343 
00344 MatrixType
00345 octave_base_value::matrix_type (void) const
00346 {
00347   gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
00348   return MatrixType ();
00349 }
00350 
00351 MatrixType
00352 octave_base_value::matrix_type (const MatrixType&) const
00353 {
00354   gripe_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
00355   return MatrixType ();
00356 }
00357 
00358 octave_value
00359 octave_base_value::all (int) const
00360 {
00361   return 0.0;
00362 }
00363 
00364 octave_value
00365 octave_base_value::any (int) const
00366 {
00367   return 0.0;
00368 }
00369 
00370 octave_value
00371 octave_base_value::convert_to_str (bool pad, bool force, char type) const
00372 {
00373   octave_value retval = convert_to_str_internal (pad, force, type);
00374 
00375   if (! force && is_numeric_type ())
00376     gripe_implicit_conversion ("Octave:num-to-str",
00377                                type_name (), retval.type_name ());
00378 
00379   return retval;
00380 }
00381 
00382 octave_value
00383 octave_base_value::convert_to_str_internal (bool, bool, char) const
00384 {
00385   gripe_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
00386                         type_name ());
00387   return octave_value ();
00388 }
00389 
00390 void
00391 octave_base_value::convert_to_row_or_column_vector (void)
00392 {
00393   gripe_wrong_type_arg
00394     ("octave_base_value::convert_to_row_or_column_vector ()",
00395      type_name ());
00396 }
00397 
00398 void
00399 octave_base_value::print (std::ostream&, bool) const
00400 {
00401   gripe_wrong_type_arg ("octave_base_value::print ()", type_name ());
00402 }
00403 
00404 void
00405 octave_base_value::print_raw (std::ostream&, bool) const
00406 {
00407   gripe_wrong_type_arg ("octave_base_value::print_raw ()", type_name ());
00408 }
00409 
00410 bool
00411 octave_base_value::print_name_tag (std::ostream& os, const std::string& name) const
00412 {
00413   bool retval = false;
00414 
00415   indent (os);
00416 
00417   if (print_as_scalar ())
00418     os << name << " = ";
00419   else
00420     {
00421       os << name << " =";
00422       newline (os);
00423       if (! Vcompact_format)
00424         newline (os);
00425 
00426       retval = true;
00427     }
00428 
00429   return retval;
00430 }
00431 
00432 void
00433 octave_base_value::print_with_name (std::ostream& output_buf,
00434                                     const std::string& name,
00435                                     bool print_padding)
00436 {
00437   bool pad_after = print_name_tag (output_buf, name);
00438 
00439   print (output_buf);
00440 
00441   if (print_padding  && pad_after && ! Vcompact_format)
00442     newline (output_buf);
00443 }
00444 
00445 void
00446 octave_base_value::print_info (std::ostream& os,
00447                                const std::string& /* prefix */) const
00448 {
00449   os << "no info for type: " << type_name () << "\n";
00450 }
00451 
00452 #define INT_CONV_METHOD(T, F, MIN_LIMIT, MAX_LIMIT) \
00453   T \
00454   octave_base_value::F ## _value (bool require_int, bool frc_str_conv) const \
00455   { \
00456     T retval = 0; \
00457  \
00458     double d = double_value (frc_str_conv); \
00459  \
00460     if (! error_state) \
00461       { \
00462         if (require_int && D_NINT (d) != d) \
00463           error_with_cfn ("conversion of %g to " #T " value failed", d); \
00464         else if (d < MIN_LIMIT) \
00465           retval = MIN_LIMIT; \
00466         else if (d > MAX_LIMIT) \
00467           retval = MAX_LIMIT; \
00468         else \
00469           retval = static_cast<T> (::fix (d));  \
00470       } \
00471     else \
00472       gripe_wrong_type_arg ("octave_base_value::" #F "_value ()", \
00473                             type_name ()); \
00474  \
00475     return retval; \
00476   }
00477 
00478 INT_CONV_METHOD (short int, short, SHRT_MIN, SHRT_MAX)
00479 INT_CONV_METHOD (unsigned short int, ushort, 0, USHRT_MAX)
00480 
00481 INT_CONV_METHOD (int, int, INT_MIN, INT_MAX)
00482 INT_CONV_METHOD (unsigned int, uint, 0, UINT_MAX)
00483 
00484 INT_CONV_METHOD (long int, long, LONG_MIN, LONG_MAX)
00485 INT_CONV_METHOD (unsigned long int, ulong, 0, ULONG_MAX)
00486 
00487 int
00488 octave_base_value::nint_value (bool frc_str_conv) const
00489 {
00490   int retval = 0;
00491 
00492   double d = double_value (frc_str_conv);
00493 
00494   if (! error_state)
00495     {
00496       if (xisnan (d))
00497         {
00498           error ("conversion of NaN to integer value failed");
00499           return retval;
00500         }
00501 
00502       retval = static_cast<int> (::fix (d));
00503     }
00504   else
00505     gripe_wrong_type_arg ("octave_base_value::nint_value ()", type_name ());
00506 
00507   return retval;
00508 }
00509 
00510 double
00511 octave_base_value::double_value (bool) const
00512 {
00513   double retval = lo_ieee_nan_value ();
00514   gripe_wrong_type_arg ("octave_base_value::double_value ()", type_name ());
00515   return retval;
00516 }
00517 
00518 float
00519 octave_base_value::float_value (bool) const
00520 {
00521   float retval = lo_ieee_float_nan_value ();
00522   gripe_wrong_type_arg ("octave_base_value::float_value ()", type_name ());
00523   return retval;
00524 }
00525 
00526 Cell
00527 octave_base_value::cell_value () const
00528 {
00529   Cell retval;
00530   gripe_wrong_type_arg ("octave_base_value::cell_value()", type_name ());
00531   return retval;
00532 }
00533 
00534 Matrix
00535 octave_base_value::matrix_value (bool) const
00536 {
00537   Matrix retval;
00538   gripe_wrong_type_arg ("octave_base_value::matrix_value()", type_name ());
00539   return retval;
00540 }
00541 
00542 FloatMatrix
00543 octave_base_value::float_matrix_value (bool) const
00544 {
00545   FloatMatrix retval;
00546   gripe_wrong_type_arg ("octave_base_value::float_matrix_value()", type_name ());
00547   return retval;
00548 }
00549 
00550 NDArray
00551 octave_base_value::array_value (bool) const
00552 {
00553   FloatNDArray retval;
00554   gripe_wrong_type_arg ("octave_base_value::array_value()", type_name ());
00555   return retval;
00556 }
00557 
00558 FloatNDArray
00559 octave_base_value::float_array_value (bool) const
00560 {
00561   FloatNDArray retval;
00562   gripe_wrong_type_arg ("octave_base_value::float_array_value()", type_name ());
00563   return retval;
00564 }
00565 
00566 Complex
00567 octave_base_value::complex_value (bool) const
00568 {
00569   double tmp = lo_ieee_nan_value ();
00570   Complex retval (tmp, tmp);
00571   gripe_wrong_type_arg ("octave_base_value::complex_value()", type_name ());
00572   return retval;
00573 }
00574 
00575 FloatComplex
00576 octave_base_value::float_complex_value (bool) const
00577 {
00578   float tmp = lo_ieee_float_nan_value ();
00579   FloatComplex retval (tmp, tmp);
00580   gripe_wrong_type_arg ("octave_base_value::float_complex_value()", type_name ());
00581   return retval;
00582 }
00583 
00584 ComplexMatrix
00585 octave_base_value::complex_matrix_value (bool) const
00586 {
00587   ComplexMatrix retval;
00588   gripe_wrong_type_arg ("octave_base_value::complex_matrix_value()",
00589                         type_name ());
00590   return retval;
00591 }
00592 
00593 FloatComplexMatrix
00594 octave_base_value::float_complex_matrix_value (bool) const
00595 {
00596   FloatComplexMatrix retval;
00597   gripe_wrong_type_arg ("octave_base_value::float_complex_matrix_value()",
00598                         type_name ());
00599   return retval;
00600 }
00601 
00602 ComplexNDArray
00603 octave_base_value::complex_array_value (bool) const
00604 {
00605   ComplexNDArray retval;
00606   gripe_wrong_type_arg ("octave_base_value::complex_array_value()",
00607                         type_name ());
00608   return retval;
00609 }
00610 
00611 FloatComplexNDArray
00612 octave_base_value::float_complex_array_value (bool) const
00613 {
00614   FloatComplexNDArray retval;
00615   gripe_wrong_type_arg ("octave_base_value::float_complex_array_value()",
00616                         type_name ());
00617   return retval;
00618 }
00619 
00620 bool
00621 octave_base_value::bool_value (bool) const
00622 {
00623   bool retval = false;
00624   gripe_wrong_type_arg ("octave_base_value::bool_value()", type_name ());
00625   return retval;
00626 }
00627 
00628 boolMatrix
00629 octave_base_value::bool_matrix_value (bool) const
00630 {
00631   boolMatrix retval;
00632   gripe_wrong_type_arg ("octave_base_value::bool_matrix_value()",
00633                         type_name ());
00634   return retval;
00635 }
00636 
00637 boolNDArray
00638 octave_base_value::bool_array_value (bool) const
00639 {
00640   boolNDArray retval;
00641   gripe_wrong_type_arg ("octave_base_value::bool_array_value()",
00642                         type_name ());
00643   return retval;
00644 }
00645 
00646 charMatrix
00647 octave_base_value::char_matrix_value (bool force) const
00648 {
00649   charMatrix retval;
00650 
00651   octave_value tmp = convert_to_str (false, force);
00652 
00653   if (! error_state)
00654     retval = tmp.char_matrix_value ();
00655 
00656   return retval;
00657 }
00658 
00659 charNDArray
00660 octave_base_value::char_array_value (bool) const
00661 {
00662   charNDArray retval;
00663   gripe_wrong_type_arg ("octave_base_value::char_array_value()",
00664                         type_name ());
00665   return retval;
00666 }
00667 
00668 SparseMatrix
00669 octave_base_value::sparse_matrix_value (bool) const
00670 {
00671   SparseMatrix retval;
00672   gripe_wrong_type_arg ("octave_base_value::sparse_matrix_value()", type_name ());
00673   return retval;
00674 }
00675 
00676 SparseComplexMatrix
00677 octave_base_value::sparse_complex_matrix_value (bool) const
00678 {
00679   SparseComplexMatrix retval;
00680   gripe_wrong_type_arg ("octave_base_value::sparse_complex_matrix_value()", type_name ());
00681   return retval;
00682 }
00683 
00684 SparseBoolMatrix
00685 octave_base_value::sparse_bool_matrix_value (bool) const
00686 {
00687   SparseBoolMatrix retval;
00688   gripe_wrong_type_arg ("octave_base_value::sparse_bool_matrix_value()", type_name ());
00689   return retval;
00690 }
00691 
00692 DiagMatrix
00693 octave_base_value::diag_matrix_value (bool) const
00694 {
00695   DiagMatrix retval;
00696   gripe_wrong_type_arg ("octave_base_value::diag_matrix_value()", type_name ());
00697   return retval;
00698 }
00699 
00700 FloatDiagMatrix
00701 octave_base_value::float_diag_matrix_value (bool) const
00702 {
00703   FloatDiagMatrix retval;
00704   gripe_wrong_type_arg ("octave_base_value::float_diag_matrix_value()", type_name ());
00705   return retval;
00706 }
00707 
00708 ComplexDiagMatrix
00709 octave_base_value::complex_diag_matrix_value (bool) const
00710 {
00711   ComplexDiagMatrix retval;
00712   gripe_wrong_type_arg ("octave_base_value::complex_diag_matrix_value()", type_name ());
00713   return retval;
00714 }
00715 
00716 FloatComplexDiagMatrix
00717 octave_base_value::float_complex_diag_matrix_value (bool) const
00718 {
00719   FloatComplexDiagMatrix retval;
00720   gripe_wrong_type_arg ("octave_base_value::float_complex_diag_matrix_value()", type_name ());
00721   return retval;
00722 }
00723 
00724 PermMatrix
00725 octave_base_value::perm_matrix_value (void) const
00726 {
00727   PermMatrix retval;
00728   gripe_wrong_type_arg ("octave_base_value::perm_matrix_value()", type_name ());
00729   return retval;
00730 }
00731 
00732 octave_int8
00733 octave_base_value::int8_scalar_value (void) const
00734 {
00735   octave_int8 retval;
00736   gripe_wrong_type_arg ("octave_base_value::int8_scalar_value()",
00737                         type_name ());
00738   return retval;
00739 }
00740 
00741 octave_int16
00742 octave_base_value::int16_scalar_value (void) const
00743 {
00744   octave_int16 retval;
00745   gripe_wrong_type_arg ("octave_base_value::int16_scalar_value()",
00746                         type_name ());
00747   return retval;
00748 }
00749 
00750 octave_int32
00751 octave_base_value::int32_scalar_value (void) const
00752 {
00753   octave_int32 retval;
00754   gripe_wrong_type_arg ("octave_base_value::int32_scalar_value()",
00755                         type_name ());
00756   return retval;
00757 }
00758 
00759 octave_int64
00760 octave_base_value::int64_scalar_value (void) const
00761 {
00762   octave_int64 retval;
00763   gripe_wrong_type_arg ("octave_base_value::int64_scalar_value()",
00764                         type_name ());
00765   return retval;
00766 }
00767 
00768 octave_uint8
00769 octave_base_value::uint8_scalar_value (void) const
00770 {
00771   octave_uint8 retval;
00772   gripe_wrong_type_arg ("octave_base_value::uint8_scalar_value()",
00773                         type_name ());
00774   return retval;
00775 }
00776 
00777 octave_uint16
00778 octave_base_value::uint16_scalar_value (void) const
00779 {
00780   octave_uint16 retval;
00781   gripe_wrong_type_arg ("octave_base_value::uint16_scalar_value()",
00782                         type_name ());
00783   return retval;
00784 }
00785 
00786 octave_uint32
00787 octave_base_value::uint32_scalar_value (void) const
00788 {
00789   octave_uint32 retval;
00790   gripe_wrong_type_arg ("octave_base_value::uint32_scalar_value()",
00791                         type_name ());
00792   return retval;
00793 }
00794 
00795 octave_uint64
00796 octave_base_value::uint64_scalar_value (void) const
00797 {
00798   octave_uint64 retval;
00799   gripe_wrong_type_arg ("octave_base_value::uint64_scalar_value()",
00800                         type_name ());
00801   return retval;
00802 }
00803 
00804 int8NDArray
00805 octave_base_value::int8_array_value (void) const
00806 {
00807   int8NDArray retval;
00808   gripe_wrong_type_arg ("octave_base_value::int8_array_value()",
00809                         type_name ());
00810   return retval;
00811 }
00812 
00813 int16NDArray
00814 octave_base_value::int16_array_value (void) const
00815 {
00816   int16NDArray retval;
00817   gripe_wrong_type_arg ("octave_base_value::int16_array_value()",
00818                         type_name ());
00819   return retval;
00820 }
00821 
00822 int32NDArray
00823 octave_base_value::int32_array_value (void) const
00824 {
00825   int32NDArray retval;
00826   gripe_wrong_type_arg ("octave_base_value::int32_array_value()",
00827                         type_name ());
00828   return retval;
00829 }
00830 
00831 int64NDArray
00832 octave_base_value::int64_array_value (void) const
00833 {
00834   int64NDArray retval;
00835   gripe_wrong_type_arg ("octave_base_value::int64_array_value()",
00836                         type_name ());
00837   return retval;
00838 }
00839 
00840 uint8NDArray
00841 octave_base_value::uint8_array_value (void) const
00842 {
00843   uint8NDArray retval;
00844   gripe_wrong_type_arg ("octave_base_value::uint8_array_value()",
00845                         type_name ());
00846   return retval;
00847 }
00848 
00849 uint16NDArray
00850 octave_base_value::uint16_array_value (void) const
00851 {
00852   uint16NDArray retval;
00853   gripe_wrong_type_arg ("octave_base_value::uint16_array_value()",
00854                         type_name ());
00855   return retval;
00856 }
00857 
00858 uint32NDArray
00859 octave_base_value::uint32_array_value (void) const
00860 {
00861   uint32NDArray retval;
00862   gripe_wrong_type_arg ("octave_base_value::uint32_array_value()",
00863                         type_name ());
00864   return retval;
00865 }
00866 
00867 uint64NDArray
00868 octave_base_value::uint64_array_value (void) const
00869 {
00870   uint64NDArray retval;
00871   gripe_wrong_type_arg ("octave_base_value::uint64_array_value()",
00872                         type_name ());
00873   return retval;
00874 }
00875 
00876 string_vector
00877 octave_base_value::all_strings (bool pad) const
00878 {
00879   string_vector retval;
00880 
00881   octave_value tmp = convert_to_str (pad, true);
00882 
00883   if (! error_state)
00884     retval = tmp.all_strings ();
00885 
00886   return retval;
00887 }
00888 
00889 std::string
00890 octave_base_value::string_value (bool force) const
00891 {
00892   std::string retval;
00893 
00894   octave_value tmp = convert_to_str (force);
00895 
00896   if (! error_state)
00897     retval = tmp.string_value ();
00898 
00899   return retval;
00900 }
00901 
00902 Array<std::string>
00903 octave_base_value::cellstr_value (void) const
00904 {
00905   Array<std::string> retval;
00906   gripe_wrong_type_arg ("octave_base_value::cellstry_value()",
00907                         type_name ());
00908   return retval;
00909 }
00910 
00911 Range
00912 octave_base_value::range_value (void) const
00913 {
00914   Range retval;
00915   gripe_wrong_type_arg ("octave_base_value::range_value()", type_name ());
00916   return retval;
00917 }
00918 
00919 octave_map
00920 octave_base_value::map_value (void) const
00921 {
00922   octave_map retval;
00923   gripe_wrong_type_arg ("octave_base_value::map_value()", type_name ());
00924   return retval;
00925 }
00926 
00927 octave_scalar_map
00928 octave_base_value::scalar_map_value (void) const
00929 {
00930   octave_map tmp = map_value ();
00931 
00932   if (tmp.numel () == 1)
00933     return tmp.checkelem (0);
00934   else
00935     {
00936       if (! error_state)
00937         error ("invalid conversion of multi-dimensional struct to scalar struct");
00938 
00939       return octave_scalar_map ();
00940     }
00941 }
00942 
00943 string_vector
00944 octave_base_value::map_keys (void) const
00945 {
00946   string_vector retval;
00947   gripe_wrong_type_arg ("octave_base_value::map_keys()", type_name ());
00948   return retval;
00949 }
00950 
00951 size_t
00952 octave_base_value::nparents (void) const
00953 {
00954   size_t retval = 0;
00955   gripe_wrong_type_arg ("octave_base_value::nparents()", type_name ());
00956   return retval;
00957 }
00958 
00959 std::list<std::string>
00960 octave_base_value::parent_class_name_list (void) const
00961 {
00962   std::list<std::string> retval;
00963   gripe_wrong_type_arg ("octave_base_value::parent_class_name_list()",
00964                         type_name ());
00965   return retval;
00966 }
00967 
00968 string_vector
00969 octave_base_value::parent_class_names (void) const
00970 {
00971   string_vector retval;
00972   gripe_wrong_type_arg ("octave_base_value::parent_class_names()",
00973                         type_name ());
00974   return retval;
00975 }
00976 
00977 octave_function *
00978 octave_base_value::function_value (bool silent)
00979 {
00980   octave_function *retval = 0;
00981 
00982   if (! silent)
00983     gripe_wrong_type_arg ("octave_base_value::function_value()",
00984                           type_name ());
00985   return retval;
00986 }
00987 
00988 octave_user_function *
00989 octave_base_value::user_function_value (bool silent)
00990 {
00991   octave_user_function *retval = 0;
00992 
00993   if (! silent)
00994     gripe_wrong_type_arg ("octave_base_value::user_function_value()",
00995                           type_name ());
00996   return retval;
00997 }
00998 
00999 octave_user_script *
01000 octave_base_value::user_script_value (bool silent)
01001 {
01002   octave_user_script *retval = 0;
01003 
01004   if (! silent)
01005     gripe_wrong_type_arg ("octave_base_value::user_script_value()",
01006                           type_name ());
01007   return retval;
01008 }
01009 
01010 octave_user_code *
01011 octave_base_value::user_code_value (bool silent)
01012 {
01013   octave_user_code *retval = 0;
01014 
01015   if (! silent)
01016     gripe_wrong_type_arg ("octave_base_value::user_code_value()",
01017                           type_name ());
01018   return retval;
01019 }
01020 
01021 octave_fcn_handle *
01022 octave_base_value::fcn_handle_value (bool silent)
01023 {
01024   octave_fcn_handle *retval = 0;
01025 
01026   if (! silent)
01027     gripe_wrong_type_arg ("octave_base_value::fcn_handle_value()",
01028                           type_name ());
01029   return retval;
01030 }
01031 
01032 octave_fcn_inline *
01033 octave_base_value::fcn_inline_value (bool silent)
01034 {
01035   octave_fcn_inline *retval = 0;
01036 
01037   if (! silent)
01038     gripe_wrong_type_arg ("octave_base_value::fcn_inline_value()",
01039                           type_name ());
01040   return retval;
01041 }
01042 
01043 octave_value_list
01044 octave_base_value::list_value (void) const
01045 {
01046   octave_value_list retval;
01047   gripe_wrong_type_arg ("octave_base_value::list_value()", type_name ());
01048   return retval;
01049 }
01050 
01051 bool
01052 octave_base_value::save_ascii (std::ostream&)
01053 {
01054   gripe_wrong_type_arg ("octave_base_value::save_ascii()", type_name ());
01055   return false;
01056 }
01057 
01058 bool
01059 octave_base_value::load_ascii (std::istream&)
01060 {
01061   gripe_wrong_type_arg ("octave_base_value::load_ascii()", type_name ());
01062   return false;
01063 }
01064 
01065 bool
01066 octave_base_value::save_binary (std::ostream&, bool&)
01067 {
01068   gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
01069   return false;
01070 }
01071 
01072 bool
01073 octave_base_value::load_binary (std::istream&, bool,
01074                                 oct_mach_info::float_format)
01075 {
01076   gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
01077   return false;
01078 }
01079 
01080 #if defined (HAVE_HDF5)
01081 
01082 bool
01083 octave_base_value::save_hdf5 (hid_t, const char *, bool)
01084 {
01085   gripe_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
01086 
01087   return false;
01088 }
01089 
01090 bool
01091 octave_base_value::load_hdf5 (hid_t, const char *)
01092 {
01093   gripe_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
01094 
01095   return false;
01096 }
01097 
01098 #endif
01099 
01100 int
01101 octave_base_value::write (octave_stream&, int, oct_data_conv::data_type,
01102                           int, oct_mach_info::float_format) const
01103 {
01104   gripe_wrong_type_arg ("octave_base_value::write()", type_name ());
01105 
01106   return false;
01107 }
01108 
01109 mxArray *
01110 octave_base_value::as_mxArray (void) const
01111 {
01112   return 0;
01113 }
01114 
01115 octave_value
01116 octave_base_value::diag (octave_idx_type) const
01117 {
01118   gripe_wrong_type_arg ("octave_base_value::diag ()", type_name ());
01119 
01120   return octave_value();
01121 }
01122 
01123 octave_value
01124 octave_base_value::sort (octave_idx_type, sortmode) const
01125 {
01126   gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ());
01127 
01128   return octave_value();
01129 }
01130 
01131 octave_value
01132 octave_base_value::sort (Array<octave_idx_type> &,
01133                          octave_idx_type, sortmode) const
01134 {
01135   gripe_wrong_type_arg ("octave_base_value::sort ()", type_name ());
01136 
01137   return octave_value();
01138 }
01139 
01140 sortmode
01141 octave_base_value::is_sorted (sortmode) const
01142 {
01143   gripe_wrong_type_arg ("octave_base_value::is_sorted ()", type_name ());
01144 
01145   return UNSORTED;
01146 }
01147 
01148 Array<octave_idx_type>
01149 octave_base_value::sort_rows_idx (sortmode) const
01150 {
01151   gripe_wrong_type_arg ("octave_base_value::sort_rows_idx ()", type_name ());
01152 
01153   return Array<octave_idx_type> ();
01154 }
01155 
01156 sortmode
01157 octave_base_value::is_sorted_rows (sortmode) const
01158 {
01159   gripe_wrong_type_arg ("octave_base_value::is_sorted_rows ()", type_name ());
01160 
01161   return UNSORTED;
01162 }
01163 
01164 
01165 const char *
01166 octave_base_value::get_umap_name (unary_mapper_t umap)
01167 {
01168   static const char *names[num_unary_mappers] =
01169     {
01170       "abs",
01171       "acos",
01172       "acosh",
01173       "angle",
01174       "arg",
01175       "asin",
01176       "asinh",
01177       "atan",
01178       "atanh",
01179       "cbrt",
01180       "ceil",
01181       "conj",
01182       "cos",
01183       "cosh",
01184       "erf",
01185       "erfinv",
01186       "erfc",
01187       "exp",
01188       "expm1",
01189       "finite",
01190       "fix",
01191       "floor",
01192       "gamma",
01193       "imag",
01194       "isinf",
01195       "isna",
01196       "isnan",
01197       "lgamma",
01198       "log",
01199       "log2",
01200       "log10",
01201       "log1p",
01202       "real",
01203       "round",
01204       "roundb",
01205       "signum",
01206       "sin",
01207       "sinh",
01208       "sqrt",
01209       "tan",
01210       "tanh",
01211       "isalnum",
01212       "isalpha",
01213       "isascii",
01214       "iscntrl",
01215       "isdigit",
01216       "isgraph",
01217       "islower",
01218       "isprint",
01219       "ispunct",
01220       "isspace",
01221       "isupper",
01222       "isxdigit",
01223       "toascii",
01224       "tolower",
01225       "toupper"
01226     };
01227 
01228   if (umap < 0 || umap >= num_unary_mappers)
01229     return "unknown";
01230   else
01231     return names[umap];
01232 }
01233 
01234 octave_value
01235 octave_base_value::map (unary_mapper_t umap) const
01236 {
01237   error ("%s: not defined for %s", get_umap_name (umap), type_name ().c_str ());
01238   return octave_value ();
01239 }
01240 
01241 void
01242 octave_base_value::lock (void)
01243 {
01244   gripe_wrong_type_arg ("octave_base_value::lock ()", type_name ());
01245 }
01246 
01247 void
01248 octave_base_value::unlock (void)
01249 {
01250   gripe_wrong_type_arg ("octave_base_value::unlock ()", type_name ());
01251 }
01252 
01253 void
01254 octave_base_value::dump (std::ostream& os) const
01255 {
01256   dim_vector dv = this->dims ();
01257 
01258   os << "class: " << this->class_name ()
01259      << " type: " << this->type_name ()
01260      << " dims: " << dv.str ();
01261 }
01262 
01263 static void
01264 gripe_indexed_assignment (const std::string& tn1, const std::string& tn2)
01265 {
01266   error ("assignment of '%s' to indexed '%s' not implemented",
01267          tn2.c_str (), tn1.c_str ());
01268 }
01269 
01270 static void
01271 gripe_assign_conversion_failed (const std::string& tn1,
01272                                 const std::string& tn2)
01273 {
01274   error ("type conversion for assignment of '%s' to indexed '%s' failed",
01275          tn2.c_str (), tn1.c_str ());
01276 }
01277 
01278 static void
01279 gripe_no_conversion (const std::string& on, const std::string& tn1,
01280                      const std::string& tn2)
01281 {
01282   error ("operator %s: no conversion for assignment of '%s' to indexed '%s'",
01283          on.c_str (), tn2.c_str (), tn1.c_str ());
01284 }
01285 
01286 octave_value
01287 octave_base_value::numeric_assign (const std::string& type,
01288                                    const std::list<octave_value_list>& idx,
01289                                    const octave_value& rhs)
01290 {
01291   octave_value retval;
01292 
01293   if (idx.front ().empty ())
01294     {
01295       error ("missing index in indexed assignment");
01296       return retval;
01297     }
01298 
01299   int t_lhs = type_id ();
01300   int t_rhs = rhs.type_id ();
01301 
01302   octave_value_typeinfo::assign_op_fcn f
01303     = octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
01304                                                t_lhs, t_rhs);
01305 
01306   bool done = false;
01307 
01308   if (f)
01309     {
01310       f (*this, idx.front (), rhs.get_rep ());
01311 
01312       done = (! error_state);
01313     }
01314 
01315   if (done)
01316     {
01317       count++;
01318       retval = octave_value (this);
01319     }
01320   else
01321     {
01322       int t_result
01323         = octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
01324 
01325       if (t_result >= 0)
01326         {
01327           octave_base_value::type_conv_fcn cf
01328             = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
01329 
01330           if (cf)
01331             {
01332               octave_base_value *tmp = cf (*this);
01333 
01334               if (tmp)
01335                 {
01336                   octave_value val (tmp);
01337 
01338                   retval = val.subsasgn (type, idx, rhs);
01339 
01340                   done = (! error_state);
01341                 }
01342               else
01343                 gripe_assign_conversion_failed (type_name (),
01344                                                 rhs.type_name ());
01345             }
01346           else
01347             gripe_indexed_assignment (type_name (), rhs.type_name ());
01348         }
01349 
01350       if (! (done || error_state))
01351         {
01352           octave_value tmp_rhs;
01353 
01354           octave_base_value::type_conv_info cf_rhs
01355             = rhs.numeric_conversion_function ();
01356 
01357           octave_base_value::type_conv_info cf_this
01358             = numeric_conversion_function ();
01359 
01360           // Try biased (one-sided) conversions first.
01361           if (cf_rhs.type_id () >= 0
01362               && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
01363                                                            t_lhs, cf_rhs.type_id ())
01364                   || octave_value_typeinfo::lookup_pref_assign_conv (t_lhs,
01365                                                                      cf_rhs.type_id ()) >= 0))
01366             cf_this = 0;
01367           else if (cf_this.type_id () >= 0
01368                    && (octave_value_typeinfo::lookup_assign_op (octave_value::op_asn_eq,
01369                                                                 cf_this.type_id (), t_rhs)
01370                        || octave_value_typeinfo::lookup_pref_assign_conv (cf_this.type_id (),
01371                                                                           t_rhs) >= 0))
01372             cf_rhs = 0;
01373 
01374           if (cf_rhs)
01375             {
01376               octave_base_value *tmp = cf_rhs (rhs.get_rep ());
01377 
01378               if (tmp)
01379                 tmp_rhs = octave_value (tmp);
01380               else
01381                 {
01382                   gripe_assign_conversion_failed (type_name (),
01383                                                   rhs.type_name ());
01384                   return octave_value ();
01385                 }
01386             }
01387           else
01388             tmp_rhs = rhs;
01389 
01390           count++;
01391           octave_value tmp_lhs = octave_value (this);
01392 
01393           if (cf_this)
01394             {
01395               octave_base_value *tmp = cf_this (*this);
01396 
01397               if (tmp)
01398                 tmp_lhs = octave_value (tmp);
01399               else
01400                 {
01401                   gripe_assign_conversion_failed (type_name (),
01402                                                   rhs.type_name ());
01403                   return octave_value ();
01404                 }
01405             }
01406 
01407           if (cf_this || cf_rhs)
01408             {
01409               retval = tmp_lhs.subsasgn (type, idx, tmp_rhs);
01410 
01411               done = (! error_state);
01412             }
01413           else
01414             gripe_no_conversion (octave_value::assign_op_as_string (octave_value::op_asn_eq),
01415                                  type_name (), rhs.type_name ());
01416         }
01417     }
01418 
01419   // The assignment may have converted to a type that is wider than
01420   // necessary.
01421 
01422   retval.maybe_mutate ();
01423 
01424   return retval;
01425 }
01426 
01427 // Current indentation.
01428 int octave_base_value::curr_print_indent_level = 0;
01429 
01430 // TRUE means we are at the beginning of a line.
01431 bool octave_base_value::beginning_of_line = true;
01432 
01433 // Each print() function should call this before printing anything.
01434 //
01435 // This doesn't need to be fast, but isn't there a better way?
01436 
01437 void
01438 octave_base_value::indent (std::ostream& os) const
01439 {
01440   assert (curr_print_indent_level >= 0);
01441 
01442   if (beginning_of_line)
01443     {
01444       // FIXME -- do we need this?
01445       // os << prefix;
01446 
01447       for (int i = 0; i < curr_print_indent_level; i++)
01448         os << " ";
01449 
01450       beginning_of_line = false;
01451     }
01452 }
01453 
01454 // All print() functions should use this to print new lines.
01455 
01456 void
01457 octave_base_value::newline (std::ostream& os) const
01458 {
01459   os << "\n";
01460 
01461   beginning_of_line = true;
01462 }
01463 
01464 // For ressetting print state.
01465 
01466 void
01467 octave_base_value::reset (void) const
01468 {
01469   beginning_of_line = true;
01470   curr_print_indent_level = 0;
01471 }
01472 
01473 
01474 octave_value
01475 octave_base_value::fast_elem_extract (octave_idx_type) const
01476 {
01477   return octave_value ();
01478 }
01479 
01480 bool
01481 octave_base_value::fast_elem_insert (octave_idx_type, const octave_value&)
01482 {
01483   return false;
01484 }
01485 
01486 bool
01487 octave_base_value::fast_elem_insert_self (void *, builtin_type_t) const
01488 {
01489   return false;
01490 }
01491 
01492 CONVDECLX (matrix_conv)
01493 {
01494   return new octave_matrix ();
01495 }
01496 
01497 CONVDECLX (complex_matrix_conv)
01498 {
01499   return new octave_complex_matrix ();
01500 }
01501 
01502 CONVDECLX (string_conv)
01503 {
01504   return new octave_char_matrix_str ();
01505 }
01506 
01507 CONVDECLX (cell_conv)
01508 {
01509   return new octave_cell ();
01510 }
01511 
01512 void
01513 install_base_type_conversions (void)
01514 {
01515   INSTALL_ASSIGNCONV (octave_base_value, octave_scalar, octave_matrix);
01516   INSTALL_ASSIGNCONV (octave_base_value, octave_matrix, octave_matrix);
01517   INSTALL_ASSIGNCONV (octave_base_value, octave_complex, octave_complex_matrix);
01518   INSTALL_ASSIGNCONV (octave_base_value, octave_complex_matrix, octave_complex_matrix);
01519   INSTALL_ASSIGNCONV (octave_base_value, octave_range, octave_matrix);
01520   INSTALL_ASSIGNCONV (octave_base_value, octave_char_matrix_str, octave_char_matrix_str);
01521   INSTALL_ASSIGNCONV (octave_base_value, octave_cell, octave_cell);
01522 
01523   INSTALL_WIDENOP (octave_base_value, octave_matrix, matrix_conv);
01524   INSTALL_WIDENOP (octave_base_value, octave_complex_matrix, complex_matrix_conv);
01525   INSTALL_WIDENOP (octave_base_value, octave_char_matrix_str, string_conv);
01526   INSTALL_WIDENOP (octave_base_value, octave_cell, cell_conv);
01527 }
01528 
01529 DEFUN (sparse_auto_mutate, args, nargout,
01530   "-*- texinfo -*-\n\
01531 @deftypefn  {Built-in Function} {@var{val} =} sparse_auto_mutate ()\n\
01532 @deftypefnx {Built-in Function} {@var{old_val} =} sparse_auto_mutate (@var{new_val})\n\
01533 @deftypefnx {Built-in Function} {} sparse_auto_mutate (@var{new_val}, \"local\")\n\
01534 Query or set the internal variable that controls whether Octave will\n\
01535 automatically mutate sparse matrices to full matrices to save memory.\n\
01536 For example:\n\
01537 \n\
01538 @example\n\
01539 @group\n\
01540 s = speye (3);\n\
01541 sparse_auto_mutate (false)\n\
01542 s(:, 1) = 1;\n\
01543 typeinfo (s)\n\
01544 @result{} sparse matrix\n\
01545 sparse_auto_mutate (true)\n\
01546 s(1, :) = 1;\n\
01547 typeinfo (s)\n\
01548 @result{} matrix\n\
01549 @end group\n\
01550 @end example\n\
01551 \n\
01552 When called from inside a function with the \"local\" option, the variable is\n\
01553 changed locally for the function and any subroutines it calls.  The original\n\
01554 variable value is restored when exiting the function.\n\
01555 @end deftypefn")
01556 {
01557   return SET_INTERNAL_VARIABLE (sparse_auto_mutate);
01558 }
01559 
01560 /*
01561 
01562 %!test
01563  s = speye(3);
01564  sparse_auto_mutate (false);
01565  s(:, 1) = 1;
01566  assert (typeinfo (s), "sparse matrix");
01567  sparse_auto_mutate (true);
01568  s(1, :) = 1;
01569  assert (typeinfo (s), "matrix");
01570 
01571 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines