changeset 22283:564203123065

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.
author John W. Eaton <jwe@octave.org>
date Sat, 13 Aug 2016 17:49:18 -0400
parents cd2e24983670
children a7e68243a326
files libinterp/octave-value/ov-flt-re-mat.cc libinterp/octave-value/ov-re-mat.cc libinterp/octave-value/ov-type-conv.h libinterp/octave-value/ov.cc libinterp/octave-value/ov.h
diffstat 5 files changed, 164 insertions(+), 186 deletions(-) [+]
line wrap: on
line diff
--- 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");
-*/
--- 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");
-*/
--- 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 <typename MATRIX_RESULT_T, typename SCALAR_RESULT_T>
+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<octave_ ## NAME ## _matrix, octave_ ## NAME ## _scalar> (args(0), #NAME);
 
 #endif
--- 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<octave_perm_matrix, octave_scalar> (*this, "double");
+  else if (is_diag_matrix ())
+    {
+      if (is_complex_type ())
+        return octave_type_conv<octave_complex_diag_matrix, octave_complex> (*this, "double");
+      else
+        return octave_type_conv<octave_diag_matrix, octave_scalar> (*this, "double");
+    }
+  else if (is_sparse_type ())
+    {
+      if (is_complex_type ())
+        return octave_type_conv<octave_sparse_complex_matrix, octave_complex> (*this, "double");
+      else
+        return octave_type_conv<octave_sparse_matrix, octave_scalar> (*this, "double");
+    }
+  else if (is_complex_type ())
+    return octave_type_conv<octave_complex_matrix, octave_complex> (*this, "double");
+  else
+    return octave_type_conv<octave_matrix, octave_scalar> (*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<octave_float_complex_diag_matrix, octave_float_complex> (*this, "single");
+      else
+        return octave_type_conv<octave_float_diag_matrix, octave_float_scalar> (*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<octave_float_complex_matrix, octave_float_complex> (*this, "single");
+  else
+    return octave_type_conv<octave_float_matrix, octave_float_scalar> (*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)
 {
--- 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 (); }