changeset 18195:1b6db9303933

allow toupper and tolower to handle numeric values (bug #33537) * ov-base-sparse.cc (octave_base_sparse<T>::map): Special case for umap_xtolower and umap_xtoupper. * ov-float.cc (octave_float_scalar::map): Likewise. * ov-flt-re-mat.cc (octave_float_matrix::map): Likewise. * ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::map, OCTAVE_VALUE_INT_SCALAR_T::map): Likewise. * ov-re-mat.cc (octave_matrix::map): Likewise. * ov-scalar.cc (octave_scalar::map): Likewise. * build-sparse-tests.sh, mappers.cc: Update tests.
author John W. Eaton <jwe@octave.org>
date Thu, 02 Jan 2014 22:44:37 -0500
parents 1461b9cfac4e
children 0d5721873d6b
files libinterp/corefcn/mappers.cc libinterp/octave-value/ov-base-sparse.cc libinterp/octave-value/ov-float.cc libinterp/octave-value/ov-flt-re-mat.cc libinterp/octave-value/ov-intx.h libinterp/octave-value/ov-re-mat.cc libinterp/octave-value/ov-scalar.cc test/build-sparse-tests.sh
diffstat 8 files changed, 86 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/mappers.cc	Thu Jan 02 13:23:51 2014 -0800
+++ b/libinterp/corefcn/mappers.cc	Thu Jan 02 22:44:37 2014 -0500
@@ -2156,8 +2156,17 @@
 %!assert (tolower ({"ABC", "DEF", {"GHI", {"JKL"}}}), {"abc", "def", {"ghi", {"jkl"}}})
 %!assert (tolower (["ABC"; "DEF"]), ["abc"; "def"])
 %!assert (tolower ({["ABC"; "DEF"]}), {["abc";"def"]})
-%!assert (tolower (68), "d")
-%!assert (tolower ({[68, 68; 68, 68]}), {["dd";"dd"]})
+%!assert (tolower (68), 68)
+%!assert (tolower ({[68, 68; 68, 68]}), {[68, 68; 68, 68]})
+%!test
+%! classes = {@char, @double, @single, ...
+%!            @int8, @int16, @int32, @int64, ...
+%!            @uint8, @uint16, @uint32, @uint64};
+%! for i = 1:numel (classes)
+%!   cls = classes{i};
+%!   assert (class (tolower (cls (97))), class (cls (97)));
+%!   assert (class (tolower (cls ([98, 99]))), class (cls ([98, 99])));
+%! endfor
 %!test
 %! a(3,3,3,3) = "D";
 %! assert (tolower (a)(3,3,3,3), "d");
@@ -2207,8 +2216,17 @@
 %!assert (toupper ({"abc", "def", {"ghi", {"jkl"}}}), {"ABC", "DEF", {"GHI", {"JKL"}}})
 %!assert (toupper (["abc"; "def"]), ["ABC"; "DEF"])
 %!assert (toupper ({["abc"; "def"]}), {["ABC";"DEF"]})
-%!assert (toupper (100), "D")
-%!assert (toupper ({[100, 100; 100, 100]}), {["DD";"DD"]})
+%!assert (toupper (100), 100)
+%!assert (toupper ({[100, 100; 100, 100]}), {[100, 100; 100, 100]})
+%!test
+%! classes = {@char, @double, @single, ...
+%!            @int8, @int16, @int32, @int64, ...
+%!            @uint8, @uint16, @uint32, @uint64};
+%! for i = 1:numel (classes)
+%!   cls = classes{i};
+%!   assert (class (toupper (cls (97))), class (cls (97)));
+%!   assert (class (toupper (cls ([98, 99]))), class (cls ([98, 99])));
+%! endfor
 %!test
 %! a(3,3,3,3) = "d";
 %! assert (toupper (a)(3,3,3,3), "D");
--- a/libinterp/octave-value/ov-base-sparse.cc	Thu Jan 02 13:23:51 2014 -0800
+++ b/libinterp/octave-value/ov-base-sparse.cc	Thu Jan 02 22:44:37 2014 -0500
@@ -440,11 +440,19 @@
 octave_value
 octave_base_sparse<T>::map (octave_base_value::unary_mapper_t umap) const
 {
+  if (umap == umap_xtolower || umap == umap_xtoupper)
+    return matrix;
+
   // Try the map on the dense value.
+  // FIXME: We should probably be smarter about this, especially for the
+  // cases that are expected to return sparse matrices.
   octave_value retval = this->full_value ().map (umap);
 
   // Sparsify the result if possible.
+
   // FIXME: intentionally skip this step for string mappers. Is this wanted?
+  // FIXME: this will break if some well-meaning person rearranges the
+  // enum list in ov-base.h.
   if (umap >= umap_xisalnum && umap <= umap_xtoupper)
     return retval;
 
--- a/libinterp/octave-value/ov-float.cc	Thu Jan 02 13:23:51 2014 -0800
+++ b/libinterp/octave-value/ov-float.cc	Thu Jan 02 22:44:37 2014 -0500
@@ -327,8 +327,21 @@
       SCALAR_MAPPER (isnan, xisnan);
       SCALAR_MAPPER (xsignbit, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return scalar;
+
     default:
-      return octave_base_value::map (umap);
+      // FIXME: this will break if some well-meaning person rearranges
+      // the enum list in ov-base.h.
+      if (umap >= umap_xisalnum && umap <= umap_xtoupper)
+        {
+          octave_value str_conv = convert_to_str (true, true);
+          return error_state ? octave_value () : str_conv.map (umap);
+        }
+      else
+        return octave_base_value::map (umap);
     }
 }
 
--- a/libinterp/octave-value/ov-flt-re-mat.cc	Thu Jan 02 13:23:51 2014 -0800
+++ b/libinterp/octave-value/ov-flt-re-mat.cc	Thu Jan 02 22:44:37 2014 -0500
@@ -812,8 +812,21 @@
       ARRAY_MAPPER (isna, bool, octave_is_NA);
       ARRAY_MAPPER (xsignbit, float, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return matrix;
+
     default:
-      return octave_base_value::map (umap);
+      // FIXME: this will break if some well-meaning person rearranges
+      // the enum list in ov-base.h.
+      if (umap >= umap_xisalnum && umap <= umap_xtoupper)
+        {
+          octave_value str_conv = convert_to_str (true, true);
+          return error_state ? octave_value () : str_conv.map (umap);
+        }
+      else
+        return octave_base_value::map (umap);
     }
 }
 
