changeset 9813:8fa32b527d9a

improve & partially revert previous change
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 13 Nov 2009 11:45:39 +0100
parents f80c566bc751
children 2b29f3472e20
files src/Cell.cc src/Cell.h src/ChangeLog src/DLD-FUNCTIONS/lookup.cc src/data.cc src/mappers.cc src/ov-base-sparse.cc src/ov-base-sparse.h src/ov-base.cc src/ov-base.h src/ov-cell.cc src/ov-cell.h src/ov-ch-mat.cc src/ov-cx-sparse.cc src/ov-re-mat.cc src/ov-re-sparse.cc src/ov-scalar.cc src/ov.h
diffstat 18 files changed, 433 insertions(+), 267 deletions(-) [+]
line wrap: on
line diff
--- a/src/Cell.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/Cell.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -266,7 +266,7 @@
 }
 
 Cell
-Cell::map (unary_mapper_t umap) const
+Cell::map (ctype_mapper fcn) const
 {
   Cell retval (dims ());
   octave_value *r = retval.fortran_vec ();
@@ -274,11 +274,7 @@
   const octave_value *p = data ();
 
   for (octave_idx_type i = 0; i < numel (); i++)
-    {
-      r[i] = p[i].map (umap);
-      if (error_state)
-        break;
-    }
+    r[i] = ((p++)->*fcn) ();
 
   return retval;
 }
--- a/src/Cell.h	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/Cell.h	Fri Nov 13 11:45:39 2009 +0100
@@ -104,7 +104,27 @@
 
   Cell diag (octave_idx_type k = 0) const;
 
-  Cell map (unary_mapper_t umap) const;
+  Cell xisalnum (void) const { return map (&octave_value::xisalnum); }
+  Cell xisalpha (void) const { return map (&octave_value::xisalpha); }
+  Cell xisascii (void) const { return map (&octave_value::xisascii); }
+  Cell xiscntrl (void) const { return map (&octave_value::xiscntrl); }
+  Cell xisdigit (void) const { return map (&octave_value::xisdigit); }
+  Cell xisgraph (void) const { return map (&octave_value::xisgraph); }
+  Cell xislower (void) const { return map (&octave_value::xislower); }
+  Cell xisprint (void) const { return map (&octave_value::xisprint); }
+  Cell xispunct (void) const { return map (&octave_value::xispunct); }
+  Cell xisspace (void) const { return map (&octave_value::xisspace); }
+  Cell xisupper (void) const { return map (&octave_value::xisupper); }
+  Cell xisxdigit (void) const { return map (&octave_value::xisxdigit); }
+  Cell xtoascii (void) const { return map (&octave_value::xtoascii); }
+  Cell xtolower (void) const { return map (&octave_value::xtolower); }
+  Cell xtoupper (void) const { return map (&octave_value::xtoupper); }
+
+private:
+
+  typedef octave_value (octave_value::*ctype_mapper) (void) const;
+
+  Cell map (ctype_mapper) const;
 };
 
 #endif
--- a/src/ChangeLog	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ChangeLog	Fri Nov 13 11:45:39 2009 +0100
@@ -1,3 +1,18 @@
+2009-11-13  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-base.h (unary_mapper_t): Move to octave_base_value.
+	* ov.h: Partially revert to c657c056240d.
+	(FORWARD_MAPPER): Update to use octave_base_value::map.
+	(octave_value::map): Ditto.
+	* mappers.cc: Revert to c657c056240d.
+	* data.cc: Ditto.
+	* Cell.h, Cell.cc: Ditto.
+	* ov-cell.cc (octave_cell::map): Rewrite.
+	* ov-base-sparse.cc (octave_base_sparse::map): New method.
+	* ov-base-sparse.h: Declare it.
+	* ov-re-sparse.cc (octave_sparse_matrix::map): Use it as a fallback.
+	* ov-cx-sparse.cc (octave_sparse_complexmatrix::map): Ditto.
+
 2009-11-12  Jaroslav Hajek  <highegg@gmail.com>
 
 	* ov-base.h (unary_mapper_t): New enum.
