# HG changeset patch # User John W. Eaton # Date 1471124958 14400 # Node ID 564203123065e8b1c585b1992910a8e31facf2e8 # Parent cd2e24983670b329d353dba6b9a76cbe1024f26c move single and double type conversion functions to ov.cc * ov.h, ov.cc (octave_value::as_double, octave_value::as_double): New functions. (Fdouble): Move here from ov-re-mat.cc. (Fsingle): Move here from ov-flt-re-mat.cc. * ov-type-conv.h (octave_type_conv): New template function, replaces OCTAVE_TYPE_CONV_BODY3 macro. Change all uses. (OCTAVE_TYPE_CONV_BODY): Simplify. diff -r cd2e24983670 -r 564203123065 libinterp/octave-value/ov-flt-re-mat.cc --- a/libinterp/octave-value/ov-flt-re-mat.cc Sat Aug 13 17:44:19 2016 -0400 +++ b/libinterp/octave-value/ov-flt-re-mat.cc Sat Aug 13 17:49:18 2016 -0400 @@ -59,7 +59,6 @@ #include "ov-re-sparse.h" #include "ov-flt-re-diag.h" #include "ov-flt-cx-diag.h" -#include "ov-type-conv.h" #include "pr-output.h" #include "variables.h" #include "ops.h" @@ -810,74 +809,3 @@ return octave_base_value::map (umap); } } - -DEFUN (single, args, , - doc: /* -*- texinfo -*- -@deftypefn {} {} single (@var{x}) -Convert @var{x} to single precision type. -@seealso{double} -@end deftypefn */) -{ - // The OCTAVE_TYPE_CONV_BODY3 macro declares retval, so they go - // inside their own scopes, and we don't declare retval here to - // avoid a shadowed declaration warning. - - if (args.length () != 1) - print_usage (); - - if (args(0).is_diag_matrix ()) - { - if (args(0).is_complex_type ()) - { - OCTAVE_TYPE_CONV_BODY3 (single, octave_float_complex_diag_matrix, - octave_float_complex); - } - else - { - OCTAVE_TYPE_CONV_BODY3 (single, octave_float_diag_matrix, - octave_float_scalar); - } - } - else if (args(0).is_sparse_type ()) - { - error ("single: sparse type does not support single precision"); - } - else if (args(0).is_complex_type ()) - { - OCTAVE_TYPE_CONV_BODY3 (single, octave_float_complex_matrix, - octave_float_complex); - } - else - { - OCTAVE_TYPE_CONV_BODY3 (single, octave_float_matrix, - octave_float_scalar); - } - - return ovl (); -} - -/* -%!assert (class (single (1)), "single") -%!assert (class (single (1 + i)), "single") -%!assert (class (single (int8 (1))), "single") -%!assert (class (single (uint8 (1))), "single") -%!assert (class (single (int16 (1))), "single") -%!assert (class (single (uint16 (1))), "single") -%!assert (class (single (int32 (1))), "single") -%!assert (class (single (uint32 (1))), "single") -%!assert (class (single (int64 (1))), "single") -%!assert (class (single (uint64 (1))), "single") -%!assert (class (single (true)), "single") -%!assert (class (single ("A")), "single") -%!error (single (sparse (1))) -%!test -%! x = diag ([1 3 2]); -%! y = single (x); -%! assert (class (x), "double"); -%! assert (class (y), "single"); -%!test -%! x = diag ([i 3 2]); -%! y = single (x); -%! assert (class (x), "double"); -%! assert (class (y), "single"); -*/ diff -r cd2e24983670 -r 564203123065 libinterp/octave-value/ov-re-mat.cc --- a/libinterp/octave-value/ov-re-mat.cc Sat Aug 13 17:44:19 2016 -0400 +++ b/libinterp/octave-value/ov-re-mat.cc Sat Aug 13 17:49:18 2016 -0400 @@ -60,7 +60,6 @@ #include "ov-cx-diag.h" #include "ov-lazy-idx.h" #include "ov-perm.h" -#include "ov-type-conv.h" #include "pr-output.h" #include "variables.h" @@ -935,91 +934,3 @@ return octave_base_value::map (umap); } } - -DEFUN (double, args, , - doc: /* -*- texinfo -*- -@deftypefn {} {} double (@var{x}) -Convert @var{x} to double precision type. -@seealso{single} -@end deftypefn */) -{ - // The OCTAVE_TYPE_CONV_BODY3 macro declares retval, so they go - // inside their own scopes, and we don't declare retval here to - // avoid a shadowed declaration warning. - - if (args.length () != 1) - print_usage (); - - if (args(0).is_perm_matrix ()) - { - OCTAVE_TYPE_CONV_BODY3 (double, octave_perm_matrix, octave_scalar); - } - else if (args(0).is_diag_matrix ()) - { - if (args(0).is_complex_type ()) - { - OCTAVE_TYPE_CONV_BODY3 (double, octave_complex_diag_matrix, - octave_complex); - } - else - { - OCTAVE_TYPE_CONV_BODY3 (double, octave_diag_matrix, - octave_scalar); - } - } - else if (args(0).is_sparse_type ()) - { - if (args(0).is_complex_type ()) - { - OCTAVE_TYPE_CONV_BODY3 (double, octave_sparse_complex_matrix, - octave_complex); - } - else - { - OCTAVE_TYPE_CONV_BODY3 (double, octave_sparse_matrix, - octave_scalar); - } - } - else if (args(0).is_complex_type ()) - { - OCTAVE_TYPE_CONV_BODY3 (double, octave_complex_matrix, - octave_complex); - } - else - { - OCTAVE_TYPE_CONV_BODY3 (double, octave_matrix, octave_scalar); - } - - return ovl (); -} - -/* -%!assert (class (double (single (1))), "double") -%!assert (class (double (single (1 + i))), "double") -%!assert (class (double (int8 (1))), "double") -%!assert (class (double (uint8 (1))), "double") -%!assert (class (double (int16 (1))), "double") -%!assert (class (double (uint16 (1))), "double") -%!assert (class (double (int32 (1))), "double") -%!assert (class (double (uint32 (1))), "double") -%!assert (class (double (int64 (1))), "double") -%!assert (class (double (uint64 (1))), "double") -%!assert (class (double (true)), "double") -%!assert (class (double ("A")), "double") -%!test -%! x = sparse (logical ([1 0; 0 1])); -%! y = double (x); -%! assert (class (x), "logical"); -%! assert (class (y), "double"); -%! assert (issparse (y)); -%!test -%! x = diag (single ([1 3 2])); -%! y = double (x); -%! assert (class (x), "single"); -%! assert (class (y), "double"); -%!test -%! x = diag (single ([i 3 2])); -%! y = double (x); -%! assert (class (x), "single"); -%! assert (class (y), "double"); -*/ diff -r cd2e24983670 -r 564203123065 libinterp/octave-value/ov-type-conv.h --- a/libinterp/octave-value/ov-type-conv.h Sat Aug 13 17:44:19 2016 -0400 +++ b/libinterp/octave-value/ov-type-conv.h Sat Aug 13 17:49:18 2016 -0400 @@ -75,33 +75,34 @@ return retval; } -#define OCTAVE_TYPE_CONV_BODY3(NAME, MATRIX_RESULT_T, SCALAR_RESULT_T) \ - \ +template +octave_value +octave_type_conv (const octave_value& arg, const char *t_name) +{ + octave_value retval; + + int t_result = MATRIX_RESULT_T::static_type_id (); + + retval = octave_type_conv_body (arg, t_name, t_result); + + if (retval.is_undefined ()) + { + std::string arg_tname = arg.type_name (); + + std::string result_tname = arg.numel () == 1 + ? SCALAR_RESULT_T::static_type_name () + : MATRIX_RESULT_T::static_type_name (); + + err_invalid_conversion (arg_tname, result_tname); + } + + return retval; +} + +#define OCTAVE_TYPE_CONV_BODY(NAME) \ if (args.length () != 1) \ print_usage (); \ \ - octave_value retval; \ - \ - const octave_value arg = args(0); \ - \ - int t_result = MATRIX_RESULT_T::static_type_id (); \ - \ - retval = octave_type_conv_body (arg, #NAME, t_result); \ - if (retval.is_undefined ()) \ - { \ - std::string arg_tname = arg.type_name (); \ - \ - std::string result_tname = arg.numel () == 1 \ - ? SCALAR_RESULT_T::static_type_name () \ - : MATRIX_RESULT_T::static_type_name (); \ - \ - err_invalid_conversion (arg_tname, result_tname); \ - } \ - \ - return retval; - -#define OCTAVE_TYPE_CONV_BODY(NAME) \ - OCTAVE_TYPE_CONV_BODY3 (NAME, octave_ ## NAME ## _matrix, \ - octave_ ## NAME ## _scalar) + return octave_type_conv (args(0), #NAME); #endif diff -r cd2e24983670 -r 564203123065 libinterp/octave-value/ov.cc --- a/libinterp/octave-value/ov.cc Sat Aug 13 17:44:19 2016 -0400 +++ b/libinterp/octave-value/ov.cc Sat Aug 13 17:49:18 2016 -0400 @@ -74,6 +74,7 @@ #include "ov-usr-fcn.h" #include "ov-fcn-handle.h" #include "ov-fcn-inline.h" +#include "ov-type-conv.h" #include "ov-typeinfo.h" #include "ov-null-mat.h" #include "ov-lazy-idx.h" @@ -1184,6 +1185,138 @@ } octave_value +octave_value::as_double (void) const +{ + if (is_perm_matrix ()) + return octave_type_conv (*this, "double"); + else if (is_diag_matrix ()) + { + if (is_complex_type ()) + return octave_type_conv (*this, "double"); + else + return octave_type_conv (*this, "double"); + } + else if (is_sparse_type ()) + { + if (is_complex_type ()) + return octave_type_conv (*this, "double"); + else + return octave_type_conv (*this, "double"); + } + else if (is_complex_type ()) + return octave_type_conv (*this, "double"); + else + return octave_type_conv (*this, "double"); + + return ovl (); +} + +DEFUN (double, args, , + doc: /* -*- texinfo -*- +@deftypefn {} {} double (@var{x}) +Convert @var{x} to double precision type. +@seealso{single} +@end deftypefn */) +{ + if (args.length () != 1) + print_usage (); + + return ovl (args(0).as_double ()); +} + +/* +%!assert (class (double (single (1))), "double") +%!assert (class (double (single (1 + i))), "double") +%!assert (class (double (int8 (1))), "double") +%!assert (class (double (uint8 (1))), "double") +%!assert (class (double (int16 (1))), "double") +%!assert (class (double (uint16 (1))), "double") +%!assert (class (double (int32 (1))), "double") +%!assert (class (double (uint32 (1))), "double") +%!assert (class (double (int64 (1))), "double") +%!assert (class (double (uint64 (1))), "double") +%!assert (class (double (true)), "double") +%!assert (class (double ("A")), "double") +%!test +%! x = sparse (logical ([1 0; 0 1])); +%! y = double (x); +%! assert (class (x), "logical"); +%! assert (class (y), "double"); +%! assert (issparse (y)); +%!test +%! x = diag (single ([1 3 2])); +%! y = double (x); +%! assert (class (x), "single"); +%! assert (class (y), "double"); +%!test +%! x = diag (single ([i 3 2])); +%! y = double (x); +%! assert (class (x), "single"); +%! assert (class (y), "double"); +*/ + +octave_value +octave_value::as_single (void) const +{ + if (is_diag_matrix ()) + { + if (is_complex_type ()) + return octave_type_conv (*this, "single"); + else + return octave_type_conv (*this, "single"); + } + else if (is_sparse_type ()) + error ("single: sparse type does not support single precision"); + else if (is_complex_type ()) + return octave_type_conv (*this, "single"); + else + return octave_type_conv (*this, "single"); + + return octave_value (); +} + +DEFUN (single, args, , + doc: /* -*- texinfo -*- +@deftypefn {} {} single (@var{x}) +Convert @var{x} to single precision type. +@seealso{double} +@end deftypefn */) +{ + if (args.length () != 1) + print_usage (); + + return args(0).as_single (); + + return ovl (); +} + +/* +%!assert (class (single (1)), "single") +%!assert (class (single (1 + i)), "single") +%!assert (class (single (int8 (1))), "single") +%!assert (class (single (uint8 (1))), "single") +%!assert (class (single (int16 (1))), "single") +%!assert (class (single (uint16 (1))), "single") +%!assert (class (single (int32 (1))), "single") +%!assert (class (single (uint32 (1))), "single") +%!assert (class (single (int64 (1))), "single") +%!assert (class (single (uint64 (1))), "single") +%!assert (class (single (true)), "single") +%!assert (class (single ("A")), "single") +%!error (single (sparse (1))) +%!test +%! x = diag ([1 3 2]); +%! y = single (x); +%! assert (class (x), "double"); +%! assert (class (y), "single"); +%!test +%! x = diag ([i 3 2]); +%! y = single (x); +%! assert (class (x), "double"); +%! assert (class (y), "single"); +*/ + + octave_value octave_value::single_subsref (const std::string& type, const octave_value_list& idx) { diff -r cd2e24983670 -r 564203123065 libinterp/octave-value/ov.h --- a/libinterp/octave-value/ov.h Sat Aug 13 17:44:19 2016 -0400 +++ b/libinterp/octave-value/ov.h Sat Aug 13 17:49:18 2016 -0400 @@ -386,6 +386,11 @@ octave_value full_value (void) const { return rep->full_value (); } + // Type conversions. + + octave_value as_double (void) const; + octave_value as_single (void) const; + octave_base_value *try_narrowing_conversion (void) { return rep->try_narrowing_conversion (); }