--- a/libinterp/octave-value/ov-intx.h	Thu Jan 02 13:23:51 2014 -0800
+++ b/libinterp/octave-value/ov-intx.h	Thu Jan 02 22:44:37 2014 -0500
@@ -358,8 +358,15 @@
       case umap_finite:
         return boolNDArray (matrix.dims (), true);
 
+      // Special cases for Matlab compatibility.
+      case umap_xtolower:
+      case umap_xtoupper:
+        return matrix;
+
       default:
         {
+          // FIXME: we should be able to do better than converting to
+          // double here.
           octave_matrix m (array_value ());
           return m.map (umap);
         }
@@ -658,6 +665,11 @@
       case umap_finite:
         return true;
 
+      // Special cases for Matlab compatibility.
+      case umap_xtolower:
+      case umap_xtoupper:
+        return scalar;
+
       default:
         {
           octave_scalar m (scalar_value ());
--- a/libinterp/octave-value/ov-re-mat.cc	Thu Jan 02 13:23:51 2014 -0800
+++ b/libinterp/octave-value/ov-re-mat.cc	Thu Jan 02 22:44:37 2014 -0500
@@ -935,7 +935,14 @@
       ARRAY_MAPPER (isna, bool, octave_is_NA);
       ARRAY_MAPPER (xsignbit, double, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return matrix;
+
     default:
+      // FIXME: this will break if some well-meaning person rearranges
+      // the enum list in ov-base.h.
       if (umap >= umap_xisalnum && umap <= umap_xtoupper)
         {
           octave_value str_conv = convert_to_str (true, true);
--- a/libinterp/octave-value/ov-scalar.cc	Thu Jan 02 13:23:51 2014 -0800
+++ b/libinterp/octave-value/ov-scalar.cc	Thu Jan 02 22:44:37 2014 -0500
@@ -343,7 +343,14 @@
       SCALAR_MAPPER (isnan, xisnan);
       SCALAR_MAPPER (xsignbit, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return scalar;
+
     default:
+      // FIXME: this will break if some well-meaning person rearranges
+      // the enum list in ov-base.h.
       if (umap >= umap_xisalnum && umap <= umap_xtoupper)
         {
           octave_value str_conv = convert_to_str (true, true);
--- a/test/build-sparse-tests.sh	Thu Jan 02 13:23:51 2014 -0800
+++ b/test/build-sparse-tests.sh	Thu Jan 02 22:44:37 2014 -0500
@@ -513,14 +513,13 @@
 # Specific tests for certain mapper functions
     cat >>$TESTS <<EOF
 
-%% These mapper functions always return a full matrix
 %!test
 %! wn2s = warning ("query", "Octave:num-to-str");
 %! warning ("off", "Octave:num-to-str");
 %! if (isreal (af))
 %!   assert (toascii (as), toascii (af));
-%!   assert (tolower (as), tolower (af));
-%!   assert (toupper (as), toupper (af));
+%!   assert (tolower (as), as);
+%!   assert (toupper (as), as);
 %! endif
 %! warning (wn2s.state, "Octave:num-to-str");