--- a/src/DLD-FUNCTIONS/lookup.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/DLD-FUNCTIONS/lookup.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -227,10 +227,10 @@
       // (though it's not too meaningful).
       
       if (table.is_complex_type ())
-        table = table.map (umap_abs);
+        table = table.abs ();
 
       if (y.is_complex_type ())
-        y = y.map (umap_abs);
+        y = y.abs ();
 
       Array<octave_idx_type> idx;
 
--- a/src/data.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/data.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -978,6 +978,120 @@
 %!assert (hypot (single(1:10), single(1:10)), single(sqrt(2) * [1:10]));
 */
 
+template<typename T, typename ET>
+void 
+map_2_xlog2 (const Array<T>& x, Array<T>& f, Array<ET>& e)
+{
+  f = Array<T>(x.dims ());
+  e = Array<ET>(x.dims ());
+  for (octave_idx_type i = 0; i < x.numel (); i++)
+    {
+      int exp;
+      f.xelem (i) = xlog2 (x(i), exp);
+      e.xelem (i) = exp;
+    }
+}
+
+DEFUN (log2, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Mapping Function} {} log2 (@var{x})\n\
+@deftypefnx {Mapping Function} {[@var{f}, @var{e}] =} log2 (@var{x})\n\
+Compute the base-2 logarithm of each element of @var{x}.\n\
+\n\
+If called with two output arguments, split @var{x} into\n\
+binary mantissa and exponent so that\n\
+@tex\n\
+${1 \\over 2} \\le \\left| f \\right| < 1$\n\
+@end tex\n\
+@ifnottex\n\
+@code{1/2 <= abs(f) < 1}\n\
+@end ifnottex\n\
+and @var{e} is an integer.  If\n\
+@tex\n\
+$x = 0$, $f = e = 0$.\n\
+@end tex\n\
+@ifnottex\n\
+@code{x = 0}, @code{f = e = 0}.\n\
+@end ifnottex\n\
+@seealso{pow2, log, log10, exp}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      if (nargout < 2)
+        retval(0) = args(0).log2 ();
+      else if (args(0).is_single_type ())
+	{
+	  if (args(0).is_real_type ())
+	    {
+	      FloatNDArray f;
+	      FloatNDArray x = args(0).float_array_value ();
+	      // FIXME -- should E be an int value?
+	      FloatMatrix e;
+	      map_2_xlog2 (x, f, e);
+	      retval (1) = e;
+	      retval (0) = f;
+	    }
+	  else if (args(0).is_complex_type ())
+	    {
+	      FloatComplexNDArray f;
+	      FloatComplexNDArray x = args(0).float_complex_array_value ();
+	      // FIXME -- should E be an int value?
+	      FloatNDArray e;
+	      map_2_xlog2 (x, f, e);
+	      retval (1) = e;
+	      retval (0) = f;
+	    }
+	}
+      else if (args(0).is_real_type ())
+        {
+          NDArray f;
+          NDArray x = args(0).array_value ();
+          // FIXME -- should E be an int value?
+          Matrix e;
+          map_2_xlog2 (x, f, e);
+          retval (1) = e;
+          retval (0) = f;
+        }
+      else if (args(0).is_complex_type ())
+        {
+          ComplexNDArray f;
+          ComplexNDArray x = args(0).complex_array_value ();
+          // FIXME -- should E be an int value?
+          NDArray e;
+          map_2_xlog2 (x, f, e);
+          retval (1) = e;
+          retval (0) = f;
+        }
+      else
+        gripe_wrong_type_arg ("log2", args(0));
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert(log2 ([1/4, 1/2, 1, 2, 4]), [-2, -1, 0, 1, 2]);
+%!assert(log2(Inf), Inf);
+%!assert(isnan(log2(NaN)));
+%!assert(log2(4*i), 2 + log2(1*i));
+%!assert(log2(complex(0,Inf)), Inf + log2(i));
+
+%!test
+%! [f, e] = log2 ([0,-1; 2,-4; Inf,-Inf]);
+%! assert (f, [0,-0.5; 0.5,-0.5; Inf,-Inf]);
+%! assert (e(1:2,:), [0,1;2,3])
+
+%!test
+%! [f, e] = log2 (complex (zeros (3, 2), [0,-1; 2,-4; Inf,-Inf]));
+%! assert (f, complex (zeros (3, 2), [0,-0.5; 0.5,-0.5; Inf,-Inf]));
+%! assert (e(1:2,:), [0,1; 2,3]);
+*/
+
 DEFUN (fmod, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} fmod (@var{x}, @var{y})\n\
--- a/src/mappers.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/mappers.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -35,7 +35,6 @@
 #include "defun.h"
 #include "error.h"
 #include "variables.h"
-#include "gripes.h"
 
 DEFUN (abs, args, ,
     "-*- texinfo -*-\n\
@@ -60,7 +59,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_abs);
+    retval = args(0).abs ();
   else
     print_usage ();
 
@@ -95,7 +94,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_acos);
+    retval = args(0).acos ();
   else
     print_usage ();
 
@@ -132,7 +131,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_acosh);
+    retval = args(0).acosh ();
   else
     print_usage ();
 
@@ -164,7 +163,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_arg);
+    retval = args(0).arg ();
   else
     print_usage ();
 
@@ -196,7 +195,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_arg);
+    retval = args(0).arg ();
   else
     print_usage ();
 
@@ -231,7 +230,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_asin);
+    retval = args(0).asin ();
   else
     print_usage ();
 
@@ -258,7 +257,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_asinh);
+    retval = args(0).asinh ();
   else
     print_usage ();
 
@@ -291,7 +290,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_atan);
+    retval = args(0).atan ();
   else
     print_usage ();
 
@@ -328,7 +327,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_atanh);
+    retval = args(0).atanh ();
   else
     print_usage ();
 
@@ -369,7 +368,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_ceil);
+    retval = args(0).ceil ();
   else
     print_usage ();
 
@@ -410,7 +409,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_conj);
+    retval = args(0).conj ();
   else
     print_usage ();
 
@@ -445,7 +444,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_cos);
+    retval = args(0).cos ();
   else
     print_usage ();
 
@@ -482,7 +481,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_cosh);
+    retval = args(0).cosh ();
   else
     print_usage ();
 
@@ -532,7 +531,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_erf);
+    retval = args(0).erf ();
   else
     print_usage ();
 
@@ -584,7 +583,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_erfc);
+    retval = args(0).erfc ();
   else
     print_usage ();
 
@@ -616,7 +615,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_exp);
+    retval = args(0).exp ();
   else
     print_usage ();
 
@@ -654,7 +653,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_expm1);
+    retval = args(0).expm1 ();
   else
     print_usage ();
 
@@ -677,7 +676,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_finite);
+    retval = args(0).finite ();
   else
     print_usage ();
 
@@ -713,7 +712,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_fix);
+    retval = args(0).fix ();
   else
     print_usage ();
 
@@ -749,7 +748,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_floor);
+    retval = args(0).floor ();
   else
     print_usage ();
 
@@ -794,7 +793,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_gamma);
+    retval = args(0).gamma ();
   else
     print_usage ();
 
@@ -835,7 +834,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_imag);
+    retval = args(0).imag ();
   else
     print_usage ();
 
@@ -868,7 +867,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isalnum);
+    retval = args(0).xisalnum ();
   else
     print_usage ();
 
@@ -885,7 +884,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isalpha);
+    retval = args(0).xisalpha ();
   else
     print_usage ();
 
@@ -900,7 +899,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isascii);
+    retval = args(0).xisascii ();
   else
     print_usage ();
 
@@ -915,7 +914,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_iscntrl);
+    retval = args(0).xiscntrl ();
   else
     print_usage ();
 
@@ -930,7 +929,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isdigit);
+    retval = args(0).xisdigit ();
   else
     print_usage ();
 
@@ -953,7 +952,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isinf);
+    retval = args(0).isinf ();
   else
     print_usage ();
 
@@ -984,7 +983,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isgraph);
+    retval = args(0).xisgraph ();
   else
     print_usage ();
 
@@ -999,7 +998,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_islower);
+    retval = args(0).xislower ();
   else
     print_usage ();
 
@@ -1023,7 +1022,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isna);
+    retval = args(0).isna ();
   else
     print_usage ();
 
@@ -1063,7 +1062,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isnan);
+    retval = args(0).isnan ();
   else
     print_usage ();
 
@@ -1094,7 +1093,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isprint);
+    retval = args(0).xisprint ();
   else
     print_usage ();
 
@@ -1109,7 +1108,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_ispunct);
+    retval = args(0).xispunct ();
   else
     print_usage ();
 
@@ -1125,7 +1124,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isspace);
+    retval = args(0).xisspace ();
   else
     print_usage ();
 
@@ -1140,7 +1139,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isupper);
+    retval = args(0).xisupper ();
   else
     print_usage ();
 
@@ -1155,7 +1154,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_isxdigit);
+    retval = args(0).xisxdigit ();
   else
     print_usage ();
 
@@ -1172,7 +1171,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_lgamma);
+    retval = args(0).lgamma ();
   else
     print_usage ();
 
@@ -1221,7 +1220,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_log);
+    retval = args(0).log ();
   else
     print_usage ();
 
@@ -1241,120 +1240,6 @@
 
  */
 
-template<typename T, typename ET>
-void 
-map_2_xlog2 (const Array<T>& x, Array<T>& f, Array<ET>& e)
-{
-  f = Array<T>(x.dims ());
-  e = Array<ET>(x.dims ());
-  for (octave_idx_type i = 0; i < x.numel (); i++)
-    {
-      int exp;
-      f.xelem (i) = xlog2 (x(i), exp);
-      e.xelem (i) = exp;
-    }
-}
-
-DEFUN (log2, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn {Mapping Function} {} log2 (@var{x})\n\
-@deftypefnx {Mapping Function} {[@var{f}, @var{e}] =} log2 (@var{x})\n\
-Compute the base-2 logarithm of each element of @var{x}.\n\
-\n\
-If called with two output arguments, split @var{x} into\n\
-binary mantissa and exponent so that\n\
-@tex\n\
-${1 \\over 2} \\le \\left| f \\right| < 1$\n\
-@end tex\n\
-@ifnottex\n\
-@code{1/2 <= abs(f) < 1}\n\
-@end ifnottex\n\
-and @var{e} is an integer.  If\n\
-@tex\n\
-$x = 0$, $f = e = 0$.\n\
-@end tex\n\
-@ifnottex\n\
-@code{x = 0}, @code{f = e = 0}.\n\
-@end ifnottex\n\
-@seealso{pow2, log, log10, exp}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  if (args.length () == 1)
-    {
-      if (nargout < 2)
-        retval(0) = args(0).map (umap_log2);
-      else if (args(0).is_single_type ())
-	{
-	  if (args(0).is_real_type ())
-	    {
-	      FloatNDArray f;
-	      FloatNDArray x = args(0).float_array_value ();
-	      // FIXME -- should E be an int value?
-	      FloatMatrix e;
-	      map_2_xlog2 (x, f, e);
-	      retval (1) = e;
-	      retval (0) = f;
-	    }
-	  else if (args(0).is_complex_type ())
-	    {
-	      FloatComplexNDArray f;
-	      FloatComplexNDArray x = args(0).float_complex_array_value ();
-	      // FIXME -- should E be an int value?
-	      FloatNDArray e;
-	      map_2_xlog2 (x, f, e);
-	      retval (1) = e;
-	      retval (0) = f;
-	    }
-	}
-      else if (args(0).is_real_type ())
-        {
-          NDArray f;
-          NDArray x = args(0).array_value ();
-          // FIXME -- should E be an int value?
-          Matrix e;
-          map_2_xlog2 (x, f, e);
-          retval (1) = e;
-          retval (0) = f;
-        }
-      else if (args(0).is_complex_type ())
-        {
-          ComplexNDArray f;
-          ComplexNDArray x = args(0).complex_array_value ();
-          // FIXME -- should E be an int value?
-          NDArray e;
-          map_2_xlog2 (x, f, e);
-          retval (1) = e;
-          retval (0) = f;
-        }
-      else
-        gripe_wrong_type_arg ("log2", args(0));
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!assert(log2 ([1/4, 1/2, 1, 2, 4]), [-2, -1, 0, 1, 2]);
-%!assert(log2(Inf), Inf);
-%!assert(isnan(log2(NaN)));
-%!assert(log2(4*i), 2 + log2(1*i));
-%!assert(log2(complex(0,Inf)), Inf + log2(i));
-
-%!test
-%! [f, e] = log2 ([0,-1; 2,-4; Inf,-Inf]);
-%! assert (f, [0,-0.5; 0.5,-0.5; Inf,-Inf]);
-%! assert (e(1:2,:), [0,1;2,3])
-
-%!test
-%! [f, e] = log2 (complex (zeros (3, 2), [0,-1; 2,-4; Inf,-Inf]));
-%! assert (f, complex (zeros (3, 2), [0,-0.5; 0.5,-0.5; Inf,-Inf]));
-%! assert (e(1:2,:), [0,1; 2,3]);
-*/
-
 DEFUN (log10, args, ,
     "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} log10 (@var{x})\n\
@@ -1364,7 +1249,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_log10);
+    retval = args(0).log10 ();
   else
     print_usage ();
 
@@ -1397,7 +1282,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_log1p);
+    retval = args(0).log1p ();
   else
     print_usage ();
 
@@ -1413,7 +1298,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_real);
+    retval = args(0).real ();
   else
     print_usage ();
 
@@ -1453,7 +1338,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_round);
+    retval = args(0).round ();
   else
     print_usage ();
 
@@ -1494,7 +1379,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_roundb);
+    retval = args(0).roundb ();
   else
     print_usage ();
 
@@ -1526,7 +1411,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_signum);
+    retval = args(0).signum ();
   else
     print_usage ();
 
@@ -1559,7 +1444,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_sin);
+    retval = args(0).sin ();
   else
     print_usage ();
 
@@ -1596,7 +1481,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_sinh);
+    retval = args(0).sinh ();
   else
     print_usage ();
 
@@ -1631,7 +1516,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_sqrt);
+    retval = args(0).sqrt ();
   else
     print_usage ();
 
@@ -1664,7 +1549,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_tan);
+    retval = args(0).tan ();
   else
     print_usage ();
 
@@ -1701,7 +1586,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_tanh);
+    retval = args(0).tanh ();
   else
     print_usage ();
 
@@ -1742,7 +1627,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_toascii);
+    retval = args(0).xtoascii ();
   else
     print_usage ();
 
@@ -1768,7 +1653,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_tolower);
+    retval = args(0).xtolower ();
   else
     print_usage ();
 
@@ -1814,7 +1699,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).map (umap_toupper);
+    retval = args(0).xtoupper ();
   else
     print_usage ();
 
--- a/src/ov-base-sparse.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-base-sparse.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -369,6 +369,36 @@
   return success;
 }
 
+template <class T>
+octave_value
+octave_base_sparse<T>::map (octave_base_value::unary_mapper_t umap) const
+{
+  // Try the map on the dense value.
+  octave_value retval = this->full_value ().map (umap);
+
+  // Sparsify the result if possible.
+  // FIXME: intentionally skip this step for string mappers. Is this wanted?
+  if (umap >= umap_xisalnum && umap <= umap_xtoupper)
+    return retval;
+
+  switch (retval.builtin_type ())
+    {
+    case btyp_double:
+      retval = retval.sparse_matrix_value ();
+      break;
+    case btyp_complex:
+      retval = retval.sparse_complex_matrix_value ();
+      break;
+    case btyp_bool:
+      retval = retval.sparse_bool_matrix_value ();
+      break;
+    default:
+      break;
+    }
+
+  return retval;
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/ov-base-sparse.h	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-base-sparse.h	Fri Nov 13 11:45:39 2009 +0100
@@ -169,6 +169,8 @@
 
 protected:
 
+  octave_value map (octave_base_value::unary_mapper_t umap) const;
+
   T matrix;
 
   mutable MatrixType typ;
--- a/src/ov-base.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-base.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -1117,8 +1117,9 @@
   return UNSORTED;
 }
 
-extern OCTINTERP_API
-const char *get_umap_name (unary_mapper_t umap)
+
+const char *
+octave_base_value::get_umap_name (unary_mapper_t umap)
 {
   static const char *names[num_unary_mappers] = 
     {
--- a/src/ov-base.h	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-base.h	Fri Nov 13 11:45:39 2009 +0100
@@ -117,70 +117,6 @@
 DEF_CLASS_TO_BTYP (bool, btyp_bool);
 DEF_CLASS_TO_BTYP (char, btyp_char);
 
-// Standard mappers.
-enum unary_mapper_t
-{
-  umap_abs,
-  umap_acos,
-  umap_acosh,
-  umap_angle,
-  umap_arg,
-  umap_asin,
-  umap_asinh,
-  umap_atan,
-  umap_atanh,
-  umap_ceil,
-  umap_conj,
-  umap_cos,
-  umap_cosh,
-  umap_erf,
-  umap_erfc,
-  umap_exp,
-  umap_expm1,
-  umap_finite,
-  umap_fix,
-  umap_floor,
-  umap_gamma,
-  umap_imag,
-  umap_isinf,
-  umap_isna,
-  umap_isnan,
-  umap_lgamma,
-  umap_log,
-  umap_log2,
-  umap_log10,
-  umap_log1p,
-  umap_real,
-  umap_round,
-  umap_roundb,
-  umap_signum,
-  umap_sin,
-  umap_sinh,
-  umap_sqrt,
-  umap_tan,
-  umap_tanh,
-  umap_isalnum,
-  umap_isalpha,
-  umap_isascii,
-  umap_iscntrl,
-  umap_isdigit,
-  umap_isgraph,
-  umap_islower,
-  umap_isprint,
-  umap_ispunct,
-  umap_isspace,
-  umap_isupper,
-  umap_isxdigit,
-  umap_toascii,
-  umap_tolower,
-  umap_toupper,
-  umap_unknown,
-  num_unary_mappers = umap_unknown
-};
-
-extern OCTINTERP_API
-const char *get_umap_name (unary_mapper_t);
-
 // T_ID is the type id of struct objects, set by register_type().
 // T_NAME is the type name of struct objects.
 
@@ -696,6 +632,67 @@
 
   virtual void dump (std::ostream& os) const;
 
+  // Standard mappers. Register new ones here.
+  enum unary_mapper_t
+    {
+      umap_abs,
+      umap_acos,
+      umap_acosh,
+      umap_angle,
+      umap_arg,
+      umap_asin,
+      umap_asinh,
+      umap_atan,
+      umap_atanh,
+      umap_ceil,
+      umap_conj,
+      umap_cos,
+      umap_cosh,
+      umap_erf,
+      umap_erfc,
+      umap_exp,
+      umap_expm1,
+      umap_finite,
+      umap_fix,
+      umap_floor,
+      umap_gamma,
+      umap_imag,
+      umap_isinf,
+      umap_isna,
+      umap_isnan,
+      umap_lgamma,
+      umap_log,
+      umap_log2,
+      umap_log10,
+      umap_log1p,
+      umap_real,
+      umap_round,
+      umap_roundb,
+      umap_signum,
+      umap_sin,
+      umap_sinh,
+      umap_sqrt,
+      umap_tan,
+      umap_tanh,
+      umap_xisalnum,
+      umap_xisalpha,
+      umap_xisascii,
+      umap_xiscntrl,
+      umap_xisdigit,
+      umap_xisgraph,
+      umap_xislower,
+      umap_xisprint,
+      umap_xispunct,
+      umap_xisspace,
+      umap_xisupper,
+      umap_xisxdigit,
+      umap_xtoascii,
+      umap_xtolower,
+      umap_xtoupper,
+      umap_unknown,
+      num_unary_mappers = umap_unknown
+    };
+
   virtual octave_value map (unary_mapper_t) const;
 
 protected:
@@ -732,6 +729,8 @@
 
 private:
 
+  static const char *get_umap_name (unary_mapper_t);
+
   static int curr_print_indent_level;
   static bool beginning_of_line;
 
--- a/src/ov-cell.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-cell.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -1426,6 +1426,35 @@
   return retval;
 }
 
+octave_value
+octave_cell::map (unary_mapper_t umap) const
+{
+  switch (umap)
+    {
+#define FORWARD_MAPPER(UMAP) \
+    case umap_ ## UMAP: \
+      return matrix.UMAP ()
+    FORWARD_MAPPER (xisalnum);
+    FORWARD_MAPPER (xisalpha);
+    FORWARD_MAPPER (xisascii);
+    FORWARD_MAPPER (xiscntrl);
+    FORWARD_MAPPER (xisdigit);
+    FORWARD_MAPPER (xisgraph);
+    FORWARD_MAPPER (xislower);
+    FORWARD_MAPPER (xisprint);
+    FORWARD_MAPPER (xispunct);
+    FORWARD_MAPPER (xisspace);
+    FORWARD_MAPPER (xisupper);
+    FORWARD_MAPPER (xisxdigit);
+    FORWARD_MAPPER (xtoascii);
+    FORWARD_MAPPER (xtolower);
+    FORWARD_MAPPER (xtoupper);
+    
+    default:
+      return octave_base_value::map (umap);
+    }
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/ov-cell.h	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-cell.h	Fri Nov 13 11:45:39 2009 +0100
@@ -155,8 +155,7 @@
   bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
 #endif
 
-  octave_value map (unary_mapper_t umap) const
-    { return matrix.map (umap); }
+  octave_value map (unary_mapper_t umap) const;
 
   mxArray *as_mxArray (void) const;
 
--- a/src/ov-ch-mat.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-ch-mat.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -168,24 +168,24 @@
   switch (umap)
     {
 #define STRING_MAPPER(UMAP,FCN,TYPE) \
-    case UMAP: \
+    case umap_ ## UMAP: \
       return octave_value (matrix.map<TYPE, int (&) (int)> (FCN))
 
-    STRING_MAPPER (umap_isalnum, std::isalnum, bool);
-    STRING_MAPPER (umap_isalpha, std::isalpha, bool);
-    STRING_MAPPER (umap_isascii, xisascii, bool);
-    STRING_MAPPER (umap_iscntrl, std::iscntrl, bool);
-    STRING_MAPPER (umap_isdigit, std::isdigit, bool);
-    STRING_MAPPER (umap_isgraph, std::isgraph, bool);
-    STRING_MAPPER (umap_islower, std::islower, bool);
-    STRING_MAPPER (umap_isprint, std::isprint, bool);
-    STRING_MAPPER (umap_ispunct, std::ispunct, bool);
-    STRING_MAPPER (umap_isspace, std::isspace, bool);
-    STRING_MAPPER (umap_isupper, std::isupper, bool);
-    STRING_MAPPER (umap_isxdigit, std::isxdigit, bool);
-    STRING_MAPPER (umap_toascii, xtoascii, double);
-    STRING_MAPPER (umap_tolower, std::tolower, char);
-    STRING_MAPPER (umap_toupper, std::toupper, char);
+    STRING_MAPPER (xisalnum, std::isalnum, bool);
+    STRING_MAPPER (xisalpha, std::isalpha, bool);
+    STRING_MAPPER (xisascii, xisascii, bool);
+    STRING_MAPPER (xiscntrl, std::iscntrl, bool);
+    STRING_MAPPER (xisdigit, std::isdigit, bool);
+    STRING_MAPPER (xisgraph, std::isgraph, bool);
+    STRING_MAPPER (xislower, std::islower, bool);
+    STRING_MAPPER (xisprint, std::isprint, bool);
+    STRING_MAPPER (xispunct, std::ispunct, bool);
+    STRING_MAPPER (xisspace, std::isspace, bool);
+    STRING_MAPPER (xisupper, std::isupper, bool);
+    STRING_MAPPER (xisxdigit, std::isxdigit, bool);
+    STRING_MAPPER (xtoascii, xtoascii, double);
+    STRING_MAPPER (xtolower, std::tolower, char);
+    STRING_MAPPER (xtoupper, std::toupper, char);
 
     default: 
       {
--- a/src/ov-cx-sparse.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-cx-sparse.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -876,7 +876,7 @@
       ARRAY_MAPPER (finite, bool, xfinite);
 
     default: // Attempt to go via dense matrix.
-      return full_value ().map (umap).sparse_matrix_value ();
+      return octave_base_sparse<SparseComplexMatrix>::map (umap);
     }
 }
 
--- a/src/ov-re-mat.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-re-mat.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -768,7 +768,13 @@
       ARRAY_MAPPER (isna, bool, octave_is_NA);
 
     default:
-      return octave_base_value::map (umap);
+      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/src/ov-re-sparse.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-re-sparse.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -868,7 +868,7 @@
       ARRAY_MAPPER (finite, bool, xfinite);
 
     default: // Attempt to go via dense matrix.
-      return full_value ().map (umap).sparse_matrix_value ();
+      return octave_base_sparse<SparseMatrix>::map (umap);
     }
 }
 
--- a/src/ov-scalar.cc	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov-scalar.cc	Fri Nov 13 11:45:39 2009 +0100
@@ -321,7 +321,13 @@
       SCALAR_MAPPER (isnan, xisnan);
 
     default:
-      return octave_base_value::map (umap);
+      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/src/ov.h	Thu Nov 12 15:47:58 2009 +0100
+++ b/src/ov.h	Fri Nov 13 11:45:39 2009 +0100
@@ -1076,8 +1076,72 @@
 
   void dump (std::ostream& os) const { rep->dump (os); }
 
-  octave_value map (unary_mapper_t umap) const
-    { return rep->map (umap); } 
+#define MAPPER_FORWARD(F) \
+  octave_value F (void) const { return rep->map (octave_base_value::umap_ ## F); }
+
+  MAPPER_FORWARD (abs)
+  MAPPER_FORWARD (acos)
+  MAPPER_FORWARD (acosh)
+  MAPPER_FORWARD (angle)
+  MAPPER_FORWARD (arg)
+  MAPPER_FORWARD (asin)
+  MAPPER_FORWARD (asinh)
+  MAPPER_FORWARD (atan)
+  MAPPER_FORWARD (atanh)
+  MAPPER_FORWARD (ceil)
+  MAPPER_FORWARD (conj)
+  MAPPER_FORWARD (cos)
+  MAPPER_FORWARD (cosh)
+  MAPPER_FORWARD (erf)
+  MAPPER_FORWARD (erfc)
+  MAPPER_FORWARD (exp)
+  MAPPER_FORWARD (expm1)
+  MAPPER_FORWARD (finite)
+  MAPPER_FORWARD (fix)
+  MAPPER_FORWARD (floor)
+  MAPPER_FORWARD (gamma)
+  MAPPER_FORWARD (imag)
+  MAPPER_FORWARD (isinf)
+  MAPPER_FORWARD (isna)
+  MAPPER_FORWARD (isnan)
+  MAPPER_FORWARD (lgamma)
+  MAPPER_FORWARD (log)
+  MAPPER_FORWARD (log2)
+  MAPPER_FORWARD (log10)
+  MAPPER_FORWARD (log1p)
+  MAPPER_FORWARD (real)
+  MAPPER_FORWARD (round)
+  MAPPER_FORWARD (roundb)
+  MAPPER_FORWARD (signum)
+  MAPPER_FORWARD (sin)
+  MAPPER_FORWARD (sinh)
+  MAPPER_FORWARD (sqrt)
+  MAPPER_FORWARD (tan)
+  MAPPER_FORWARD (tanh)
+
+  // These functions are prefixed with X to avoid potential macro
+  // conflicts.
+
+  MAPPER_FORWARD (xisalnum)
+  MAPPER_FORWARD (xisalpha)
+  MAPPER_FORWARD (xisascii)
+  MAPPER_FORWARD (xiscntrl)
+  MAPPER_FORWARD (xisdigit)
+  MAPPER_FORWARD (xisgraph)
+  MAPPER_FORWARD (xislower)
+  MAPPER_FORWARD (xisprint)
+  MAPPER_FORWARD (xispunct)
+  MAPPER_FORWARD (xisspace)
+  MAPPER_FORWARD (xisupper)
+  MAPPER_FORWARD (xisxdigit)
+  MAPPER_FORWARD (xtoascii)
+  MAPPER_FORWARD (xtolower)
+  MAPPER_FORWARD (xtoupper)
+
+#undef MAPPER_FORWARD
+
+  octave_value map (octave_base_value::unary_mapper_t umap) const
+    { return rep->map (umap); }
 
 protected: