changeset 9812:f80c566bc751

improve unary mapper system
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 12 Nov 2009 15:47:58 +0100
parents c657c056240d
children 8fa32b527d9a
files liboctave/Array.h liboctave/Array2.h liboctave/CColVector.cc liboctave/CColVector.h liboctave/CDiagMatrix.cc liboctave/CMatrix.cc liboctave/CMatrix.h liboctave/CNDArray.cc liboctave/CNDArray.h liboctave/CRowVector.cc liboctave/CRowVector.h liboctave/CSparse.cc liboctave/CSparse.h liboctave/ChangeLog liboctave/MArray.h liboctave/MArray2.h liboctave/MArrayN.h liboctave/MSparse.h liboctave/Sparse.h liboctave/chNDArray.cc liboctave/chNDArray.h liboctave/dColVector.cc liboctave/dColVector.h liboctave/dDiagMatrix.cc liboctave/dMatrix.cc liboctave/dMatrix.h liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/dRowVector.cc liboctave/dRowVector.h liboctave/dSparse.cc liboctave/dSparse.h liboctave/fCColVector.cc liboctave/fCColVector.h liboctave/fCDiagMatrix.cc liboctave/fCMatrix.cc liboctave/fCMatrix.h liboctave/fCNDArray.cc liboctave/fCNDArray.h liboctave/fCRowVector.cc liboctave/fCRowVector.h liboctave/fColVector.cc liboctave/fColVector.h liboctave/fDiagMatrix.cc liboctave/fMatrix.cc liboctave/fMatrix.h liboctave/fNDArray.cc liboctave/fNDArray.h liboctave/fRowVector.cc liboctave/fRowVector.h liboctave/lo-mappers.cc liboctave/lo-mappers.h liboctave/lo-specfun.cc liboctave/lo-specfun.h src/Cell.cc src/Cell.h src/ChangeLog src/DLD-FUNCTIONS/lookup.cc src/data.cc src/mappers.cc src/ov-base-diag.cc src/ov-base-diag.h src/ov-base.cc src/ov-base.h src/ov-bool-mat.h src/ov-bool-sparse.h src/ov-bool.h src/ov-cell.h src/ov-ch-mat.cc src/ov-ch-mat.h src/ov-complex.cc src/ov-complex.h src/ov-cx-diag.cc src/ov-cx-diag.h src/ov-cx-mat.cc src/ov-cx-mat.h src/ov-cx-sparse.cc src/ov-cx-sparse.h src/ov-float.cc src/ov-float.h src/ov-flt-complex.cc src/ov-flt-complex.h src/ov-flt-cx-diag.cc src/ov-flt-cx-diag.h src/ov-flt-cx-mat.cc src/ov-flt-cx-mat.h src/ov-flt-re-diag.cc src/ov-flt-re-diag.h src/ov-flt-re-mat.cc src/ov-flt-re-mat.h src/ov-intx.h src/ov-perm.cc src/ov-perm.h src/ov-range.h src/ov-re-diag.cc src/ov-re-diag.h src/ov-re-mat.cc src/ov-re-mat.h src/ov-re-sparse.cc src/ov-re-sparse.h src/ov-scalar.cc src/ov-scalar.h src/ov.h
diffstat 103 files changed, 1447 insertions(+), 3105 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/Array.h	Thu Nov 12 15:47:58 2009 +0100
@@ -666,16 +666,36 @@
     Array<U> result (dims ());
     U *p = result.fortran_vec ();
 
-    for (octave_idx_type i = 0; i < len; i++)
+    octave_idx_type i;
+    for (i = 0; i < len - 3; i += 4)
       {
 	OCTAVE_QUIT;
 
-	p[i] = fcn (m[i]);
+        p[i] = fcn (m[i]);
+        p[i+1] = fcn (m[i+1]);
+        p[i+2] = fcn (m[i+2]);
+        p[i+3] = fcn (m[i+3]);
       }
 
+    OCTAVE_QUIT;
+
+    for (; i < len; i++)
+      p[i] = fcn (m[i]);
+
     return result;
   }
 
+  // Overloads for function references.
+  template <class U>
+  Array<U>
+  map (U (&fcn) (T)) const
+  { return map<U, U (&) (T)> (fcn); }
+
+  template <class U>
+  Array<U>
+  map (U (&fcn) (const T&)) const
+  { return map<U, U (&) (const T&)> (fcn); }
+
   template <class U> friend class Array;
 
 private:
--- a/liboctave/Array2.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/Array2.h	Thu Nov 12 15:47:58 2009 +0100
@@ -148,11 +148,16 @@
     return Array<T>::diag (k);
   }
 
-  template <class U, class F>
-  Array2<U> map (F fcn) const
-  {
-    return Array<T>::template map<U> (fcn);
-  }
+  // FIXME: should go away.
+  template <class U>
+  Array2<U>
+  map (U (&fcn) (T)) const
+  { return Array<T>::template map<U> (fcn); }
+
+  template <class U>
+  Array2<U>
+  map (U (&fcn) (const T&)) const
+  { return Array<T>::template map<U> (fcn); }
 };
 
 #endif
--- a/liboctave/CColVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CColVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -453,18 +453,6 @@
 
 // other operations
 
-ColumnVector
-ComplexColumnVector::map (dmapper fcn) const
-{
-  return MArray<Complex>::map<double> (func_ptr (fcn));
-}
-
-ComplexColumnVector
-ComplexColumnVector::map (cmapper fcn) const
-{
-  return MArray<Complex>::map<Complex> (func_ptr (fcn));
-}
-
 Complex
 ComplexColumnVector::min (void) const
 {
--- a/liboctave/CColVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CColVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -116,12 +116,6 @@
 
   // other operations
 
-  typedef double (*dmapper) (const Complex&);
-  typedef Complex (*cmapper) (const Complex&);
-
-  ColumnVector map (dmapper fcn) const;
-  ComplexColumnVector map (cmapper fcn) const;
-
   Complex min (void) const;
   Complex max (void) const;
 
--- a/liboctave/CDiagMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CDiagMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -564,7 +564,7 @@
 double
 ComplexDiagMatrix::rcond (void) const
 {
-  ColumnVector av = diag (0).map (std::abs);
+  ColumnVector av = diag (0).map<double> (std::abs);
   double amx = av.max (), amn = av.min ();
   return amx == 0 ? 0.0 : amn / amx;
 }
--- a/liboctave/CMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -3079,24 +3079,6 @@
 
 // other operations
 
-Matrix
-ComplexMatrix::map (dmapper fcn) const
-{
-  return MArray2<Complex>::map<double> (func_ptr (fcn));
-}
-
-ComplexMatrix
-ComplexMatrix::map (cmapper fcn) const
-{
-  return MArray2<Complex>::map<Complex> (func_ptr (fcn));
-}
-
-boolMatrix
-ComplexMatrix::map (bmapper fcn) const
-{
-  return MArray2<Complex>::map<bool> (func_ptr (fcn));
-}
-
 bool
 ComplexMatrix::any_element_is_nan (void) const
 {
--- a/liboctave/CMatrix.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CMatrix.h	Thu Nov 12 15:47:58 2009 +0100
@@ -333,14 +333,6 @@
 
   // other operations
 
-  typedef double (*dmapper) (const Complex&);
-  typedef Complex (*cmapper) (const Complex&);
-  typedef bool (*bmapper) (const Complex&);
-
-  Matrix map (dmapper fcn) const;
-  ComplexMatrix map (cmapper fcn) const;
-  boolMatrix map (bmapper fcn) const;
-
   bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool all_elements_are_real (void) const;
--- a/liboctave/CNDArray.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CNDArray.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -886,24 +886,6 @@
   return MArrayN<Complex>::diag (k);
 }
 
-NDArray
-ComplexNDArray::map (dmapper fcn) const
-{
-  return MArrayN<Complex>::map<double> (func_ptr (fcn));
-}
-
-ComplexNDArray
-ComplexNDArray::map (cmapper fcn) const
-{
-  return MArrayN<Complex>::map<Complex> (func_ptr (fcn));
-}
-
-boolNDArray
-ComplexNDArray::map (bmapper fcn) const
-{
-  return MArrayN<Complex>::map<bool> (func_ptr (fcn));
-}
-
 // This contains no information on the array structure !!!
 std::ostream&
 operator << (std::ostream& os, const ComplexNDArray& a)
--- a/liboctave/CNDArray.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CNDArray.h	Thu Nov 12 15:47:58 2009 +0100
@@ -148,14 +148,6 @@
       return *this; 
     }
 
-  typedef double (*dmapper) (const Complex&);
-  typedef Complex (*cmapper) (const Complex&);
-  typedef bool (*bmapper) (const Complex&);
-
-  NDArray map (dmapper fcn) const;
-  ComplexNDArray map (cmapper fcn) const;
-  boolNDArray map (bmapper fcn) const;
-
 private:
 
   ComplexNDArray (Complex *d, const dim_vector& dv)
--- a/liboctave/CRowVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CRowVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -366,18 +366,6 @@
 
 // other operations
 
-RowVector
-ComplexRowVector::map (dmapper fcn) const
-{
-  return MArray<Complex>::map<double> (func_ptr (fcn));
-}
-
-ComplexRowVector
-ComplexRowVector::map (cmapper fcn) const
-{
-  return MArray<Complex>::map<Complex> (func_ptr (fcn));
-}
-
 Complex
 ComplexRowVector::min (void) const
 {
--- a/liboctave/CRowVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CRowVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -98,12 +98,6 @@
 
   // other operations
 
-  typedef double (*dmapper) (const Complex&);
-  typedef Complex (*cmapper) (const Complex&);
-
-  RowVector map (dmapper fcn) const;
-  ComplexRowVector map (cmapper fcn) const;
-
   Complex min (void) const;
   Complex max (void) const;
 
--- a/liboctave/CSparse.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CSparse.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -7432,24 +7432,6 @@
   return MSparse<Complex>::diag (k);
 }
 
-SparseMatrix
-SparseComplexMatrix::map (dmapper fcn) const
-{
-  return MSparse<Complex>::map<double> (func_ptr (fcn));
-}
-
-SparseComplexMatrix
-SparseComplexMatrix::map (cmapper fcn) const
-{
-  return MSparse<Complex>::map<Complex> (func_ptr (fcn));
-}
-
-SparseBoolMatrix
-SparseComplexMatrix::map (bmapper fcn) const
-{
-  return MSparse<Complex>::map<bool> (func_ptr (fcn));
-}
-
 std::ostream&
 operator << (std::ostream& os, const SparseComplexMatrix& a)
 {
--- a/liboctave/CSparse.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/CSparse.h	Thu Nov 12 15:47:58 2009 +0100
@@ -438,13 +438,6 @@
 				    const SparseComplexMatrix& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, 
 				    SparseComplexMatrix& a);
-
-  typedef double (*dmapper) (const Complex&);
-  typedef Complex (*cmapper) (const Complex&);
-  typedef bool (*bmapper) (const Complex&);
-  SparseMatrix map (dmapper fcn) const;
-  SparseComplexMatrix map (cmapper fcn) const;
-  SparseBoolMatrix map (bmapper fcn) const;
 };
 
 extern OCTAVE_API SparseComplexMatrix operator * (const SparseMatrix&,        
--- a/liboctave/ChangeLog	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/ChangeLog	Thu Nov 12 15:47:58 2009 +0100
@@ -1,3 +1,64 @@
+2009-11-12  Jaroslav Hajek  <highegg@gmail.com>
+
+	* lo-mappers.cc ( rc_acos, rc_acos, rc_acosh, rc_acosh, rc_asin,
+	rc_asin, rc_atanh, rc_atanh, rc_log, rc_log, rc_xlog2, rc_log2,
+	rc_log10, rc_log10, rc_sqrt, rc_sqrt): New mappers.
+	* lo-mappers.h: Declare them.
+
+	* lo-specfun.cc (rc_lgamma, rc_lgamma, rc_log1p, rc_log1p): New
+	mappers.
+	* lo-specfun.h: Declare them.
+	* Array.h (Array<T>::map): Unroll loop to reduce OCTAVE_QUIT checking.
+	Provide function-reference overloads.
+
+	* MArray.h (MArray<T>::map): Provide function-reference overloads.
+	* Array2.h (Array2<T>::map): Ditto.
+	* MArray2.h (MArray2<T>::map): Ditto.
+
+	* Sparse.h (Sparse<T>::map): Ditto.
+	* MSparse.h (MSparse<T>::map): Ditto.
+
+	* dNDArray.h (NDArray::map): Remove.
+	* dNDArray.cc (NDArray::map): Remove.
+	* fNDArray.h (FloatNDArray::map): Remove.
+	* fNDArray.cc (FloatNDArray::map): Remove.
+	* CNDArray.h (ComplexNDArray::map): Remove.
+	* CNDArray.cc (ComplexNDArray::map): Remove.
+	* fCNDArray.h (FloatComplexNDArray::map): Remove.
+	* fCNDArray.cc (FloatComplexNDArray::map): Remove.
+
+	* dMatrix.h (Matrix::map): Remove.
+	* dMatrix.cc (Matrix::map): Remove.
+	* fMatrix.h (FloatMatrix::map): Remove.
+	* fMatrix.cc (FloatMatrix::map): Remove.
+	* CMatrix.h (ComplexMatrix::map): Remove.
+	* CMatrix.cc (ComplexMatrix::map): Remove.
+	* fCMatrix.h (FloatComplexMatrix::map): Remove.
+	* fCMatrix.cc (FloatComplexMatrix::map): Remove.
+
+	* dRowVector.h (RowVector::map): Remove.
+	* dRowVector.cc (RowVector::map): Remove.
+	* fRowVector.h (FloatRowVector::map): Remove.
+	* fRowVector.cc (FloatRowVector::map): Remove.
+	* CRowVector.h (ComplexRowVector::map): Remove.
+	* CRowVector.cc (ComplexRowVector::map): Remove.
+	* fCRowVector.h (FloatComplexRowVector::map): Remove.
+	* fCRowVector.cc (FloatComplexRowVector::map): Remove.
+
+	* dColVector.h (ColumnVector::map): Remove.
+	* dColVector.cc (ColumnVector::map): Remove.
+	* fColVector.h (FloatColumnVector::map): Remove.
+	* fColVector.cc (FloatColumnVector::map): Remove.
+	* CColVector.h (ComplexColumnVector::map): Remove.
+	* CColVector.cc (ComplexColumnVector::map): Remove.
+	* fCColVector.h (FloatComplexColumnVector::map): Remove.
+	* fCColVector.cc (FloatComplexColumnVector::map): Remove.
+
+	* dSparse.h (SparseMatrix::map): Remove.
+	* dSparse.cc (SparseMatrix::map): Remove.
+	* CSparse.h (SparseComplexMatrix::map): Remove.
+	* CSparse.cc (SparseComplexMatrix::map): Remove.
+
 2009-11-11  John W. Eaton  <jwe@octave.org>
 
 	* lo-ieee.cc (octave_ieee_init): Improve comment about systems
--- a/liboctave/MArray.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/MArray.h	Thu Nov 12 15:47:58 2009 +0100
@@ -93,11 +93,16 @@
   double norm (double p) const;
   float norm (float p) const;
 
-  template <class U, class F>
-  MArray<U> map (F fcn) const
-  {
-    return Array<T>::template map<U> (fcn);
-  }
+  // FIXME: should go away.
+  template <class U>
+  MArray<U>
+  map (U (&fcn) (T)) const
+  { return Array<T>::template map<U> (fcn); }
+
+  template <class U>
+  MArray<U>
+  map (U (&fcn) (const T&)) const
+  { return Array<T>::template map<U> (fcn); }
 
   // Performs indexed accumulative addition.
 
--- a/liboctave/MArray2.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/MArray2.h	Thu Nov 12 15:47:58 2009 +0100
@@ -87,11 +87,16 @@
     return Array2<T>::diag (k);
   }
 
-  template <class U, class F>
-  MArray2<U> map (F fcn) const
-  {
-    return Array2<T>::template map<U> (fcn);
-  }
+  // FIXME: should go away.
+  template <class U>
+  MArray2<U>
+  map (U (&fcn) (T)) const
+  { return Array2<T>::template map<U> (fcn); }
+
+  template <class U>
+  MArray2<U>
+  map (U (&fcn) (const T&)) const
+  { return Array2<T>::template map<U> (fcn); }
 
   // Currently, the OPS functions don't need to be friends, but that
   // may change.
--- a/liboctave/MArrayN.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/MArrayN.h	Thu Nov 12 15:47:58 2009 +0100
@@ -104,12 +104,6 @@
     return Array<T>::diag (k);
   }
 
-  template <class U, class F>
-  MArrayN<U> map (F fcn) const
-  {
-    return Array<T>::template map<U> (fcn);
-  }
-
   void changesign (void);
 };
 
--- a/liboctave/MSparse.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/MSparse.h	Thu Nov 12 15:47:58 2009 +0100
@@ -117,11 +117,16 @@
     return Sparse<T>::diag (k);
   }
 
- template <class U, class F>
-  MSparse<U> map (F fcn) const
-  {
-    return Sparse<T>::template map<U> (fcn);
-  }
+  // FIXME: should go away.
+  template <class U>
+  MSparse<U>
+  map (U (&fcn) (T)) const
+  { return Sparse<T>::template map<U> (fcn); }
+
+  template <class U>
+  MSparse<U>
+  map (U (&fcn) (const T&)) const
+  { return Sparse<T>::template map<U> (fcn); }
 
   // Currently, the OPS functions don't need to be friends, but that
   // may change.
--- a/liboctave/Sparse.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/Sparse.h	Thu Nov 12 15:47:58 2009 +0100
@@ -569,6 +569,17 @@
     return result;
   }
 
+  // Overloads for function references.
+  template <class U>
+  Sparse<U>
+  map (U (&fcn) (T)) const
+  { return map<U, U (&) (T)> (fcn); }
+
+  template <class U>
+  Sparse<U>
+  map (U (&fcn) (const T&)) const
+  { return map<U, U (&) (const T&)> (fcn); }
+
   bool indices_ok (void) const { return rep->indices_ok (); }
 };
 
--- a/liboctave/chNDArray.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/chNDArray.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -152,60 +152,6 @@
   return MArrayN<char>::diag (k);
 }
 
-boolNDArray
-charNDArray::bmap (mapper fcn) const
-{
-  octave_idx_type len = length ();
-  const char *m = fortran_vec();
-  boolNDArray result (dims ());
-  bool *p = result.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      p[i] = bool (fcn (m[i]));
-    }
-
-  return result;
-}
-
-NDArray
-charNDArray::dmap (mapper fcn) const
-{
-  octave_idx_type len = length ();
-  const char *m = fortran_vec();
-  NDArray result (dims ());
-  double *p = result.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      p[i] = fcn (m[i]);
-    }
-
-  return result;
-}
-
-charNDArray
-charNDArray::smap (mapper fcn) const
-{
-  octave_idx_type len = length ();
-  const char *m = fortran_vec();
-  charNDArray result (dims ());
-  char *p = result.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      p[i] = fcn (m[i]);
-    }
-
-  return result;
-}
-
 NDS_CMP_OPS (charNDArray, char)
 NDS_BOOL_OPS (charNDArray, char)
 
--- a/liboctave/chNDArray.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/chNDArray.h	Thu Nov 12 15:47:58 2009 +0100
@@ -95,11 +95,6 @@
 
   charNDArray diag (octave_idx_type k = 0) const;
 
-  typedef int (*mapper) (int);
-  boolNDArray bmap (mapper fcn) const;
-  NDArray dmap (mapper fcn) const;
-  charNDArray smap (mapper fcn) const;
-
 private:
 
   charNDArray (char *d, dim_vector& dv) : MArrayN<char> (d, dv) { }
--- a/liboctave/dColVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dColVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -260,18 +260,6 @@
 
 // other operations
 
-ColumnVector
-ColumnVector::map (dmapper fcn) const
-{
-  return MArray<double>::map<double> (func_ptr (fcn));
-}
-
-ComplexColumnVector
-ColumnVector::map (cmapper fcn) const
-{
-  return MArray<double>::map<Complex> (func_ptr (fcn));
-}
-
 double
 ColumnVector::min (void) const
 {
--- a/liboctave/dColVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dColVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -85,12 +85,6 @@
 
   // other operations
 
-  typedef double (*dmapper) (double);
-  typedef Complex (*cmapper) (const Complex&);
-
-  ColumnVector map (dmapper fcn) const;
-  ComplexColumnVector map (cmapper fcn) const;
-
   double min (void) const;
   double max (void) const;
 
--- a/liboctave/dDiagMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dDiagMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -376,7 +376,7 @@
 double
 DiagMatrix::rcond (void) const
 {
-  ColumnVector av  = diag (0).map (fabs);
+  ColumnVector av  = diag (0).map<double> (fabs);
   double amx = av.max (), amn = av.min ();
   return amx == 0 ? 0.0 : amn / amx;
 }
--- a/liboctave/dMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -2637,24 +2637,6 @@
 
 // other operations.
 
-Matrix
-Matrix::map (dmapper fcn) const
-{
-  return MArray2<double>::map<double> (func_ptr (fcn));
-}
-
-ComplexMatrix
-Matrix::map (cmapper fcn) const
-{
-  return MArray2<double>::map<Complex> (func_ptr (fcn));
-}
-
-boolMatrix
-Matrix::map (bmapper fcn) const
-{
-  return MArray2<double>::map<bool> (func_ptr (fcn));
-}
-
 bool
 Matrix::any_element_is_negative (bool neg_zero) const
 {
--- a/liboctave/dMatrix.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dMatrix.h	Thu Nov 12 15:47:58 2009 +0100
@@ -287,14 +287,6 @@
 
   // other operations
 
-  typedef double (*dmapper) (double);
-  typedef Complex (*cmapper) (const Complex&);
-  typedef bool (*bmapper) (double);
-
-  Matrix map (dmapper fcn) const;
-  ComplexMatrix map (cmapper fcn) const;
-  boolMatrix map (bmapper fcn) const;
-
   bool any_element_is_negative (bool = false) const;
   bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
--- a/liboctave/dNDArray.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dNDArray.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -931,24 +931,6 @@
   return MArrayN<double>::diag (k);
 }
 
-NDArray
-NDArray::map (dmapper fcn) const
-{
-  return MArrayN<double>::map<double> (func_ptr (fcn));
-}
-
-ComplexNDArray
-NDArray::map (cmapper fcn) const
-{
-  return MArrayN<double>::map<Complex> (func_ptr (fcn));
-}
-
-boolNDArray
-NDArray::map (bmapper fcn) const
-{
-  return MArrayN<double>::map<bool> (func_ptr (fcn));
-}
-
 // This contains no information on the array structure !!!
 std::ostream&
 operator << (std::ostream& os, const NDArray& a)
--- a/liboctave/dNDArray.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dNDArray.h	Thu Nov 12 15:47:58 2009 +0100
@@ -159,14 +159,6 @@
       return *this; 
     }
 
-  typedef double (*dmapper) (double);
-  typedef Complex (*cmapper) (const Complex&);
-  typedef bool (*bmapper) (double);
-
-  NDArray map (dmapper fcn) const;
-  ComplexNDArray map (cmapper fcn) const;
-  boolNDArray map (bmapper fcn) const;
-
 private:
 
   NDArray (double *d, const dim_vector& dv) : MArrayN<double> (d, dv) { }
--- a/liboctave/dRowVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dRowVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -232,18 +232,6 @@
 
 // other operations
 
-RowVector
-RowVector::map (dmapper fcn) const
-{
-  return MArray<double>::map<double> (func_ptr (fcn));
-}
-
-ComplexRowVector
-RowVector::map (cmapper fcn) const
-{
-  return MArray<double>::map<Complex> (func_ptr (fcn));
-}
-
 double
 RowVector::min (void) const
 {
--- a/liboctave/dRowVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dRowVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -81,12 +81,6 @@
 
   // other operations
 
-  typedef double (*dmapper) (double);
-  typedef Complex (*cmapper) (const Complex&);
-
-  RowVector map (dmapper fcn) const;
-  ComplexRowVector map (cmapper fcn) const;
-
   double min (void) const;
   double max (void) const;
 
--- a/liboctave/dSparse.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dSparse.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -7550,24 +7550,6 @@
   return retval;
 }
 
-SparseMatrix
-SparseMatrix::map (dmapper fcn) const
-{
-  return MSparse<double>::map<double> (func_ptr (fcn));
-}
-
-SparseComplexMatrix
-SparseMatrix::map (cmapper fcn) const
-{
-  return MSparse<double>::map<Complex> (func_ptr (fcn));
-}
-
-SparseBoolMatrix
-SparseMatrix::map (bmapper fcn) const
-{
-  return MSparse<double>::map<bool> (func_ptr (fcn));
-}
-
 std::ostream&
 operator << (std::ostream& os, const SparseMatrix& a)
 {
--- a/liboctave/dSparse.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/dSparse.h	Thu Nov 12 15:47:58 2009 +0100
@@ -426,12 +426,6 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const SparseMatrix& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, SparseMatrix& a);
 
-  typedef double (*dmapper) (double);
-  typedef Complex (*cmapper) (const Complex&);
-  typedef bool (*bmapper) (double);
-  SparseMatrix map (dmapper fcn) const;
-  SparseComplexMatrix map (cmapper fcn) const;
-  SparseBoolMatrix map (bmapper fcn) const;
 };
 
 // Publish externally used friend functions.
--- a/liboctave/fCColVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCColVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -453,18 +453,6 @@
 
 // other operations
 
-FloatColumnVector
-FloatComplexColumnVector::map (dmapper fcn) const
-{
-  return MArray<FloatComplex>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexColumnVector
-FloatComplexColumnVector::map (cmapper fcn) const
-{
-  return MArray<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
-}
-
 FloatComplex
 FloatComplexColumnVector::min (void) const
 {
--- a/liboctave/fCColVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCColVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -116,12 +116,6 @@
 
   // other operations
 
-  typedef float (*dmapper) (const FloatComplex&);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-
-  FloatColumnVector map (dmapper fcn) const;
-  FloatComplexColumnVector map (cmapper fcn) const;
-
   FloatComplex min (void) const;
   FloatComplex max (void) const;
 
--- a/liboctave/fCDiagMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCDiagMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -564,7 +564,7 @@
 float
 FloatComplexDiagMatrix::rcond (void) const
 {
-  FloatColumnVector av = diag (0).map (std::abs);
+  FloatColumnVector av = diag (0).map<float> (std::abs);
   float amx = av.max (), amn = av.min ();
   return amx == 0 ? 0.0f : amn / amx;
 }
--- a/liboctave/fCMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -3072,24 +3072,6 @@
 
 // other operations
 
-FloatMatrix
-FloatComplexMatrix::map (dmapper fcn) const
-{
-  return MArray2<FloatComplex>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexMatrix
-FloatComplexMatrix::map (cmapper fcn) const
-{
-  return MArray2<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
-}
-
-boolMatrix
-FloatComplexMatrix::map (bmapper fcn) const
-{
-  return MArray2<FloatComplex>::map<bool> (func_ptr (fcn));
-}
-
 bool
 FloatComplexMatrix::any_element_is_nan (void) const
 {
--- a/liboctave/fCMatrix.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCMatrix.h	Thu Nov 12 15:47:58 2009 +0100
@@ -333,14 +333,6 @@
 
   // other operations
 
-  typedef float (*dmapper) (const FloatComplex&);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-  typedef bool (*bmapper) (const FloatComplex&);
-
-  FloatMatrix map (dmapper fcn) const;
-  FloatComplexMatrix map (cmapper fcn) const;
-  boolMatrix map (bmapper fcn) const;
-
   bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
   bool all_elements_are_real (void) const;
--- a/liboctave/fCNDArray.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCNDArray.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -881,24 +881,6 @@
   return MArrayN<FloatComplex>::diag (k);
 }
 
-FloatNDArray
-FloatComplexNDArray::map (dmapper fcn) const
-{
-  return MArrayN<FloatComplex>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexNDArray
-FloatComplexNDArray::map (cmapper fcn) const
-{
-  return MArrayN<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
-}
-
-boolNDArray
-FloatComplexNDArray::map (bmapper fcn) const
-{
-  return MArrayN<FloatComplex>::map<bool> (func_ptr (fcn));
-}
-
 // This contains no information on the array structure !!!
 std::ostream&
 operator << (std::ostream& os, const FloatComplexNDArray& a)
--- a/liboctave/fCNDArray.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCNDArray.h	Thu Nov 12 15:47:58 2009 +0100
@@ -148,14 +148,6 @@
       return *this; 
     }
 
-  typedef float (*dmapper) (const FloatComplex&);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-  typedef bool (*bmapper) (const FloatComplex&);
-
-  FloatNDArray map (dmapper fcn) const;
-  FloatComplexNDArray map (cmapper fcn) const;
-  boolNDArray map (bmapper fcn) const;
-
 private:
 
   FloatComplexNDArray (FloatComplex *d, const dim_vector& dv)
--- a/liboctave/fCRowVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCRowVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -366,18 +366,6 @@
 
 // other operations
 
-FloatRowVector
-FloatComplexRowVector::map (dmapper fcn) const
-{
-  return MArray<FloatComplex>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexRowVector
-FloatComplexRowVector::map (cmapper fcn) const
-{
-  return MArray<FloatComplex>::map<FloatComplex> (func_ptr (fcn));
-}
-
 FloatComplex
 FloatComplexRowVector::min (void) const
 {
--- a/liboctave/fCRowVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fCRowVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -98,12 +98,6 @@
 
   // other operations
 
-  typedef float (*dmapper) (const FloatComplex&);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-
-  FloatRowVector map (dmapper fcn) const;
-  FloatComplexRowVector map (cmapper fcn) const;
-
   FloatComplex min (void) const;
   FloatComplex max (void) const;
 
--- a/liboctave/fColVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fColVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -260,18 +260,6 @@
 
 // other operations
 
-FloatColumnVector
-FloatColumnVector::map (dmapper fcn) const
-{
-  return MArray<float>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexColumnVector
-FloatColumnVector::map (cmapper fcn) const
-{
-  return MArray<float>::map<FloatComplex> (func_ptr (fcn));
-}
-
 float
 FloatColumnVector::min (void) const
 {
--- a/liboctave/fColVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fColVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -85,12 +85,6 @@
 
   // other operations
 
-  typedef float (*dmapper) (float);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-
-  FloatColumnVector map (dmapper fcn) const;
-  FloatComplexColumnVector map (cmapper fcn) const;
-
   float min (void) const;
   float max (void) const;
 
--- a/liboctave/fDiagMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fDiagMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -376,7 +376,7 @@
 float
 FloatDiagMatrix::rcond (void) const
 {
-  FloatColumnVector av = diag (0).map (fabsf);
+  FloatColumnVector av = diag (0).map<float> (fabsf);
   float amx = av.max (), amn = av.min ();
   return amx == 0 ? 0.0f : amn / amx;
 }
--- a/liboctave/fMatrix.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fMatrix.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -2636,24 +2636,6 @@
 
 // other operations.
 
-FloatMatrix
-FloatMatrix::map (dmapper fcn) const
-{
-  return MArray2<float>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexMatrix
-FloatMatrix::map (cmapper fcn) const
-{
-  return MArray2<float>::map<FloatComplex> (func_ptr (fcn));
-}
-
-boolMatrix
-FloatMatrix::map (bmapper fcn) const
-{
-  return MArray2<float>::map<bool> (func_ptr (fcn));
-}
-
 bool
 FloatMatrix::any_element_is_negative (bool neg_zero) const
 {
--- a/liboctave/fMatrix.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fMatrix.h	Thu Nov 12 15:47:58 2009 +0100
@@ -287,14 +287,6 @@
 
   // other operations
 
-  typedef float (*dmapper) (float);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-  typedef bool (*bmapper) (float);
-
-  FloatMatrix map (dmapper fcn) const;
-  FloatComplexMatrix map (cmapper fcn) const;
-  boolMatrix map (bmapper fcn) const;
-
   bool any_element_is_negative (bool = false) const;
   bool any_element_is_nan (void) const;
   bool any_element_is_inf_or_nan (void) const;
--- a/liboctave/fNDArray.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fNDArray.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -889,24 +889,6 @@
   return MArrayN<float>::diag (k);
 }
 
-FloatNDArray
-FloatNDArray::map (dmapper fcn) const
-{
-  return MArrayN<float>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexNDArray
-FloatNDArray::map (cmapper fcn) const
-{
-  return MArrayN<float>::map<FloatComplex> (func_ptr (fcn));
-}
-
-boolNDArray
-FloatNDArray::map (bmapper fcn) const
-{
-  return MArrayN<float>::map<bool> (func_ptr (fcn));
-}
-
 // This contains no information on the array structure !!!
 std::ostream&
 operator << (std::ostream& os, const FloatNDArray& a)
--- a/liboctave/fNDArray.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fNDArray.h	Thu Nov 12 15:47:58 2009 +0100
@@ -156,14 +156,6 @@
       return *this; 
     }
 
-  typedef float (*dmapper) (float);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-  typedef bool (*bmapper) (float);
-
-  FloatNDArray map (dmapper fcn) const;
-  FloatComplexNDArray map (cmapper fcn) const;
-  boolNDArray map (bmapper fcn) const;
-
 private:
 
   FloatNDArray (float *d, const dim_vector& dv) : MArrayN<float> (d, dv) { }
--- a/liboctave/fRowVector.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fRowVector.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -232,18 +232,6 @@
 
 // other operations
 
-FloatRowVector
-FloatRowVector::map (dmapper fcn) const
-{
-  return MArray<float>::map<float> (func_ptr (fcn));
-}
-
-FloatComplexRowVector
-FloatRowVector::map (cmapper fcn) const
-{
-  return MArray<float>::map<FloatComplex> (func_ptr (fcn));
-}
-
 float
 FloatRowVector::min (void) const
 {
--- a/liboctave/fRowVector.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/fRowVector.h	Thu Nov 12 15:47:58 2009 +0100
@@ -81,12 +81,6 @@
 
   // other operations
 
-  typedef float (*dmapper) (float);
-  typedef FloatComplex (*cmapper) (const FloatComplex&);
-
-  FloatRowVector map (dmapper fcn) const;
-  FloatComplexRowVector map (cmapper fcn) const;
-
   float min (void) const;
   float max (void) const;
 
--- a/liboctave/lo-mappers.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/lo-mappers.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -672,6 +672,94 @@
   return abs (x) >= abs (y) ? x : (xisnan (x) ? x : y);
 }
 
+Complex
+rc_acos (double x)
+{
+  return fabs (x) > 1.0 ? acos (Complex (x)) : Complex (acos (x));
+}
+
+FloatComplex
+rc_acos (float x)
+{
+  return fabsf (x) > 1.0f ? acos (FloatComplex (x)) : FloatComplex (acosf (x));
+}
+
+Complex rc_acosh (double x)
+{
+  return x < 1.0 ? acosh (Complex (x)) : Complex (acosh (x));
+}
+
+FloatComplex rc_acosh (float x)
+{
+  return x < 1.0f ? acosh (FloatComplex (x)) : FloatComplex (acoshf (x));
+}
+
+Complex rc_asin (double x)
+{
+  return fabs (x) > 1.0 ? asin (Complex (x)) : Complex (asin (x));
+}
+
+FloatComplex rc_asin (float x)
+{
+  return fabsf (x) > 1.0f ? asin (FloatComplex (x)) : FloatComplex (asinf (x));
+}
+
+Complex rc_atanh (double x)
+{
+  return fabs (x) > 1.0 ? atanh (Complex (x)) : Complex (atanh (x));
+}
+
+FloatComplex rc_atanh (float x)
+{
+  return fabsf (x) > 1.0f ? atanh (FloatComplex (x)) : FloatComplex (atanhf (x));
+}
+
+Complex rc_log (double x)
+{
+  const double pi = 3.14159265358979323846;
+  return x < 0.0 ? Complex (log (-x), pi) : Complex (log (x));
+}
+
+FloatComplex rc_log (float x)
+{
+  const float pi = 3.14159265358979323846f;
+  return x < 0.0f ? FloatComplex (logf (-x), pi) : FloatComplex (logf (x));
+}
+
+Complex rc_log2 (double x)
+{
+  const double pil2 = 4.53236014182719380962; // = pi / log(2)
+  return x < 0.0 ? Complex (xlog2 (-x), pil2) : Complex (xlog2 (x));
+}
+
+FloatComplex rc_log2 (float x)
+{
+  const float pil2 = 4.53236014182719380962f; // = pi / log(2)
+  return x < 0.0f ? FloatComplex (xlog2 (-x), pil2) : FloatComplex (xlog2 (x));
+}
+
+Complex rc_log10 (double x)
+{
+  const double pil10 = 1.36437635384184134748; // = pi / log(10)
+  return x < 0.0 ? Complex (log10 (-x), pil10) : Complex (log10 (x));
+}
+
+FloatComplex rc_log10 (float x)
+{
+  const float pil10 = 1.36437635384184134748f; // = pi / log(10)
+  return x < 0.0f ? FloatComplex (log10 (-x), pil10) : FloatComplex (log10f (x));
+}
+
+Complex rc_sqrt (double x)
+{
+  return x < 0.0 ? Complex (0.0, sqrt (-x)) : Complex (sqrt (x));
+}
+
+FloatComplex rc_sqrt (float x)
+{
+  return x < 0.0f ? FloatComplex (0.0f, sqrtf (-x)) : FloatComplex (sqrtf (x));
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/lo-mappers.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/lo-mappers.h	Thu Nov 12 15:47:58 2009 +0100
@@ -174,6 +174,25 @@
 extern OCTAVE_API FloatComplex xmin (const FloatComplex& x, const FloatComplex& y);
 extern OCTAVE_API FloatComplex xmax (const FloatComplex& x, const FloatComplex& y);
 
+// These map reals to Complex.
+
+extern OCTAVE_API Complex rc_acos (double);
+extern OCTAVE_API FloatComplex rc_acos (float);
+extern OCTAVE_API Complex rc_acosh (double);
+extern OCTAVE_API FloatComplex rc_acosh (float);
+extern OCTAVE_API Complex rc_asin (double);
+extern OCTAVE_API FloatComplex rc_asin (float);
+extern OCTAVE_API Complex rc_atanh (double);
+extern OCTAVE_API FloatComplex rc_atanh (float);
+extern OCTAVE_API Complex rc_log (double);
+extern OCTAVE_API FloatComplex rc_log (float);
+extern OCTAVE_API Complex rc_log2 (double);
+extern OCTAVE_API FloatComplex rc_log2 (float);
+extern OCTAVE_API Complex rc_log10 (double);
+extern OCTAVE_API FloatComplex rc_log10 (float);
+extern OCTAVE_API Complex rc_sqrt (double);
+extern OCTAVE_API FloatComplex rc_sqrt (float);
+
 #endif
 
 /*
--- a/liboctave/lo-specfun.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/lo-specfun.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -316,10 +316,8 @@
 }
 
 Complex
-xlgamma (const Complex& xc)
+rc_lgamma (double x)
 {
-  // Can only be called with a real value of x.
-  double x = xc.real ();
   double result;
 
 #if defined (HAVE_LGAMMA_R)
@@ -383,10 +381,8 @@
 }
 
 FloatComplex
-xlgamma (const FloatComplex& xc)
+rc_lgamma (float x)
 {
-  // Can only be called with a real value of x.
-  float x = xc.real ();
   float result;
 
 #if defined (HAVE_LGAMMAF_R)
@@ -502,7 +498,7 @@
 #endif
 
 FloatComplex 
-expm1f(const FloatComplex& x)
+expm1(const FloatComplex& x)
 {
   FloatComplex retval;
 
@@ -588,7 +584,7 @@
 #endif
 
 FloatComplex 
-log1pf (const FloatComplex& x)
+log1p (const FloatComplex& x)
 {
   FloatComplex retval;
 
@@ -3092,6 +3088,19 @@
   return retval;
 }
 
+
+Complex rc_log1p (double x)
+{
+  const double pi = 3.14159265358979323846;
+  return x < -1.0 ? Complex (log (-(1.0 + x)), pi) : Complex (log1p (x));
+}
+
+FloatComplex rc_log1p (float x)
+{
+  const float pi = 3.14159265358979323846f;
+  return x < -1.0f ? FloatComplex (logf (-(1.0f + x)), pi) : FloatComplex (log1pf (x));
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/lo-specfun.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/liboctave/lo-specfun.h	Thu Nov 12 15:47:58 2009 +0100
@@ -90,7 +90,7 @@
 #if !defined (HAVE_EXPM1F)
 extern OCTAVE_API float expm1f (float x);
 #endif
-extern OCTAVE_API FloatComplex expm1f (const FloatComplex& x);
+extern OCTAVE_API FloatComplex expm1 (const FloatComplex& x);
 
 #if !defined (HAVE_LOG1P)
 extern OCTAVE_API double log1p (double x);
@@ -100,15 +100,15 @@
 #if !defined (HAVE_LOG1PF)
 extern OCTAVE_API float log1pf (float x);
 #endif
-extern OCTAVE_API FloatComplex log1pf (const FloatComplex& x);
+extern OCTAVE_API FloatComplex log1p (const FloatComplex& x);
 
 extern OCTAVE_API double xgamma (double x);
 extern OCTAVE_API double xlgamma (double x);
-extern OCTAVE_API Complex xlgamma (const Complex& x);
+extern OCTAVE_API Complex rc_lgamma (double x);
 
 extern OCTAVE_API float xgamma (float x);
 extern OCTAVE_API float xlgamma (float x);
-extern OCTAVE_API FloatComplex xlgamma (const FloatComplex& x);
+extern OCTAVE_API FloatComplex rc_lgamma (float x);
 
 extern OCTAVE_API Complex
 besselj (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr);
@@ -580,6 +580,9 @@
   return gammainc (x, a, err);
 }
 
+extern OCTAVE_API Complex rc_log1p (double);
+extern OCTAVE_API FloatComplex rc_log1p (float);
+
 #endif
 
 /*
--- a/src/Cell.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/Cell.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -266,7 +266,7 @@
 }
 
 Cell
-Cell::map (ctype_mapper fcn) const
+Cell::map (unary_mapper_t umap) const
 {
   Cell retval (dims ());
   octave_value *r = retval.fortran_vec ();
@@ -274,7 +274,11 @@
   const octave_value *p = data ();
 
   for (octave_idx_type i = 0; i < numel (); i++)
-    r[i] = ((p++)->*fcn) ();
+    {
+      r[i] = p[i].map (umap);
+      if (error_state)
+        break;
+    }
 
   return retval;
 }
--- a/src/Cell.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/Cell.h	Thu Nov 12 15:47:58 2009 +0100
@@ -104,27 +104,7 @@
 
   Cell diag (octave_idx_type k = 0) 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;
+  Cell map (unary_mapper_t umap) const;
 };
 
 #endif
--- a/src/ChangeLog	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ChangeLog	Thu Nov 12 15:47:58 2009 +0100
@@ -1,3 +1,125 @@
+2009-11-12  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-base.h (unary_mapper_t): New enum.
+	(octave_base_value::map (unary_mapper_t)): New method.
+	(octave_base_value::abs): Remove.
+	(octave_base_value::acos): Remove.
+	(octave_base_value::acosh): Remove.
+	(octave_base_value::angle): Remove.
+	(octave_base_value::arg): Remove.
+	(octave_base_value::asin): Remove.
+	(octave_base_value::asinh): Remove.
+	(octave_base_value::atan): Remove.
+	(octave_base_value::atanh): Remove.
+	(octave_base_value::ceil): Remove.
+	(octave_base_value::conj): Remove.
+	(octave_base_value::cos): Remove.
+	(octave_base_value::cosh): Remove.
+	(octave_base_value::erf): Remove.
+	(octave_base_value::erfc): Remove.
+	(octave_base_value::exp): Remove.
+	(octave_base_value::expm1): Remove.
+	(octave_base_value::finite): Remove.
+	(octave_base_value::fix): Remove.
+	(octave_base_value::floor): Remove.
+	(octave_base_value::gamma): Remove.
+	(octave_base_value::imag): Remove.
+	(octave_base_value::isinf): Remove.
+	(octave_base_value::isna): Remove.
+	(octave_base_value::isnan): Remove.
+	(octave_base_value::lgamma): Remove.
+	(octave_base_value::log): Remove.
+	(octave_base_value::log2): Remove.
+	(octave_base_value::log10): Remove.
+	(octave_base_value::log1p): Remove.
+	(octave_base_value::real): Remove.
+	(octave_base_value::round): Remove.
+	(octave_base_value::roundb): Remove.
+	(octave_base_value::signum): Remove.
+	(octave_base_value::sin): Remove.
+	(octave_base_value::sinh): Remove.
+	(octave_base_value::sqrt): Remove.
+	(octave_base_value::tan): Remove.
+	(octave_base_value::tanh): Remove.
+
+	* ov.h 
+	(octave_value::map (unary_mapper_t)): New method.
+	(octave_value::abs): Remove.
+	(octave_value::acos): Remove.
+	(octave_value::acosh): Remove.
+	(octave_value::angle): Remove.
+	(octave_value::arg): Remove.
+	(octave_value::asin): Remove.
+	(octave_value::asinh): Remove.
+	(octave_value::atan): Remove.
+	(octave_value::atanh): Remove.
+	(octave_value::ceil): Remove.
+	(octave_value::conj): Remove.
+	(octave_value::cos): Remove.
+	(octave_value::cosh): Remove.
+	(octave_value::erf): Remove.
+	(octave_value::erfc): Remove.
+	(octave_value::exp): Remove.
+	(octave_value::expm1): Remove.
+	(octave_value::finite): Remove.
+	(octave_value::fix): Remove.
+	(octave_value::floor): Remove.
+	(octave_value::gamma): Remove.
+	(octave_value::imag): Remove.
+	(octave_value::isinf): Remove.
+	(octave_value::isna): Remove.
+	(octave_value::isnan): Remove.
+	(octave_value::lgamma): Remove.
+	(octave_value::log): Remove.
+	(octave_value::log2): Remove.
+	(octave_value::log10): Remove.
+	(octave_value::log1p): Remove.
+	(octave_value::real): Remove.
+	(octave_value::round): Remove.
+	(octave_value::roundb): Remove.
+	(octave_value::signum): Remove.
+	(octave_value::sin): Remove.
+	(octave_value::sinh): Remove.
+	(octave_value::sqrt): Remove.
+	(octave_value::tan): Remove.
+	(octave_value::tanh): Remove.
+
+	* ov-scalar.h, ov-scalar.cc (octave_scalar): Update.
+	* ov-float.h, ov-float.cc (octave_float): Update.
+
+	* ov-complex.h, ov-complex.cc (octave_complex): Update.
+	* ov-flt-complex.h, ov-flt-complex.cc (octave_float_complex): Update.
+
+	* ov-re-matrix.h ov-re-matrix.cc (octave_matrix): Update.
+	* ov-flt-re-matrix.h ov-flt-re-matrix.cc (octave_float_matrix): Update.
+	* ov-cx-matrix.h ov-cx-matrix.cc (octave_complex_matrix): Update.
+	* ov-flt-cx-matrix.h ov-flt-cx-matrix.cc (octave_float_complex_matrix): Update.
+
+	* ov-re-sparse.h ov-re-sparse.cc (octave_sparse_matrix): Update.
+	* ov-cx-sparse.h ov-cx-sparse.cc (octave_sparse_complex_matrix): Update.
+
+	* ov-re-diag.h ov-re-diag.cc (octave_diag_matrix): Update.
+	* ov-flt-re-diag.h ov-flt-re-diag.cc (octave_float_diag_matrix): Update.
+	* ov-cx-diag.h ov-cx-diag.cc (octave_complex_diag_matrix): Update.
+	* ov-flt-cx-diag.h ov-flt-cx-diag.cc (octave_float_complex_diag_matrix): Update.
+
+	* ov-range.h (octave_range): Update.
+	* ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T): Update.
+	(OCTAVE_VALUE_INT_SCALAR_T): Update.
+
+	* ov-perm.h (octave_perm_matrix): Update.
+	* ov-bool.h (octave_bool): Update.
+	* ov-bool-mat.h (octave_bool_matrix): Update.
+	* ov-ch-mat.h (octave_char_matrix): Update.
+
+	* mappers.cc (Fabs, Facos, Facosh, Fangle, Farg, Fasin, Fasinh,
+	Fatan, Fatanh, Fceil, Fconj, Fcos, Fcosh, Ferf, Ferfc, Fexp, Fexpm1,
+	Ffinite, Ffix, Ffloor, Fgamma, Fimag, Fisinf, Fisna, Fisnan, Flgamma,
+	Flog, Flog2, Flog10, Flog1p, Freal, Fround, Froundb, Fsignum, Fsin,
+	Fsinh, Fsqrt, Ftan, Ftanh, Fisalnum, Fisalpha, Fisascii, Fiscntrl,
+	Fisdigit, Fisgraph, Fislower, Fisprint, Fispunct, Fisspace, Fisupper,
+	Fisxdigit, Ftoascii, Ftolower, Ftoupper): Update.
+
 2009-11-11  John W. Eaton  <jwe@octave.org>
 
 	* load-path.cc (load_path::do_find_all_first_of): Take advantage
--- a/src/DLD-FUNCTIONS/lookup.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/DLD-FUNCTIONS/lookup.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -227,10 +227,10 @@
       // (though it's not too meaningful).
       
       if (table.is_complex_type ())
-        table = table.abs ();
+        table = table.map (umap_abs);
 
       if (y.is_complex_type ())
-        y = y.abs ();
+        y = y.map (umap_abs);
 
       Array<octave_idx_type> idx;
 
--- a/src/data.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/data.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -978,120 +978,6 @@
 %!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	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/mappers.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -35,6 +35,7 @@
 #include "defun.h"
 #include "error.h"
 #include "variables.h"
+#include "gripes.h"
 
 DEFUN (abs, args, ,
     "-*- texinfo -*-\n\
@@ -59,7 +60,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).abs ();
+    retval = args(0).map (umap_abs);
   else
     print_usage ();
 
@@ -94,7 +95,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).acos ();
+    retval = args(0).map (umap_acos);
   else
     print_usage ();
 
@@ -131,7 +132,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).acosh ();
+    retval = args(0).map (umap_acosh);
   else
     print_usage ();
 
@@ -163,7 +164,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).arg ();
+    retval = args(0).map (umap_arg);
   else
     print_usage ();
 
@@ -195,7 +196,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).arg ();
+    retval = args(0).map (umap_arg);
   else
     print_usage ();
 
@@ -230,7 +231,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).asin ();
+    retval = args(0).map (umap_asin);
   else
     print_usage ();
 
@@ -257,7 +258,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).asinh ();
+    retval = args(0).map (umap_asinh);
   else
     print_usage ();
 
@@ -290,7 +291,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).atan ();
+    retval = args(0).map (umap_atan);
   else
     print_usage ();
 
@@ -327,7 +328,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).atanh ();
+    retval = args(0).map (umap_atanh);
   else
     print_usage ();
 
@@ -368,7 +369,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).ceil ();
+    retval = args(0).map (umap_ceil);
   else
     print_usage ();
 
@@ -409,7 +410,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).conj ();
+    retval = args(0).map (umap_conj);
   else
     print_usage ();
 
@@ -444,7 +445,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).cos ();
+    retval = args(0).map (umap_cos);
   else
     print_usage ();
 
@@ -481,7 +482,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).cosh ();
+    retval = args(0).map (umap_cosh);
   else
     print_usage ();
 
@@ -531,7 +532,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).erf ();
+    retval = args(0).map (umap_erf);
   else
     print_usage ();
 
@@ -583,7 +584,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).erfc ();
+    retval = args(0).map (umap_erfc);
   else
     print_usage ();
 
@@ -615,7 +616,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).exp ();
+    retval = args(0).map (umap_exp);
   else
     print_usage ();
 
@@ -653,7 +654,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).expm1 ();
+    retval = args(0).map (umap_expm1);
   else
     print_usage ();
 
@@ -676,7 +677,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).finite ();
+    retval = args(0).map (umap_finite);
   else
     print_usage ();
 
@@ -712,7 +713,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).fix ();
+    retval = args(0).map (umap_fix);
   else
     print_usage ();
 
@@ -748,7 +749,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).floor ();
+    retval = args(0).map (umap_floor);
   else
     print_usage ();
 
@@ -793,7 +794,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).gamma ();
+    retval = args(0).map (umap_gamma);
   else
     print_usage ();
 
@@ -834,7 +835,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).imag ();
+    retval = args(0).map (umap_imag);
   else
     print_usage ();
 
@@ -867,7 +868,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisalnum ();
+    retval = args(0).map (umap_isalnum);
   else
     print_usage ();
 
@@ -884,7 +885,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisalpha ();
+    retval = args(0).map (umap_isalpha);
   else
     print_usage ();
 
@@ -899,7 +900,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisascii ();
+    retval = args(0).map (umap_isascii);
   else
     print_usage ();
 
@@ -914,7 +915,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xiscntrl ();
+    retval = args(0).map (umap_iscntrl);
   else
     print_usage ();
 
@@ -929,7 +930,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisdigit ();
+    retval = args(0).map (umap_isdigit);
   else
     print_usage ();
 
@@ -952,7 +953,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).isinf ();
+    retval = args(0).map (umap_isinf);
   else
     print_usage ();
 
@@ -983,7 +984,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisgraph ();
+    retval = args(0).map (umap_isgraph);
   else
     print_usage ();
 
@@ -998,7 +999,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xislower ();
+    retval = args(0).map (umap_islower);
   else
     print_usage ();
 
@@ -1022,7 +1023,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).isna ();
+    retval = args(0).map (umap_isna);
   else
     print_usage ();
 
@@ -1062,7 +1063,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).isnan ();
+    retval = args(0).map (umap_isnan);
   else
     print_usage ();
 
@@ -1093,7 +1094,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisprint ();
+    retval = args(0).map (umap_isprint);
   else
     print_usage ();
 
@@ -1108,7 +1109,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xispunct ();
+    retval = args(0).map (umap_ispunct);
   else
     print_usage ();
 
@@ -1124,7 +1125,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisspace ();
+    retval = args(0).map (umap_isspace);
   else
     print_usage ();
 
@@ -1139,7 +1140,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisupper ();
+    retval = args(0).map (umap_isupper);
   else
     print_usage ();
 
@@ -1154,7 +1155,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xisxdigit ();
+    retval = args(0).map (umap_isxdigit);
   else
     print_usage ();
 
@@ -1171,7 +1172,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).lgamma ();
+    retval = args(0).map (umap_lgamma);
   else
     print_usage ();
 
@@ -1220,7 +1221,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).log ();
+    retval = args(0).map (umap_log);
   else
     print_usage ();
 
@@ -1240,6 +1241,120 @@
 
  */
 
+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\
@@ -1249,7 +1364,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).log10 ();
+    retval = args(0).map (umap_log10);
   else
     print_usage ();
 
@@ -1282,7 +1397,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).log1p ();
+    retval = args(0).map (umap_log1p);
   else
     print_usage ();
 
@@ -1298,7 +1413,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).real ();
+    retval = args(0).map (umap_real);
   else
     print_usage ();
 
@@ -1338,7 +1453,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).round ();
+    retval = args(0).map (umap_round);
   else
     print_usage ();
 
@@ -1379,7 +1494,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).roundb ();
+    retval = args(0).map (umap_roundb);
   else
     print_usage ();
 
@@ -1411,7 +1526,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).signum ();
+    retval = args(0).map (umap_signum);
   else
     print_usage ();
 
@@ -1444,7 +1559,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).sin ();
+    retval = args(0).map (umap_sin);
   else
     print_usage ();
 
@@ -1481,7 +1596,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).sinh ();
+    retval = args(0).map (umap_sinh);
   else
     print_usage ();
 
@@ -1516,7 +1631,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).sqrt ();
+    retval = args(0).map (umap_sqrt);
   else
     print_usage ();
 
@@ -1549,7 +1664,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).tan ();
+    retval = args(0).map (umap_tan);
   else
     print_usage ();
 
@@ -1586,7 +1701,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).tanh ();
+    retval = args(0).map (umap_tanh);
   else
     print_usage ();
 
@@ -1627,7 +1742,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xtoascii ();
+    retval = args(0).map (umap_toascii);
   else
     print_usage ();
 
@@ -1653,7 +1768,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xtolower ();
+    retval = args(0).map (umap_tolower);
   else
     print_usage ();
 
@@ -1699,7 +1814,7 @@
 {
   octave_value retval;
   if (args.length () == 1)
-    retval = args(0).xtoupper ();
+    retval = args(0).map (umap_toupper);
   else
     print_usage ();
 
--- a/src/ov-base-diag.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-base-diag.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -505,46 +505,3 @@
   return dense_cache;
 }
 
-#define FORWARD_MAPPER(MAP) \
-  template <class DMT, class MT> \
-  octave_value \
-  octave_base_diag<DMT, MT>::MAP (void) const \
-  { \
-    return to_dense ().MAP (); \
-  }
-
-FORWARD_MAPPER (erf)
-FORWARD_MAPPER (erfc)
-FORWARD_MAPPER (gamma)
-FORWARD_MAPPER (lgamma)
-FORWARD_MAPPER (acos)
-FORWARD_MAPPER (acosh)
-FORWARD_MAPPER (angle)
-FORWARD_MAPPER (arg)
-FORWARD_MAPPER (asin)
-FORWARD_MAPPER (asinh)
-FORWARD_MAPPER (atan)
-FORWARD_MAPPER (atanh)
-FORWARD_MAPPER (ceil)
-FORWARD_MAPPER (cos)
-FORWARD_MAPPER (cosh)
-FORWARD_MAPPER (exp)
-FORWARD_MAPPER (expm1)
-FORWARD_MAPPER (fix)
-FORWARD_MAPPER (floor)
-FORWARD_MAPPER (log)
-FORWARD_MAPPER (log2)
-FORWARD_MAPPER (log10)
-FORWARD_MAPPER (log1p)
-FORWARD_MAPPER (round)
-FORWARD_MAPPER (roundb)
-FORWARD_MAPPER (signum)
-FORWARD_MAPPER (sin)
-FORWARD_MAPPER (sinh)
-FORWARD_MAPPER (tan)
-FORWARD_MAPPER (tanh)
-FORWARD_MAPPER (finite)
-FORWARD_MAPPER (isinf)
-FORWARD_MAPPER (isna)
-FORWARD_MAPPER (isnan)
-
--- a/src/ov-base-diag.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-base-diag.h	Thu Nov 12 15:47:58 2009 +0100
@@ -208,42 +208,6 @@
 
   void print_info (std::ostream& os, const std::string& prefix) const;
 
-  // We forward everything except abs, real, imag, conj, sqrt.
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
-
 protected:
 
   DMT matrix;
--- a/src/ov-base.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-base.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -1117,79 +1117,79 @@
   return UNSORTED;
 }
 
-#define UNDEFINED_MAPPER(F) \
-  octave_value \
-  octave_base_value::F (void) const \
-  { \
-    gripe_wrong_type_arg ("octave_base_value::" #F " ()", type_name ()); \
-    return octave_value (); \
-  }
+extern OCTINTERP_API
+const char *get_umap_name (unary_mapper_t umap)
+{
+  static const char *names[num_unary_mappers] = 
+    {
+      "abs",
+      "acos",
+      "acosh",
+      "angle",
+      "arg",
+      "asin",
+      "asinh",
+      "atan",
+      "atanh",
+      "ceil",
+      "conj",
+      "cos",
+      "cosh",
+      "erf",
+      "erfc",
+      "exp",
+      "expm1",
+      "finite",
+      "fix",
+      "floor",
+      "gamma",
+      "imag",
+      "isinf",
+      "isna",
+      "isnan",
+      "lgamma",
+      "log",
+      "log2",
+      "log10",
+      "log1p",
+      "real",
+      "round",
+      "roundb",
+      "signum",
+      "sin",
+      "sinh",
+      "sqrt",
+      "tan",
+      "tanh",
+      "isalnum",
+      "isalpha",
+      "isascii",
+      "iscntrl",
+      "isdigit",
+      "isgraph",
+      "islower",
+      "isprint",
+      "ispunct",
+      "isspace",
+      "isupper",
+      "isxdigit",
+      "toascii",
+      "tolower",
+      "toupper"
+    };
 
-UNDEFINED_MAPPER (abs)
-UNDEFINED_MAPPER (acos)
-UNDEFINED_MAPPER (acosh)
-UNDEFINED_MAPPER (angle)
-UNDEFINED_MAPPER (arg)
-UNDEFINED_MAPPER (asin)
-UNDEFINED_MAPPER (asinh)
-UNDEFINED_MAPPER (atan)
-UNDEFINED_MAPPER (atanh)
-UNDEFINED_MAPPER (ceil)
-UNDEFINED_MAPPER (conj)
-UNDEFINED_MAPPER (cos)
-UNDEFINED_MAPPER (cosh)
-UNDEFINED_MAPPER (erf)
-UNDEFINED_MAPPER (erfc)
-UNDEFINED_MAPPER (exp)
-UNDEFINED_MAPPER (expm1)
-UNDEFINED_MAPPER (finite)
-UNDEFINED_MAPPER (fix)
-UNDEFINED_MAPPER (floor)
-UNDEFINED_MAPPER (gamma)
-UNDEFINED_MAPPER (imag)
-UNDEFINED_MAPPER (isinf)
-UNDEFINED_MAPPER (isna)
-UNDEFINED_MAPPER (isnan)
-UNDEFINED_MAPPER (lgamma)
-UNDEFINED_MAPPER (log)
-UNDEFINED_MAPPER (log2)
-UNDEFINED_MAPPER (log10)
-UNDEFINED_MAPPER (log1p)
-UNDEFINED_MAPPER (real)
-UNDEFINED_MAPPER (round)
-UNDEFINED_MAPPER (roundb)
-UNDEFINED_MAPPER (signum)
-UNDEFINED_MAPPER (sin)
-UNDEFINED_MAPPER (sinh)
-UNDEFINED_MAPPER (sqrt)
-UNDEFINED_MAPPER (tan)
-UNDEFINED_MAPPER (tanh)
+  if (umap < 0 || umap >= num_unary_mappers)
+    return "unknown";
+  else
+    return names[umap];
+}
 
-// String mapper functions, convert to a string
-
-#define STRING_MAPPER(F) \
-  octave_value \
-  octave_base_value::F (void) const \
-  { \
-    octave_value tmp = char_array_value (true); \
-    return error_state ? octave_value () : octave_value (tmp.F ()); \
-  }
-
-STRING_MAPPER (xisalnum)
-STRING_MAPPER (xisalpha)
-STRING_MAPPER (xisascii)
-STRING_MAPPER (xiscntrl)
-STRING_MAPPER (xisdigit)
-STRING_MAPPER (xisgraph)
-STRING_MAPPER (xislower)
-STRING_MAPPER (xisprint)
-STRING_MAPPER (xispunct)
-STRING_MAPPER (xisspace)
-STRING_MAPPER (xisupper)
-STRING_MAPPER (xisxdigit)
-STRING_MAPPER (xtoascii)
-STRING_MAPPER (xtolower)
-STRING_MAPPER (xtoupper)
+octave_value
+octave_base_value::map (unary_mapper_t umap) const
+{
+  error ("%s: not defined for %s", get_umap_name (umap), type_name ().c_str ());
+  return octave_value ();
+}
 
 void
 octave_base_value::lock (void)
--- a/src/ov-base.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-base.h	Thu Nov 12 15:47:58 2009 +0100
@@ -117,6 +117,70 @@
 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.
 
@@ -632,64 +696,7 @@
 
   virtual void dump (std::ostream& os) const;
 
-  virtual octave_value abs (void) const;
-  virtual octave_value acos (void) const;
-  virtual octave_value acosh (void) const;
-  virtual octave_value angle (void) const;
-  virtual octave_value arg (void) const;
-  virtual octave_value asin (void) const;
-  virtual octave_value asinh (void) const;
-  virtual octave_value atan (void) const;
-  virtual octave_value atanh (void) const;
-  virtual octave_value ceil (void) const;
-  virtual octave_value conj (void) const;
-  virtual octave_value cos (void) const;
-  virtual octave_value cosh (void) const;
-  virtual octave_value erf (void) const;
-  virtual octave_value erfc (void) const;
-  virtual octave_value exp (void) const;
-  virtual octave_value expm1 (void) const;
-  virtual octave_value finite (void) const;
-  virtual octave_value fix (void) const;
-  virtual octave_value floor (void) const;
-  virtual octave_value gamma (void) const;
-  virtual octave_value imag (void) const;
-  virtual octave_value isinf (void) const;
-  virtual octave_value isna (void) const;
-  virtual octave_value isnan (void) const;
-  virtual octave_value lgamma (void) const;
-  virtual octave_value log (void) const;
-  virtual octave_value log2 (void) const;
-  virtual octave_value log10 (void) const;
-  virtual octave_value log1p (void) const;
-  virtual octave_value real (void) const;
-  virtual octave_value round (void) const;
-  virtual octave_value roundb (void) const;
-  virtual octave_value signum (void) const;
-  virtual octave_value sin (void) const;
-  virtual octave_value sinh (void) const;
-  virtual octave_value sqrt (void) const;
-  virtual octave_value tan (void) const;
-  virtual octave_value tanh (void) const;
-
-  // These functions are prefixed with X to avoid potential macro
-  // conflicts.
-
-  virtual octave_value xisalnum (void) const;
-  virtual octave_value xisalpha (void) const;
-  virtual octave_value xisascii (void) const;
-  virtual octave_value xiscntrl (void) const;
-  virtual octave_value xisdigit (void) const;
-  virtual octave_value xisgraph (void) const;
-  virtual octave_value xislower (void) const;
-  virtual octave_value xisprint (void) const;
-  virtual octave_value xispunct (void) const;
-  virtual octave_value xisspace (void) const;
-  virtual octave_value xisupper (void) const;
-  virtual octave_value xisxdigit (void) const;
-  virtual octave_value xtoascii (void) const;
-  virtual octave_value xtolower (void) const;
-  virtual octave_value xtoupper (void) const;
+  virtual octave_value map (unary_mapper_t) const;
 
 protected:
 
--- a/src/ov-bool-mat.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-bool-mat.h	Thu Nov 12 15:47:58 2009 +0100
@@ -209,55 +209,12 @@
   mxArray *as_mxArray (void) const;
 
   // Mapper functions are converted to double for treatment
-#define BOOL_MAT_MAPPER(MAP) \
-  octave_value MAP (void) const \
-    { \
-      octave_matrix m (array_value ()); \
-      return m.MAP (); \
+  octave_value map (unary_mapper_t umap) const
+    {
+      octave_matrix m (array_value ());
+      return m.map (umap);
     }
 
-  BOOL_MAT_MAPPER (abs)
-  BOOL_MAT_MAPPER (acos)
-  BOOL_MAT_MAPPER (acosh)
-  BOOL_MAT_MAPPER (angle)
-  BOOL_MAT_MAPPER (arg)
-  BOOL_MAT_MAPPER (asin)
-  BOOL_MAT_MAPPER (asinh)
-  BOOL_MAT_MAPPER (atan)
-  BOOL_MAT_MAPPER (atanh)
-  BOOL_MAT_MAPPER (ceil)
-  BOOL_MAT_MAPPER (conj)
-  BOOL_MAT_MAPPER (cos)
-  BOOL_MAT_MAPPER (cosh)
-  BOOL_MAT_MAPPER (erf)
-  BOOL_MAT_MAPPER (erfc)
-  BOOL_MAT_MAPPER (exp)
-  BOOL_MAT_MAPPER (expm1)
-  BOOL_MAT_MAPPER (finite)
-  BOOL_MAT_MAPPER (fix)
-  BOOL_MAT_MAPPER (floor)
-  BOOL_MAT_MAPPER (gamma)
-  BOOL_MAT_MAPPER (imag)
-  BOOL_MAT_MAPPER (isinf)
-  BOOL_MAT_MAPPER (isna)
-  BOOL_MAT_MAPPER (isnan)
-  BOOL_MAT_MAPPER (lgamma)
-  BOOL_MAT_MAPPER (log)
-  BOOL_MAT_MAPPER (log2)
-  BOOL_MAT_MAPPER (log10)
-  BOOL_MAT_MAPPER (log1p)
-  BOOL_MAT_MAPPER (real)
-  BOOL_MAT_MAPPER (round)
-  BOOL_MAT_MAPPER (roundb)
-  BOOL_MAT_MAPPER (signum)
-  BOOL_MAT_MAPPER (sin)
-  BOOL_MAT_MAPPER (sinh)
-  BOOL_MAT_MAPPER (sqrt)
-  BOOL_MAT_MAPPER (tan)
-  BOOL_MAT_MAPPER (tanh)
-
-#undef BOOL_MAT_MAPPER
-
 protected:
 
   DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-bool-sparse.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-bool-sparse.h	Thu Nov 12 15:47:58 2009 +0100
@@ -140,55 +140,12 @@
   mxArray *as_mxArray (void) const;
 
   // Mapper functions are converted to double for treatment
-#define BOOL_SPARSE_MAPPER(MAP) \
-  octave_value MAP (void) const \
-    { \
-      octave_sparse_matrix m (sparse_matrix_value ()); \
-      return m.MAP (); \
+  octave_value map (unary_mapper_t umap) const
+    {
+      octave_sparse_matrix m (sparse_matrix_value ());
+      return m.map (umap);
     }
 
-  BOOL_SPARSE_MAPPER (abs)
-  BOOL_SPARSE_MAPPER (acos)
-  BOOL_SPARSE_MAPPER (acosh)
-  BOOL_SPARSE_MAPPER (angle)
-  BOOL_SPARSE_MAPPER (arg)
-  BOOL_SPARSE_MAPPER (asin)
-  BOOL_SPARSE_MAPPER (asinh)
-  BOOL_SPARSE_MAPPER (atan)
-  BOOL_SPARSE_MAPPER (atanh)
-  BOOL_SPARSE_MAPPER (ceil)
-  BOOL_SPARSE_MAPPER (conj)
-  BOOL_SPARSE_MAPPER (cos)
-  BOOL_SPARSE_MAPPER (cosh)
-  BOOL_SPARSE_MAPPER (erf)
-  BOOL_SPARSE_MAPPER (erfc)
-  BOOL_SPARSE_MAPPER (exp)
-  BOOL_SPARSE_MAPPER (expm1)
-  BOOL_SPARSE_MAPPER (finite)
-  BOOL_SPARSE_MAPPER (fix)
-  BOOL_SPARSE_MAPPER (floor)
-  BOOL_SPARSE_MAPPER (gamma)
-  BOOL_SPARSE_MAPPER (imag)
-  BOOL_SPARSE_MAPPER (isinf)
-  BOOL_SPARSE_MAPPER (isna)
-  BOOL_SPARSE_MAPPER (isnan)
-  BOOL_SPARSE_MAPPER (lgamma)
-  BOOL_SPARSE_MAPPER (log)
-  BOOL_SPARSE_MAPPER (log2)
-  BOOL_SPARSE_MAPPER (log10)
-  BOOL_SPARSE_MAPPER (log1p)
-  BOOL_SPARSE_MAPPER (real)
-  BOOL_SPARSE_MAPPER (round)
-  BOOL_SPARSE_MAPPER (roundb)
-  BOOL_SPARSE_MAPPER (signum)
-  BOOL_SPARSE_MAPPER (sin)
-  BOOL_SPARSE_MAPPER (sinh)
-  BOOL_SPARSE_MAPPER (sqrt)
-  BOOL_SPARSE_MAPPER (tan)
-  BOOL_SPARSE_MAPPER (tanh)
-
-#undef BOOL_SPARSE_MAPPER
-
 protected:
 
   DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-bool.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-bool.h	Thu Nov 12 15:47:58 2009 +0100
@@ -209,55 +209,12 @@
   mxArray *as_mxArray (void) const;
 
   // Mapper functions are converted to double for treatment
-#define BOOL_MAPPER(MAP) \
-  octave_value MAP (void) const \
-    { \
-      octave_scalar s (static_cast<double> (scalar)); \
-      return s.MAP (); \
+  octave_value map (unary_mapper_t umap) const
+    {
+      octave_scalar m (scalar_value ());
+      return m.map (umap);
     }
 
-  BOOL_MAPPER (abs)
-  BOOL_MAPPER (acos)
-  BOOL_MAPPER (acosh)
-  BOOL_MAPPER (angle)
-  BOOL_MAPPER (arg)
-  BOOL_MAPPER (asin)
-  BOOL_MAPPER (asinh)
-  BOOL_MAPPER (atan)
-  BOOL_MAPPER (atanh)
-  BOOL_MAPPER (ceil)
-  BOOL_MAPPER (conj)
-  BOOL_MAPPER (cos)
-  BOOL_MAPPER (cosh)
-  BOOL_MAPPER (erf)
-  BOOL_MAPPER (erfc)
-  BOOL_MAPPER (exp)
-  BOOL_MAPPER (expm1)
-  BOOL_MAPPER (finite)
-  BOOL_MAPPER (fix)
-  BOOL_MAPPER (floor)
-  BOOL_MAPPER (gamma)
-  BOOL_MAPPER (imag)
-  BOOL_MAPPER (isinf)
-  BOOL_MAPPER (isna)
-  BOOL_MAPPER (isnan)
-  BOOL_MAPPER (lgamma)
-  BOOL_MAPPER (log)
-  BOOL_MAPPER (log2)
-  BOOL_MAPPER (log10)
-  BOOL_MAPPER (log1p)
-  BOOL_MAPPER (real)
-  BOOL_MAPPER (round)
-  BOOL_MAPPER (roundb)
-  BOOL_MAPPER (signum)
-  BOOL_MAPPER (sin)
-  BOOL_MAPPER (sinh)
-  BOOL_MAPPER (sqrt)
-  BOOL_MAPPER (tan)
-  BOOL_MAPPER (tanh)
-
-#undef BOOL_MAPPER
-
 private:
 
   DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-cell.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-cell.h	Thu Nov 12 15:47:58 2009 +0100
@@ -155,21 +155,8 @@
   bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
 #endif
 
-  octave_value xisalnum (void) const { return matrix.xisalnum (); }
-  octave_value xisalpha (void) const { return matrix.xisalpha (); }
-  octave_value xisascii (void) const { return matrix.xisascii (); }
-  octave_value xiscntrl (void) const { return matrix.xiscntrl (); }
-  octave_value xisdigit (void) const { return matrix.xisdigit (); }
-  octave_value xisgraph (void) const { return matrix.xisgraph (); }
-  octave_value xislower (void) const { return matrix.xislower (); }
-  octave_value xisprint (void) const { return matrix.xisprint (); }
-  octave_value xispunct (void) const { return matrix.xispunct (); }
-  octave_value xisspace (void) const { return matrix.xisspace (); }
-  octave_value xisupper (void) const { return matrix.xisupper (); }
-  octave_value xisxdigit (void) const { return matrix.xisxdigit (); }
-  octave_value xtoascii (void) const { return matrix.xtoascii (); }
-  octave_value xtolower (void) const { return matrix.xtolower (); }
-  octave_value xtoupper (void) const { return matrix.xtoupper (); }
+  octave_value map (unary_mapper_t umap) const
+    { return matrix.map (umap); }
 
   mxArray *as_mxArray (void) const;
 
--- a/src/ov-ch-mat.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-ch-mat.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -150,44 +150,50 @@
   return retval;
 }
 
-#define MACRO_WRAPPER(FCN, CTYPE_FCN) \
-  static int x ## FCN (int c) { return CTYPE_FCN (c); }
+// The C++ standard guarantees cctype defines functions, not macros (and hence macros *CAN'T* 
+// be defined if only cctype is included)
+// so there's no need to f*ck around. The exceptions are isascii and toascii,
+// which are not C++.
+// Oddly enough, all those character functions are int (*) (int), even
+// in C++. Wicked!
+static inline int xisascii (int c)
+{ return isascii (c); }
 
-#define STRING_MAPPER(FCN, AMAP, CTYPE_FCN) \
-  MACRO_WRAPPER (FCN, CTYPE_FCN) \
- \
-  octave_value \
-  octave_char_matrix::FCN (void) const \
-  { \
-    static charNDArray::mapper smap = x ## FCN; \
-    return matrix.AMAP (smap);  \
-  }
+static inline int xtoascii (int c)
+{ return toascii (c); }
+
+octave_value
+octave_char_matrix::map (unary_mapper_t umap) const
+{
+  switch (umap)
+    {
+#define STRING_MAPPER(UMAP,FCN,TYPE) \
+    case UMAP: \
+      return octave_value (matrix.map<TYPE, int (&) (int)> (FCN))
 
-#define TOSTRING_MAPPER(FCN, AMAP, CTYPE_FCN) \
-  MACRO_WRAPPER (FCN, CTYPE_FCN) \
- \
-  octave_value \
-  octave_char_matrix::FCN (void) const \
-  { \
-    static charNDArray::mapper smap = x ## FCN; \
-    return octave_value (matrix.AMAP (smap), is_sq_string () ? '\'' : '"'); \
-  }
+    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, bmap, isalnum)
-STRING_MAPPER (xisalpha, bmap, isalpha)
-STRING_MAPPER (xisascii, bmap, isascii)
-STRING_MAPPER (xiscntrl, bmap, iscntrl)
-STRING_MAPPER (xisdigit, bmap, isdigit)
-STRING_MAPPER (xisgraph, bmap, isgraph)
-STRING_MAPPER (xislower, bmap, islower)
-STRING_MAPPER (xisprint, bmap, isprint)
-STRING_MAPPER (xispunct, bmap, ispunct)
-STRING_MAPPER (xisspace, bmap, isspace)
-STRING_MAPPER (xisupper, bmap, isupper)
-STRING_MAPPER (xisxdigit, bmap, isxdigit)
-STRING_MAPPER (xtoascii, dmap, toascii)
-TOSTRING_MAPPER (xtolower, smap, tolower)
-TOSTRING_MAPPER (xtoupper, smap, toupper)
+    default: 
+      {
+        octave_matrix m (array_value (true));
+        return m.map (umap);
+      }
+    }
+}
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-ch-mat.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-ch-mat.h	Thu Nov 12 15:47:58 2009 +0100
@@ -143,56 +143,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value xisalnum (void) const;
-  octave_value xisalpha (void) const;
-  octave_value xisascii (void) const;
-  octave_value xiscntrl (void) const;
-  octave_value xisdigit (void) const;
-  octave_value xisgraph (void) const;
-  octave_value xislower (void) const;
-  octave_value xisprint (void) const;
-  octave_value xispunct (void) const;
-  octave_value xisspace (void) const;
-  octave_value xisupper (void) const;
-  octave_value xisxdigit (void) const;
-  octave_value xtoascii (void) const;
-  octave_value xtolower (void) const;
-  octave_value xtoupper (void) const;
-
-#define MAT_MAPPER(MAP) \
-  octave_value MAP (void) const \
-    { \
-      octave_matrix m (array_value (true)); \
-      return m.MAP (); \
-    }
-
-  MAT_MAPPER (abs)
-  MAT_MAPPER (angle)
-  MAT_MAPPER (arg)
-  MAT_MAPPER (ceil)
-  MAT_MAPPER (conj)
-  MAT_MAPPER (fix)
-  MAT_MAPPER (floor)
-  MAT_MAPPER (imag)
-  MAT_MAPPER (real)
-  MAT_MAPPER (round)
-  MAT_MAPPER (signum)
-
-#undef MAT_MAPPER
-
-#define BOOL_MAT_MAPPER(MAP, VAL)	\
-  octave_value MAP (void) const \
-    { \
-      return boolNDArray (matrix.dims (), VAL); \
-    }
-
-  BOOL_MAT_MAPPER (finite, true)
-  BOOL_MAT_MAPPER (isinf, false)
-  BOOL_MAT_MAPPER (isna, false)
-  BOOL_MAT_MAPPER (isnan, false)
-
-#undef BOOL_MAT_MAPPER
-
+  octave_value map (unary_mapper_t umap) const;
 };
 
 #endif
--- a/src/ov-complex.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-complex.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -400,102 +400,55 @@
   return retval;
 }
 
-static double
-xabs (const Complex& x)
-{
-  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
-}
-
-static double
-ximag (const Complex& x)
-{
-  return x.imag ();
-}
-
-static double
-xreal (const Complex& x)
+octave_value
+octave_complex::map (unary_mapper_t umap) const
 {
-  return x.real ();
-}
-
-#define COMPLEX_MAPPER(MAP, FCN)	\
-  octave_value \
-  octave_complex::MAP (void) const \
-  { \
-    return octave_value (FCN (scalar)); \
-  }
-
-#define SCALAR_MAPPER(MAP, FCN)	\
-  octave_value \
-  octave_complex::MAP (void) const \
-  { \
-    if (scalar.imag () == 0) \
-      return octave_value (FCN (scalar.real ())); \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
+  switch (umap)
+    {
+#define SCALAR_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (FCN (scalar))
 
-#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_complex::MAP (void) const \
-  { \
-    if (scalar.imag () == 0) \
-      { \
-	double re = scalar.real (); \
-	return (re < L1 || re > L2 \
-            ? octave_value (CFCN (scalar)) \
-	    : octave_value (RFCN (re))); \
-      } \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
-
-SCALAR_MAPPER (erf, ::erf)
-SCALAR_MAPPER (erfc, ::erfc)
-SCALAR_MAPPER (gamma, xgamma)
-CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+      SCALAR_MAPPER (abs, std::abs);
+      SCALAR_MAPPER (acos, ::acos);
+      SCALAR_MAPPER (acosh, ::acosh);
+      SCALAR_MAPPER (angle, std::arg);
+      SCALAR_MAPPER (arg, std::arg);
+      SCALAR_MAPPER (asin, ::asin);
+      SCALAR_MAPPER (asinh, ::asinh);
+      SCALAR_MAPPER (atan, ::atan);
+      SCALAR_MAPPER (atanh, ::atanh);
+      SCALAR_MAPPER (ceil, ::ceil);
+      SCALAR_MAPPER (conj, std::conj);
+      SCALAR_MAPPER (cos, std::cos);
+      SCALAR_MAPPER (cosh, std::cosh);
+      SCALAR_MAPPER (exp, std::exp);
+      SCALAR_MAPPER (expm1, ::expm1);
+      SCALAR_MAPPER (fix, ::fix);
+      SCALAR_MAPPER (floor, ::floor);
+      SCALAR_MAPPER (imag, std::imag);
+      SCALAR_MAPPER (log, std::log);
+      SCALAR_MAPPER (log2, xlog2);
+      SCALAR_MAPPER (log10, std::log10);
+      SCALAR_MAPPER (log1p, ::log1p);
+      SCALAR_MAPPER (real, std::real);
+      SCALAR_MAPPER (round, xround);
+      SCALAR_MAPPER (roundb, xroundb);
+      SCALAR_MAPPER (signum, ::signum);
+      SCALAR_MAPPER (sin, std::sin);
+      SCALAR_MAPPER (sinh, std::sinh);
+      SCALAR_MAPPER (sqrt, std::sqrt);
+      SCALAR_MAPPER (tan, std::tan);
+      SCALAR_MAPPER (tanh, std::tanh);
+      SCALAR_MAPPER (finite, xfinite);
+      SCALAR_MAPPER (isinf, xisinf);
+      SCALAR_MAPPER (isna, octave_is_NA);
+      SCALAR_MAPPER (isnan, xisnan);
 
-COMPLEX_MAPPER (abs, xabs)
-COMPLEX_MAPPER (acos, ::acos)
-COMPLEX_MAPPER (acosh, ::acosh)
-COMPLEX_MAPPER (angle, std::arg)
-COMPLEX_MAPPER (arg, std::arg)
-COMPLEX_MAPPER (asin, ::asin)
-COMPLEX_MAPPER (asinh, ::asinh)
-COMPLEX_MAPPER (atan, ::atan)
-COMPLEX_MAPPER (atanh, ::atanh)
-COMPLEX_MAPPER (ceil, ::ceil)
-COMPLEX_MAPPER (conj, std::conj)
-COMPLEX_MAPPER (cos, std::cos)
-COMPLEX_MAPPER (cosh, std::cosh)
-COMPLEX_MAPPER (exp, std::exp)
-COMPLEX_MAPPER (expm1, ::expm1)
-COMPLEX_MAPPER (fix, ::fix)
-COMPLEX_MAPPER (floor, ::floor)
-COMPLEX_MAPPER (imag, ximag)
-COMPLEX_MAPPER (log, std::log)
-COMPLEX_MAPPER (log2, xlog2)
-COMPLEX_MAPPER (log10, std::log10)
-COMPLEX_MAPPER (log1p, ::log1p)
-COMPLEX_MAPPER (real, xreal)
-COMPLEX_MAPPER (round, xround)
-COMPLEX_MAPPER (roundb, xroundb)
-COMPLEX_MAPPER (signum, ::signum)
-COMPLEX_MAPPER (sin, std::sin)
-COMPLEX_MAPPER (sinh, std::sinh)
-COMPLEX_MAPPER (sqrt, std::sqrt)
-COMPLEX_MAPPER (tan, std::tan)
-COMPLEX_MAPPER (tanh, std::tanh)
-COMPLEX_MAPPER (finite, xfinite)
-COMPLEX_MAPPER (isinf, xisinf)
-COMPLEX_MAPPER (isna, octave_is_NA)
-COMPLEX_MAPPER (isnan, xisnan)
+    default:
+      return octave_base_value::map (umap);
+    }
+}
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-complex.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-complex.h	Thu Nov 12 15:47:58 2009 +0100
@@ -165,45 +165,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-cx-diag.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-cx-diag.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -136,42 +136,28 @@
 }
 
 octave_value
-octave_complex_diag_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_complex_diag_matrix::real (void) const
-{
-  return ::real (matrix);
-}
-
-octave_value
-octave_complex_diag_matrix::conj (void) const
+octave_complex_diag_matrix::map (unary_mapper_t umap) const
 {
-  return ::conj (matrix);
-}
-
-octave_value
-octave_complex_diag_matrix::imag (void) const
-{
-  return ::imag (matrix);
-}
-
-octave_value
-octave_complex_diag_matrix::sqrt (void) const
-{    
-  octave_value retval;
-
-  static ComplexNDArray::cmapper csqrt = std::sqrt;
-
-  ComplexColumnVector dvec = matrix.diag ();
-  retval = ComplexDiagMatrix (dvec.map (csqrt));
-
-  retval.resize (dims ());
-
-  return retval;
+  switch (umap)
+    {
+    case umap_abs:
+      return matrix.abs ();
+    case umap_real:
+      return ::real (matrix);
+    case umap_conj:
+      return ::conj (matrix);
+    case umap_imag:
+      return ::imag (matrix);
+    case umap_sqrt:
+      {
+        ComplexColumnVector tmp = matrix.diag ().map<Complex> (std::sqrt);
+        ComplexDiagMatrix retval (tmp);
+        retval.resize (matrix.rows (), matrix.columns ());
+        return retval;
+      }
+    default:
+      return to_dense ().map (umap);
+    }
 }
 
 bool 
--- a/src/ov-cx-diag.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-cx-diag.h	Thu Nov 12 15:47:58 2009 +0100
@@ -80,11 +80,7 @@
   bool load_binary (std::istream& is, bool swap, 
 		    oct_mach_info::float_format fmt);
 
-  octave_value abs (void) const;
-  octave_value conj (void) const;
-  octave_value imag (void) const;
-  octave_value real (void) const;
-  octave_value sqrt (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-cx-mat.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-cx-mat.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -719,190 +719,66 @@
   return retval;
 }
 
-#if 0
-static double
-xabs (const Complex& x)
-{
-  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
-}
-#endif
-
-static double
-ximag (const Complex& x)
-{
-  return x.imag ();
-}
-
-static double
-xreal (const Complex& x)
-{
-  return x.real ();
-}
-
-static bool
-any_element_less_than (const NDArray& a, double val)
-{
-  octave_idx_type len = a.length ();
-  const double *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (m[i] < val)
-	return true;
-    }
-
-  return false;
-}
-
-static bool
-any_element_greater_than (const NDArray& a, double val)
+octave_value
+octave_complex_matrix::map (unary_mapper_t umap) const
 {
-  octave_idx_type len = a.length ();
-  const double *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
+  switch (umap)
     {
-      OCTAVE_QUIT;
-
-      if (m[i] > val)
-	return true;
-    }
-
-  return false;
-}
+    // Mappers handled specially.
+    case umap_real:
+      return ::real (matrix);
+    case umap_imag:
+      return ::imag (matrix);
+    case umap_conj:
+      return ::conj (matrix);
 
-#define ARRAY_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_complex_matrix::MAP (void) const \
-  { \
-    static AMAP cmap = FCN; \
-    return matrix.map (cmap); \
-  }
+#define ARRAY_METHOD_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.FCN ())
 
-#define DARRAY_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_complex_matrix::MAP (void) const \
-  { \
-    static ComplexNDArray::dmapper dmap = ximag; \
-    NDArray m = matrix.map (dmap); \
-    if (m.all_elements_are_zero ()) \
-      { \
-	dmap = xreal; \
-	m = matrix.map (dmap); \
-        static AMAP cmap = FCN; \
-        return m.map (cmap); \
-      } \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
+      ARRAY_METHOD_MAPPER (abs, abs);
+      ARRAY_METHOD_MAPPER (isnan, isnan);
+      ARRAY_METHOD_MAPPER (isinf, isinf);
+      ARRAY_METHOD_MAPPER (finite, isfinite);
+
+#define ARRAY_MAPPER(UMAP, TYPE, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.map<TYPE> (FCN))
 
-#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_complex_matrix::MAP (void) const \
-  { \
-    static ComplexNDArray::dmapper idmap = ximag; \
-    NDArray m = matrix.map (idmap); \
-    if (m.all_elements_are_zero ()) \
-      { \
-	static ComplexNDArray::dmapper rdmap = xreal; \
-	m = matrix.map (rdmap); \
-        static NDArray::dmapper dmap = RFCN; \
-        static NDArray::cmapper cmap = CFCN; \
-        return (any_element_less_than (m, L1) \
-                ? octave_value (m.map (cmap)) \
-	        : (any_element_greater_than (m, L2) \
-	           ? octave_value (m.map (cmap)) \
-	           : octave_value (m.map (dmap)))); \
-      } \
-    else \
-      { \
-        /*error ("%s: not defined for complex arguments", #MAP); */	\
-        return octave_value (m); \
-      } \
-  }
-
-// The fast mappers.
-octave_value
-octave_complex_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_complex_matrix::real (void) const
-{
-  return ::real (matrix);
-}
-
-octave_value
-octave_complex_matrix::conj (void) const
-{
-  return ::conj (matrix);
-}
-
-octave_value
-octave_complex_matrix::imag (void) const
-{
-  return ::imag (matrix);
-}
+      ARRAY_MAPPER (acos, Complex, ::acos);
+      ARRAY_MAPPER (acosh, Complex, ::acosh);
+      ARRAY_MAPPER (angle, double, std::arg);
+      ARRAY_MAPPER (arg, double, std::arg);
+      ARRAY_MAPPER (asin, Complex, ::asin);
+      ARRAY_MAPPER (asinh, Complex, ::asinh);
+      ARRAY_MAPPER (atan, Complex, ::atan);
+      ARRAY_MAPPER (atanh, Complex, ::atanh);
+      ARRAY_MAPPER (ceil, Complex, ::ceil);
+      ARRAY_MAPPER (cos, Complex, std::cos);
+      ARRAY_MAPPER (cosh, Complex, std::cosh);
+      ARRAY_MAPPER (exp, Complex, std::exp);
+      ARRAY_MAPPER (expm1, Complex, ::expm1);
+      ARRAY_MAPPER (fix, Complex, ::fix);
+      ARRAY_MAPPER (floor, Complex, ::floor);
+      ARRAY_MAPPER (log, Complex, std::log);
+      ARRAY_MAPPER (log2, Complex, xlog2);
+      ARRAY_MAPPER (log10, Complex, std::log10);
+      ARRAY_MAPPER (log1p, Complex, ::log1p);
+      ARRAY_MAPPER (round, Complex, xround);
+      ARRAY_MAPPER (roundb, Complex, xroundb);
+      ARRAY_MAPPER (signum, Complex, ::signum);
+      ARRAY_MAPPER (sin, Complex, std::sin);
+      ARRAY_MAPPER (sinh, Complex, std::sinh);
+      ARRAY_MAPPER (sqrt, Complex, std::sqrt);
+      ARRAY_MAPPER (tan, Complex, std::tan);
+      ARRAY_MAPPER (tanh, Complex, std::tanh);
+      ARRAY_MAPPER (isna, bool, octave_is_NA);
 
-octave_value
-octave_complex_matrix::isnan (void) const
-{
-  return matrix.isnan ();
-}
-
-octave_value
-octave_complex_matrix::isinf (void) const
-{
-  return matrix.isinf ();
-}
-
-octave_value
-octave_complex_matrix::finite (void) const
-{
-  return matrix.isfinite ();
+    default:
+      return octave_base_value::map (umap);
+    }
 }
 
-DARRAY_MAPPER (erf, NDArray::dmapper, ::erf)
-DARRAY_MAPPER (erfc, NDArray::dmapper, ::erfc)
-DARRAY_MAPPER (gamma, NDArray::dmapper, xgamma)
-CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
-
-ARRAY_MAPPER (acos, ComplexNDArray::cmapper, ::acos)
-ARRAY_MAPPER (acosh, ComplexNDArray::cmapper, ::acosh)
-ARRAY_MAPPER (angle, ComplexNDArray::dmapper, std::arg)
-ARRAY_MAPPER (arg, ComplexNDArray::dmapper, std::arg)
-ARRAY_MAPPER (asin, ComplexNDArray::cmapper, ::asin)
-ARRAY_MAPPER (asinh, ComplexNDArray::cmapper, ::asinh)
-ARRAY_MAPPER (atan, ComplexNDArray::cmapper, ::atan)
-ARRAY_MAPPER (atanh, ComplexNDArray::cmapper, ::atanh)
-ARRAY_MAPPER (ceil, ComplexNDArray::cmapper, ::ceil)
-ARRAY_MAPPER (cos, ComplexNDArray::cmapper, std::cos)
-ARRAY_MAPPER (cosh, ComplexNDArray::cmapper, std::cosh)
-ARRAY_MAPPER (exp, ComplexNDArray::cmapper, std::exp)
-ARRAY_MAPPER (expm1, ComplexNDArray::cmapper, ::expm1)
-ARRAY_MAPPER (fix, ComplexNDArray::cmapper, ::fix)
-ARRAY_MAPPER (floor, ComplexNDArray::cmapper, ::floor)
-ARRAY_MAPPER (log, ComplexNDArray::cmapper, std::log)
-ARRAY_MAPPER (log2, ComplexNDArray::cmapper, xlog2)
-ARRAY_MAPPER (log10, ComplexNDArray::cmapper, std::log10)
-ARRAY_MAPPER (log1p, ComplexNDArray::cmapper, ::log1p)
-ARRAY_MAPPER (round, ComplexNDArray::cmapper, xround)
-ARRAY_MAPPER (roundb, ComplexNDArray::cmapper, xroundb)
-ARRAY_MAPPER (signum, ComplexNDArray::cmapper, ::signum)
-ARRAY_MAPPER (sin, ComplexNDArray::cmapper, std::sin)
-ARRAY_MAPPER (sinh, ComplexNDArray::cmapper, std::sinh)
-ARRAY_MAPPER (sqrt, ComplexNDArray::cmapper, std::sqrt)
-ARRAY_MAPPER (tan, ComplexNDArray::cmapper, std::tan)
-ARRAY_MAPPER (tanh, ComplexNDArray::cmapper, std::tanh)
-ARRAY_MAPPER (isna, ComplexNDArray::bmapper, octave_is_NA)
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/ov-cx-mat.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-cx-mat.h	Thu Nov 12 15:47:58 2009 +0100
@@ -168,45 +168,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-cx-sparse.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-cx-sparse.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -821,155 +821,64 @@
   return retval;
 }
 
-static double
-xabs (const Complex& x)
-{
-  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
-}
-
-static double
-ximag (const Complex& x)
-{
-  return x.imag ();
-}
-
-static double
-xreal (const Complex& x)
+octave_value
+octave_sparse_complex_matrix::map (unary_mapper_t umap) const
 {
-  return x.real ();
-}
-
-static bool
-any_element_less_than (const SparseMatrix& a, double val)
-{
-  octave_idx_type len = a.nnz ();
-
-  if (val > 0. && len != a.numel ())
-    return true;
-
-  for (octave_idx_type i = 0; i < len; i++)
+  switch (umap)
     {
-      OCTAVE_QUIT;
+    // Mappers handled specially.
+    case umap_real:
+      return ::real (matrix);
+    case umap_imag:
+      return ::imag (matrix);
 
-      if (a.data(i) < val)
-	return true;
-    }
-
-  return false;
-}
-
-static bool
-any_element_greater_than (const SparseMatrix& a, double val)
-{
-  octave_idx_type len = a.nnz ();
-
-  if (val < 0. && len != a.numel ())
-    return true;
+#define ARRAY_METHOD_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.FCN ())
 
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (a.data(i) > val)
-	return true;
-    }
+      ARRAY_METHOD_MAPPER (abs, abs);
 
-  return false;
-}
-
-#define SPARSE_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_sparse_complex_matrix::MAP (void) const \
-  { \
-    static AMAP cmap = FCN; \
-    return matrix.map (cmap); \
-  }
+#define ARRAY_MAPPER(UMAP, TYPE, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.map<TYPE> (FCN))
 
-#define DSPARSE_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_sparse_complex_matrix::MAP (void) const \
-  { \
-    static SparseComplexMatrix::dmapper dmap = ximag; \
-    SparseMatrix m = matrix.map (dmap); \
-    if (m.all_elements_are_zero ()) \
-      { \
-	dmap = xreal; \
-	m = matrix.map (dmap); \
-        static AMAP cmap = FCN; \
-        return m.map (cmap); \
-      } \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
+      ARRAY_MAPPER (acos, Complex, ::acos);
+      ARRAY_MAPPER (acosh, Complex, ::acosh);
+      ARRAY_MAPPER (angle, double, std::arg);
+      ARRAY_MAPPER (arg, double, std::arg);
+      ARRAY_MAPPER (asin, Complex, ::asin);
+      ARRAY_MAPPER (asinh, Complex, ::asinh);
+      ARRAY_MAPPER (atan, Complex, ::atan);
+      ARRAY_MAPPER (atanh, Complex, ::atanh);
+      ARRAY_MAPPER (ceil, Complex, ::ceil);
+      ARRAY_MAPPER (conj, Complex, std::conj);
+      ARRAY_MAPPER (cos, Complex, std::cos);
+      ARRAY_MAPPER (cosh, Complex, std::cosh);
+      ARRAY_MAPPER (exp, Complex, std::exp);
+      ARRAY_MAPPER (expm1, Complex, ::expm1);
+      ARRAY_MAPPER (fix, Complex, ::fix);
+      ARRAY_MAPPER (floor, Complex, ::floor);
+      ARRAY_MAPPER (log, Complex, std::log);
+      ARRAY_MAPPER (log2, Complex, xlog2);
+      ARRAY_MAPPER (log10, Complex, std::log10);
+      ARRAY_MAPPER (log1p, Complex, ::log1p);
+      ARRAY_MAPPER (round, Complex, xround);
+      ARRAY_MAPPER (roundb, Complex, xroundb);
+      ARRAY_MAPPER (signum, Complex, ::signum);
+      ARRAY_MAPPER (sin, Complex, std::sin);
+      ARRAY_MAPPER (sinh, Complex, std::sinh);
+      ARRAY_MAPPER (sqrt, Complex, std::sqrt);
+      ARRAY_MAPPER (tan, Complex, std::tan);
+      ARRAY_MAPPER (tanh, Complex, std::tanh);
+      ARRAY_MAPPER (isnan, bool, xisnan);
+      ARRAY_MAPPER (isna, bool, octave_is_NA);
+      ARRAY_MAPPER (isinf, bool, xisinf);
+      ARRAY_MAPPER (finite, bool, xfinite);
 
-#define CD_SPARSE_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_sparse_complex_matrix::MAP (void) const \
-  { \
-    static SparseComplexMatrix::dmapper idmap = ximag; \
-    SparseMatrix m = matrix.map (idmap); \
-    if (m.all_elements_are_zero ()) \
-      { \
-        static SparseComplexMatrix::dmapper rdmap = xreal; \
-	m = matrix.map (rdmap); \
-        static SparseMatrix::dmapper dmap = RFCN; \
-        static SparseMatrix::cmapper cmap = CFCN; \
-        return (any_element_less_than (m, L1) \
-                ? octave_value (m.map (cmap)) \
-	        : (any_element_greater_than (m, L2) \
-	           ? octave_value (m.map (cmap)) \
-	           : octave_value (m.map (dmap)))); \
-      } \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
-
-DSPARSE_MAPPER (erf, SparseMatrix::dmapper, ::erf)
-DSPARSE_MAPPER (erfc, SparseMatrix::dmapper, ::erfc)
-DSPARSE_MAPPER (gamma, SparseMatrix::dmapper, xgamma)
-CD_SPARSE_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
-
-SPARSE_MAPPER (abs, SparseComplexMatrix::dmapper, xabs)
-SPARSE_MAPPER (acos, SparseComplexMatrix::cmapper, ::acos)
-SPARSE_MAPPER (acosh, SparseComplexMatrix::cmapper, ::acosh)
-SPARSE_MAPPER (angle, SparseComplexMatrix::dmapper, std::arg)
-SPARSE_MAPPER (arg, SparseComplexMatrix::dmapper, std::arg)
-SPARSE_MAPPER (asin, SparseComplexMatrix::cmapper, ::asin)
-SPARSE_MAPPER (asinh, SparseComplexMatrix::cmapper, ::asinh)
-SPARSE_MAPPER (atan, SparseComplexMatrix::cmapper, ::atan)
-SPARSE_MAPPER (atanh, SparseComplexMatrix::cmapper, ::atanh)
-SPARSE_MAPPER (ceil, SparseComplexMatrix::cmapper, ::ceil)
-SPARSE_MAPPER (conj, SparseComplexMatrix::cmapper, std::conj)
-SPARSE_MAPPER (cos, SparseComplexMatrix::cmapper, std::cos)
-SPARSE_MAPPER (cosh, SparseComplexMatrix::cmapper, std::cosh)
-SPARSE_MAPPER (exp, SparseComplexMatrix::cmapper, std::exp)
-SPARSE_MAPPER (expm1, SparseComplexMatrix::cmapper, ::expm1)
-SPARSE_MAPPER (fix, SparseComplexMatrix::cmapper, ::fix)
-SPARSE_MAPPER (floor, SparseComplexMatrix::cmapper, ::floor)
-SPARSE_MAPPER (imag, SparseComplexMatrix::dmapper, ximag)
-SPARSE_MAPPER (log, SparseComplexMatrix::cmapper, std::log)
-SPARSE_MAPPER (log2, SparseComplexMatrix::cmapper, xlog2)
-SPARSE_MAPPER (log10, SparseComplexMatrix::cmapper, std::log10)
-SPARSE_MAPPER (log1p, SparseComplexMatrix::cmapper, ::log1p)
-SPARSE_MAPPER (real, SparseComplexMatrix::dmapper, xreal)
-SPARSE_MAPPER (round, SparseComplexMatrix::cmapper, xround)
-SPARSE_MAPPER (roundb, SparseComplexMatrix::cmapper, xroundb)
-SPARSE_MAPPER (signum, SparseComplexMatrix::cmapper, ::signum)
-SPARSE_MAPPER (sin, SparseComplexMatrix::cmapper, std::sin)
-SPARSE_MAPPER (sinh, SparseComplexMatrix::cmapper, std::sinh)
-SPARSE_MAPPER (sqrt, SparseComplexMatrix::cmapper, std::sqrt)
-SPARSE_MAPPER (tan, SparseComplexMatrix::cmapper, std::tan)
-SPARSE_MAPPER (tanh, SparseComplexMatrix::cmapper, std::tanh)
-SPARSE_MAPPER (finite, SparseComplexMatrix::bmapper, xfinite)
-SPARSE_MAPPER (isinf, SparseComplexMatrix::bmapper, xisinf)
-SPARSE_MAPPER (isna, SparseComplexMatrix::bmapper, octave_is_NA)
-SPARSE_MAPPER (isnan, SparseComplexMatrix::bmapper, xisnan)
+    default: // Attempt to go via dense matrix.
+      return full_value ().map (umap).sparse_matrix_value ();
+    }
+}
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-cx-sparse.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-cx-sparse.h	Thu Nov 12 15:47:58 2009 +0100
@@ -151,45 +151,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-float.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-float.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -252,67 +252,63 @@
   return retval;
 }
 
-#define SCALAR_MAPPER(MAP, FCN) \
-  octave_value \
-  octave_float_scalar::MAP (void) const \
-  { \
-    return octave_value (FCN (scalar)); \
-  }
+octave_value
+octave_float_scalar::map (unary_mapper_t umap) const
+{
+  switch (umap)
+    {
+    case umap_imag:
+      return 0.0f;
 
-#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_float_scalar::MAP (void) const \
-  { \
-    return (scalar < L1 || scalar > L2 \
-            ? octave_value (CFCN (FloatComplex (scalar))) \
-	    : octave_value (RFCN (scalar))); \
-  }
+    case umap_real:
+    case umap_conj:
+      return scalar;
 
-static float
-xconj (float x)
-{
-  return x;
-}
+#define SCALAR_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (FCN (scalar))
 
-SCALAR_MAPPER (erf, ::erff)
-SCALAR_MAPPER (erfc, ::erfcf)
-SCALAR_MAPPER (gamma, xgamma)
-CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Float_Inf)
-SCALAR_MAPPER (abs, ::fabsf)
-CD_SCALAR_MAPPER (acos, ::acosf, ::acos, -1.0, 1.0)
-CD_SCALAR_MAPPER (acosh, ::acoshf, ::acosh, 1.0, octave_Float_Inf)
-SCALAR_MAPPER (angle, ::arg)
-SCALAR_MAPPER (arg, ::arg)
-CD_SCALAR_MAPPER (asin, ::asinf, ::asin, -1.0, 1.0)
-SCALAR_MAPPER (asinh, ::asinhf)
-SCALAR_MAPPER (atan, ::atanf)
-CD_SCALAR_MAPPER (atanh, ::atanhf, ::atanh, -1.0, 1.0)
-SCALAR_MAPPER (ceil, ::ceilf)
-SCALAR_MAPPER (conj, xconj)
-SCALAR_MAPPER (cos, ::cosf)
-SCALAR_MAPPER (cosh, ::coshf)
-SCALAR_MAPPER (exp, ::expf)
-SCALAR_MAPPER (expm1, ::expm1f)
-SCALAR_MAPPER (fix, ::fix)
-SCALAR_MAPPER (floor, ::floorf)
-SCALAR_MAPPER (imag, ::imag)
-CD_SCALAR_MAPPER (log, ::logf, std::log, 0.0, octave_Float_Inf)
-CD_SCALAR_MAPPER (log2, xlog2, xlog2, 0.0, octave_Float_Inf)
-CD_SCALAR_MAPPER (log10, ::log10f, std::log10, 0.0, octave_Float_Inf)
-CD_SCALAR_MAPPER (log1p, ::log1pf, ::log1p, -1.0, octave_Float_Inf)
-SCALAR_MAPPER (real, ::real)
-SCALAR_MAPPER (round, xround)
-SCALAR_MAPPER (roundb, xroundb)
-SCALAR_MAPPER (signum, ::signum)
-SCALAR_MAPPER (sin, ::sinf)
-SCALAR_MAPPER (sinh, ::sinhf)
-CD_SCALAR_MAPPER (sqrt, ::sqrtf, std::sqrt, 0.0, octave_Float_Inf)
-SCALAR_MAPPER (tan, ::tanf)
-SCALAR_MAPPER (tanh, ::tanhf)
-SCALAR_MAPPER (finite, xfinite)
-SCALAR_MAPPER (isinf, xisinf)
-SCALAR_MAPPER (isna, octave_is_NA)
-SCALAR_MAPPER (isnan, xisnan)
+      SCALAR_MAPPER (abs, ::fabsf);
+      SCALAR_MAPPER (acos, rc_acos);
+      SCALAR_MAPPER (acosh, rc_acosh);
+      SCALAR_MAPPER (angle, ::arg);
+      SCALAR_MAPPER (arg, ::arg);
+      SCALAR_MAPPER (asin, rc_asin);
+      SCALAR_MAPPER (asinh, ::asinhf);
+      SCALAR_MAPPER (atan, ::atanf);
+      SCALAR_MAPPER (atanh, rc_atanh);
+      SCALAR_MAPPER (erf, ::erff);
+      SCALAR_MAPPER (erfc, ::erfcf);
+      SCALAR_MAPPER (gamma, xgamma);
+      SCALAR_MAPPER (lgamma, rc_lgamma);
+      SCALAR_MAPPER (ceil, ::ceilf);
+      SCALAR_MAPPER (cos, ::cosf);
+      SCALAR_MAPPER (cosh, ::coshf);
+      SCALAR_MAPPER (exp, ::expf);
+      SCALAR_MAPPER (expm1, ::expm1f);
+      SCALAR_MAPPER (fix, ::fix);
+      SCALAR_MAPPER (floor, ::floorf);
+      SCALAR_MAPPER (log, rc_log);
+      SCALAR_MAPPER (log2, rc_log2);
+      SCALAR_MAPPER (log10, rc_log10);
+      SCALAR_MAPPER (log1p, rc_log1p);
+      SCALAR_MAPPER (round, xround);
+      SCALAR_MAPPER (roundb, xroundb);
+      SCALAR_MAPPER (signum, ::signum);
+      SCALAR_MAPPER (sin, ::sinf);
+      SCALAR_MAPPER (sinh, ::sinhf);
+      SCALAR_MAPPER (sqrt, rc_sqrt);
+      SCALAR_MAPPER (tan, ::tanf);
+      SCALAR_MAPPER (tanh, ::tanhf);
+      SCALAR_MAPPER (finite, xfinite);
+      SCALAR_MAPPER (isinf, xisinf);
+      SCALAR_MAPPER (isna, octave_is_NA);
+      SCALAR_MAPPER (isnan, xisnan);
+
+    default:
+      return octave_base_value::map (umap);
+    }
+}
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-float.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-float.h	Thu Nov 12 15:47:58 2009 +0100
@@ -244,48 +244,9 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
-  octave_value map (float (*fcn) (float)) const;
 
   DECLARE_OCTAVE_ALLOCATOR
 
--- a/src/ov-flt-complex.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-complex.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -385,102 +385,55 @@
   return retval;
 }
 
-static float
-xabs (const FloatComplex& x)
-{
-  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
-}
-
-static float
-ximag (const FloatComplex& x)
-{
-  return x.imag ();
-}
-
-static float
-xreal (const FloatComplex& x)
+octave_value
+octave_float_complex::map (unary_mapper_t umap) const
 {
-  return x.real ();
-}
-
-#define COMPLEX_MAPPER(MAP, FCN)	\
-  octave_value \
-  octave_float_complex::MAP (void) const \
-  { \
-    return octave_value (FCN (scalar)); \
-  }
-
-#define SCALAR_MAPPER(MAP, FCN)	\
-  octave_value \
-  octave_float_complex::MAP (void) const \
-  { \
-    if (scalar.imag () == 0) \
-      return octave_value (FCN (scalar.real ())); \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
+  switch (umap)
+    {
+#define SCALAR_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (FCN (scalar))
 
-#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_float_complex::MAP (void) const \
-  { \
-    if (scalar.imag () == 0) \
-      { \
-	float re = scalar.real (); \
-	return (re < L1 || re > L2 \
-            ? octave_value (CFCN (scalar)) \
-	    : octave_value (RFCN (re))); \
-      } \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
-
-SCALAR_MAPPER (erf, ::erff)
-SCALAR_MAPPER (erfc, ::erfcf)
-SCALAR_MAPPER (gamma, xgamma)
-CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
+      SCALAR_MAPPER (abs, std::abs);
+      SCALAR_MAPPER (acos, ::acos);
+      SCALAR_MAPPER (acosh, ::acosh);
+      SCALAR_MAPPER (angle, std::arg);
+      SCALAR_MAPPER (arg, std::arg);
+      SCALAR_MAPPER (asin, ::asin);
+      SCALAR_MAPPER (asinh, ::asinh);
+      SCALAR_MAPPER (atan, ::atan);
+      SCALAR_MAPPER (atanh, ::atanh);
+      SCALAR_MAPPER (ceil, ::ceil);
+      SCALAR_MAPPER (conj, std::conj);
+      SCALAR_MAPPER (cos, std::cos);
+      SCALAR_MAPPER (cosh, std::cosh);
+      SCALAR_MAPPER (exp, std::exp);
+      SCALAR_MAPPER (expm1, ::expm1);
+      SCALAR_MAPPER (fix, ::fix);
+      SCALAR_MAPPER (floor, ::floor);
+      SCALAR_MAPPER (imag, std::imag);
+      SCALAR_MAPPER (log, std::log);
+      SCALAR_MAPPER (log2, xlog2);
+      SCALAR_MAPPER (log10, std::log10);
+      SCALAR_MAPPER (log1p, ::log1p);
+      SCALAR_MAPPER (real, std::real);
+      SCALAR_MAPPER (round, xround);
+      SCALAR_MAPPER (roundb, xroundb);
+      SCALAR_MAPPER (signum, ::signum);
+      SCALAR_MAPPER (sin, std::sin);
+      SCALAR_MAPPER (sinh, std::sinh);
+      SCALAR_MAPPER (sqrt, std::sqrt);
+      SCALAR_MAPPER (tan, std::tan);
+      SCALAR_MAPPER (tanh, std::tanh);
+      SCALAR_MAPPER (finite, xfinite);
+      SCALAR_MAPPER (isinf, xisinf);
+      SCALAR_MAPPER (isna, octave_is_NA);
+      SCALAR_MAPPER (isnan, xisnan);
 
-COMPLEX_MAPPER (abs, xabs)
-COMPLEX_MAPPER (acos, ::acos)
-COMPLEX_MAPPER (acosh, ::acosh)
-COMPLEX_MAPPER (angle, std::arg)
-COMPLEX_MAPPER (arg, std::arg)
-COMPLEX_MAPPER (asin, ::asin)
-COMPLEX_MAPPER (asinh, ::asinh)
-COMPLEX_MAPPER (atan, ::atan)
-COMPLEX_MAPPER (atanh, ::atanh)
-COMPLEX_MAPPER (ceil, ::ceil)
-COMPLEX_MAPPER (conj, std::conj)
-COMPLEX_MAPPER (cos, std::cos)
-COMPLEX_MAPPER (cosh, std::cosh)
-COMPLEX_MAPPER (exp, std::exp)
-COMPLEX_MAPPER (expm1, ::expm1f)
-COMPLEX_MAPPER (fix, ::fix)
-COMPLEX_MAPPER (floor, ::floor)
-COMPLEX_MAPPER (imag, ximag)
-COMPLEX_MAPPER (log, std::log)
-COMPLEX_MAPPER (log2, xlog2)
-COMPLEX_MAPPER (log10, std::log10)
-COMPLEX_MAPPER (log1p, ::log1pf)
-COMPLEX_MAPPER (real, xreal)
-COMPLEX_MAPPER (round, xround)
-COMPLEX_MAPPER (roundb, xroundb)
-COMPLEX_MAPPER (signum, ::signum)
-COMPLEX_MAPPER (sin, std::sin)
-COMPLEX_MAPPER (sinh, std::sinh)
-COMPLEX_MAPPER (sqrt, std::sqrt)
-COMPLEX_MAPPER (tan, std::tan)
-COMPLEX_MAPPER (tanh, std::tanh)
-COMPLEX_MAPPER (finite, xfinite)
-COMPLEX_MAPPER (isinf, xisinf)
-COMPLEX_MAPPER (isna, octave_is_NA)
-COMPLEX_MAPPER (isnan, xisnan)
+    default:
+      return octave_base_value::map (umap);
+    }
+}
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-flt-complex.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-complex.h	Thu Nov 12 15:47:58 2009 +0100
@@ -163,45 +163,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-flt-cx-diag.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-cx-diag.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -120,43 +120,30 @@
 }
 
 octave_value
-octave_float_complex_diag_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_float_complex_diag_matrix::real (void) const
+octave_float_complex_diag_matrix::map (unary_mapper_t umap) const
 {
-  return ::real (matrix);
-}
-
-octave_value
-octave_float_complex_diag_matrix::conj (void) const
-{
-  return ::conj (matrix);
+  switch (umap)
+    {
+    case umap_abs:
+      return matrix.abs ();
+    case umap_real:
+      return ::real (matrix);
+    case umap_conj:
+      return ::conj (matrix);
+    case umap_imag:
+      return ::imag (matrix);
+    case umap_sqrt:
+      {
+        FloatComplexColumnVector tmp = matrix.diag ().map<FloatComplex> (std::sqrt);
+        FloatComplexDiagMatrix retval (tmp);
+        retval.resize (matrix.rows (), matrix.columns ());
+        return retval;
+      }
+    default:
+      return to_dense ().map (umap);
+    }
 }
 
-octave_value
-octave_float_complex_diag_matrix::imag (void) const
-{
-  return ::imag (matrix);
-}
-
-octave_value
-octave_float_complex_diag_matrix::sqrt (void) const
-{    
-  octave_value retval;
-
-  static FloatComplexNDArray::cmapper csqrt = std::sqrt;
-
-  FloatComplexColumnVector dvec = matrix.diag ();
-  retval = FloatComplexDiagMatrix (dvec.map (csqrt));
-
-  retval.resize (dims ());
-
-  return retval;
-}
 
 bool 
 octave_float_complex_diag_matrix::save_binary (std::ostream& os, 
--- a/src/ov-flt-cx-diag.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-cx-diag.h	Thu Nov 12 15:47:58 2009 +0100
@@ -78,11 +78,7 @@
   bool load_binary (std::istream& is, bool swap, 
 		    oct_mach_info::float_format fmt);
 
-  octave_value abs (void) const;
-  octave_value conj (void) const;
-  octave_value imag (void) const;
-  octave_value real (void) const;
-  octave_value sqrt (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-flt-cx-mat.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-cx-mat.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -686,190 +686,66 @@
   return retval;
 }
 
-#if 0
-static float
-xabs (const FloatComplex& x)
-{
-  return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x);
-}
-#endif
-
-static float
-ximag (const FloatComplex& x)
-{
-  return x.imag ();
-}
-
-static float
-xreal (const FloatComplex& x)
-{
-  return x.real ();
-}
-
-static bool
-any_element_less_than (const FloatNDArray& a, float val)
-{
-  octave_idx_type len = a.length ();
-  const float *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (m[i] < val)
-	return true;
-    }
-
-  return false;
-}
-
-static bool
-any_element_greater_than (const FloatNDArray& a, float val)
+octave_value
+octave_float_complex_matrix::map (unary_mapper_t umap) const
 {
-  octave_idx_type len = a.length ();
-  const float *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
+  switch (umap)
     {
-      OCTAVE_QUIT;
-
-      if (m[i] > val)
-	return true;
-    }
-
-  return false;
-}
+    // Mappers handled specially.
+    case umap_real:
+      return ::real (matrix);
+    case umap_imag:
+      return ::imag (matrix);
+    case umap_conj:
+      return ::conj (matrix);
 
-#define ARRAY_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_float_complex_matrix::MAP (void) const \
-  { \
-    static AMAP cmap = FCN; \
-    return matrix.map (cmap); \
-  }
+#define ARRAY_METHOD_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.FCN ())
 
-#define DARRAY_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_float_complex_matrix::MAP (void) const \
-  { \
-    static FloatComplexNDArray::dmapper dmap = ximag; \
-    FloatNDArray m = matrix.map (dmap); \
-    if (m.all_elements_are_zero ()) \
-      { \
-	dmap = xreal; \
-	m = matrix.map (dmap); \
-        static AMAP cmap = FCN; \
-        return m.map (cmap); \
-      } \
-    else \
-      { \
-        error ("%s: not defined for complex arguments", #MAP); \
-        return octave_value (); \
-      } \
-  }
+      ARRAY_METHOD_MAPPER (abs, abs);
+      ARRAY_METHOD_MAPPER (isnan, isnan);
+      ARRAY_METHOD_MAPPER (isinf, isinf);
+      ARRAY_METHOD_MAPPER (finite, isfinite);
+
+#define ARRAY_MAPPER(UMAP, TYPE, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.map<TYPE> (FCN))
 
-#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_float_complex_matrix::MAP (void) const \
-  { \
-    static FloatComplexNDArray::dmapper idmap = ximag; \
-    NDArray m = matrix.map (idmap); \
-    if (m.all_elements_are_zero ()) \
-      { \
-	static FloatComplexNDArray::dmapper rdmap = xreal; \
-	m = matrix.map (rdmap); \
-        static NDArray::dmapper dmap = RFCN; \
-        static NDArray::cmapper cmap = CFCN; \
-        return (any_element_less_than (m, L1) \
-                ? octave_value (m.map (cmap)) \
-	        : (any_element_greater_than (m, L2) \
-	           ? octave_value (m.map (cmap)) \
-	           : octave_value (m.map (dmap)))); \
-      } \
-    else \
-      { \
-        /*error ("%s: not defined for complex arguments", #MAP); */	\
-        return octave_value (m); \
-      } \
-  }
-
-// The fast mappers.
-octave_value
-octave_float_complex_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_float_complex_matrix::real (void) const
-{
-  return ::real (matrix);
-}
-
-octave_value
-octave_float_complex_matrix::conj (void) const
-{
-  return ::conj (matrix);
-}
-
-octave_value
-octave_float_complex_matrix::imag (void) const
-{
-  return ::imag (matrix);
-}
+      ARRAY_MAPPER (acos, FloatComplex, ::acos);
+      ARRAY_MAPPER (acosh, FloatComplex, ::acosh);
+      ARRAY_MAPPER (angle, float, std::arg);
+      ARRAY_MAPPER (arg, float, std::arg);
+      ARRAY_MAPPER (asin, FloatComplex, ::asin);
+      ARRAY_MAPPER (asinh, FloatComplex, ::asinh);
+      ARRAY_MAPPER (atan, FloatComplex, ::atan);
+      ARRAY_MAPPER (atanh, FloatComplex, ::atanh);
+      ARRAY_MAPPER (ceil, FloatComplex, ::ceil);
+      ARRAY_MAPPER (cos, FloatComplex, std::cos);
+      ARRAY_MAPPER (cosh, FloatComplex, std::cosh);
+      ARRAY_MAPPER (exp, FloatComplex, std::exp);
+      ARRAY_MAPPER (expm1, FloatComplex, ::expm1);
+      ARRAY_MAPPER (fix, FloatComplex, ::fix);
+      ARRAY_MAPPER (floor, FloatComplex, ::floor);
+      ARRAY_MAPPER (log, FloatComplex, std::log);
+      ARRAY_MAPPER (log2, FloatComplex, xlog2);
+      ARRAY_MAPPER (log10, FloatComplex, std::log10);
+      ARRAY_MAPPER (log1p, FloatComplex, ::log1p);
+      ARRAY_MAPPER (round, FloatComplex, xround);
+      ARRAY_MAPPER (roundb, FloatComplex, xroundb);
+      ARRAY_MAPPER (signum, FloatComplex, ::signum);
+      ARRAY_MAPPER (sin, FloatComplex, std::sin);
+      ARRAY_MAPPER (sinh, FloatComplex, std::sinh);
+      ARRAY_MAPPER (sqrt, FloatComplex, std::sqrt);
+      ARRAY_MAPPER (tan, FloatComplex, std::tan);
+      ARRAY_MAPPER (tanh, FloatComplex, std::tanh);
+      ARRAY_MAPPER (isna, bool, octave_is_NA);
 
-octave_value
-octave_float_complex_matrix::isnan (void) const
-{
-  return matrix.isnan ();
-}
-
-octave_value
-octave_float_complex_matrix::isinf (void) const
-{
-  return matrix.isinf ();
-}
-
-octave_value
-octave_float_complex_matrix::finite (void) const
-{
-  return matrix.isfinite ();
+    default:
+      return octave_base_value::map (umap);
+    }
 }
 
-DARRAY_MAPPER (erf, FloatNDArray::dmapper, ::erff)
-DARRAY_MAPPER (erfc, FloatNDArray::dmapper, ::erfcf)
-DARRAY_MAPPER (gamma, FloatNDArray::dmapper, xgamma)
-CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
-
-ARRAY_MAPPER (acos, FloatComplexNDArray::cmapper, ::acos)
-ARRAY_MAPPER (acosh, FloatComplexNDArray::cmapper, ::acosh)
-ARRAY_MAPPER (angle, FloatComplexNDArray::dmapper, std::arg)
-ARRAY_MAPPER (arg, FloatComplexNDArray::dmapper, std::arg)
-ARRAY_MAPPER (asin, FloatComplexNDArray::cmapper, ::asin)
-ARRAY_MAPPER (asinh, FloatComplexNDArray::cmapper, ::asinh)
-ARRAY_MAPPER (atan, FloatComplexNDArray::cmapper, ::atan)
-ARRAY_MAPPER (atanh, FloatComplexNDArray::cmapper, ::atanh)
-ARRAY_MAPPER (ceil, FloatComplexNDArray::cmapper, ::ceil)
-ARRAY_MAPPER (cos, FloatComplexNDArray::cmapper, std::cos)
-ARRAY_MAPPER (cosh, FloatComplexNDArray::cmapper, std::cosh)
-ARRAY_MAPPER (exp, FloatComplexNDArray::cmapper, std::exp)
-ARRAY_MAPPER (expm1, FloatComplexNDArray::cmapper, ::expm1f)
-ARRAY_MAPPER (fix, FloatComplexNDArray::cmapper, ::fix)
-ARRAY_MAPPER (floor, FloatComplexNDArray::cmapper, ::floor)
-ARRAY_MAPPER (log, FloatComplexNDArray::cmapper, std::log)
-ARRAY_MAPPER (log2, FloatComplexNDArray::cmapper, xlog2)
-ARRAY_MAPPER (log10, FloatComplexNDArray::cmapper, std::log10)
-ARRAY_MAPPER (log1p, FloatComplexNDArray::cmapper, ::log1pf)
-ARRAY_MAPPER (round, FloatComplexNDArray::cmapper, xround)
-ARRAY_MAPPER (roundb, FloatComplexNDArray::cmapper, xroundb)
-ARRAY_MAPPER (signum, FloatComplexNDArray::cmapper, ::signum)
-ARRAY_MAPPER (sin, FloatComplexNDArray::cmapper, std::sin)
-ARRAY_MAPPER (sinh, FloatComplexNDArray::cmapper, std::sinh)
-ARRAY_MAPPER (sqrt, FloatComplexNDArray::cmapper, std::sqrt)
-ARRAY_MAPPER (tan, FloatComplexNDArray::cmapper, std::tan)
-ARRAY_MAPPER (tanh, FloatComplexNDArray::cmapper, std::tanh)
-ARRAY_MAPPER (isna, FloatComplexNDArray::bmapper, octave_is_NA)
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/ov-flt-cx-mat.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-cx-mat.h	Thu Nov 12 15:47:58 2009 +0100
@@ -166,45 +166,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-flt-re-diag.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-re-diag.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -91,46 +91,27 @@
 }
 
 octave_value
-octave_float_diag_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_float_diag_matrix::real (void) const
-{
-  return matrix;
-}
-
-octave_value
-octave_float_diag_matrix::conj (void) const
-{
-  return matrix;
-}
-
-octave_value
-octave_float_diag_matrix::imag (void) const
+octave_float_diag_matrix::map (unary_mapper_t umap) const
 {
-  return DiagMatrix (matrix.rows (), matrix.cols (), 0.0f);
-}
-
-octave_value
-octave_float_diag_matrix::sqrt (void) const
-{    
-  octave_value retval;
-
-  static FloatNDArray::dmapper dsqrt = ::sqrtf;
-  static FloatNDArray::cmapper csqrt = std::sqrt;
-
-  FloatColumnVector dvec = matrix.diag ();
-  if (FloatMatrix (dvec).any_element_is_negative ())
-    retval = FloatComplexDiagMatrix (dvec.map (csqrt));
-  else
-    retval = FloatDiagMatrix (dvec.map (dsqrt));
-
-  retval.resize (dims ());
-
-  return retval;
+  switch (umap)
+    {
+    case umap_abs:
+      return matrix.abs ();
+    case umap_real:
+    case umap_conj:
+      return matrix;
+    case umap_imag:
+      return DiagMatrix (matrix.rows (), matrix.cols (), 0.0);
+    case umap_sqrt:
+      {
+        FloatComplexColumnVector tmp = matrix.diag ().map<FloatComplex> (rc_sqrt);
+        FloatComplexDiagMatrix retval (tmp);
+        retval.resize (matrix.rows (), matrix.columns ());
+        return retval;
+      }
+    default:
+      return to_dense ().map (umap);
+    }
 }
 
 bool 
--- a/src/ov-flt-re-diag.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-re-diag.h	Thu Nov 12 15:47:58 2009 +0100
@@ -78,11 +78,7 @@
   bool load_binary (std::istream& is, bool swap, 
 		    oct_mach_info::float_format fmt);
 
-  octave_value abs (void) const;
-  octave_value conj (void) const;
-  octave_value imag (void) const;
-  octave_value real (void) const;
-  octave_value sqrt (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-flt-re-mat.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-re-mat.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -680,137 +680,69 @@
   return retval;
 }
 
-static bool
-any_element_less_than (const FloatNDArray& a, float val)
-{
-  octave_idx_type len = a.length ();
-  const float *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (m[i] < val)
-	return true;
-    }
-
-  return false;
-}
-
-static bool
-any_element_greater_than (const FloatNDArray& a, float val)
-{
-  octave_idx_type len = a.length ();
-  const float *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (m[i] > val)
-	return true;
-    }
-
-  return false;
-}
-
-#define ARRAY_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_float_matrix::MAP (void) const \
-  { \
-    static AMAP dmap = FCN; \
-    return matrix.map (dmap); \
-  }
-
-#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_float_matrix::MAP (void) const \
-  { \
-    static FloatNDArray::dmapper dmap = RFCN; \
-    static FloatNDArray::cmapper cmap = CFCN; \
- \
-    return (any_element_less_than (matrix, L1) \
-            ? octave_value (matrix.map (cmap)) \
-	    : (any_element_greater_than (matrix, L2) \
-	       ? octave_value (matrix.map (cmap)) \
-	       : octave_value (matrix.map (dmap)))); \
-  }
-
-// The fast mappers.
 octave_value
-octave_float_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_float_matrix::real (void) const
+octave_float_matrix::map (unary_mapper_t umap) const
 {
-  return matrix;
-}
+  switch (umap)
+    {
+    case umap_imag:
+      return FloatNDArray (matrix.dims (), 0.0);
 
-octave_value
-octave_float_matrix::conj (void) const
-{
-  return matrix;
-}
-
-octave_value
-octave_float_matrix::imag (void) const
-{
-  return FloatNDArray (matrix.dims (), 0.0);
-}
+    case umap_real:
+    case umap_conj:
+      return matrix;
 
-octave_value
-octave_float_matrix::isnan (void) const
-{
-  return matrix.isnan ();
-}
+    // Mappers handled specially.
+#define ARRAY_METHOD_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.FCN ())
 
-octave_value
-octave_float_matrix::isinf (void) const
-{
-  return matrix.isinf ();
-}
+      ARRAY_METHOD_MAPPER (abs, abs);
+      ARRAY_METHOD_MAPPER (isnan, isnan);
+      ARRAY_METHOD_MAPPER (isinf, isinf);
+      ARRAY_METHOD_MAPPER (finite, isfinite);
 
-octave_value
-octave_float_matrix::finite (void) const
-{
-  return matrix.isfinite ();
-}
+#define ARRAY_MAPPER(UMAP, TYPE, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.map<TYPE> (FCN))
 
-ARRAY_MAPPER (erf, FloatNDArray::dmapper, ::erff)
-ARRAY_MAPPER (erfc, FloatNDArray::dmapper, ::erfcf)
-ARRAY_MAPPER (gamma, FloatNDArray::dmapper, xgamma)
-CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Float_Inf)
-CD_ARRAY_MAPPER (acos, ::acosf, ::acos, -1.0, 1.0)
-CD_ARRAY_MAPPER (acosh, ::acoshf, ::acosh, 1.0, octave_Float_Inf)
-ARRAY_MAPPER (angle, FloatNDArray::dmapper, ::arg)
-ARRAY_MAPPER (arg, FloatNDArray::dmapper, ::arg)
-CD_ARRAY_MAPPER (asin, ::asinf, ::asin, -1.0, 1.0)
-ARRAY_MAPPER (asinh, FloatNDArray::dmapper,::asinhf)
-ARRAY_MAPPER (atan, FloatNDArray::dmapper, ::atanf)
-CD_ARRAY_MAPPER (atanh, ::atanhf, ::atanh, -1.0, 1.0)
-ARRAY_MAPPER (ceil, FloatNDArray::dmapper, ::ceilf)
-ARRAY_MAPPER (cos, FloatNDArray::dmapper, ::cosf)
-ARRAY_MAPPER (cosh, FloatNDArray::dmapper, ::coshf)
-ARRAY_MAPPER (exp, FloatNDArray::dmapper, ::expf)
-ARRAY_MAPPER (expm1, FloatNDArray::dmapper, ::expm1f)
-ARRAY_MAPPER (fix, FloatNDArray::dmapper, ::fix)
-ARRAY_MAPPER (floor, FloatNDArray::dmapper, ::floorf)
-CD_ARRAY_MAPPER (log, ::logf, std::log, 0.0, octave_Float_Inf)
-CD_ARRAY_MAPPER (log2, xlog2, xlog2, 0.0, octave_Float_Inf)
-CD_ARRAY_MAPPER (log10, ::log10f, std::log10, 0.0, octave_Float_Inf)
-CD_ARRAY_MAPPER (log1p, ::log1pf, ::log1pf, -1.0, octave_Float_Inf)
-ARRAY_MAPPER (round, FloatNDArray::dmapper, xround)
-ARRAY_MAPPER (roundb, FloatNDArray::dmapper, xroundb)
-ARRAY_MAPPER (signum, FloatNDArray::dmapper, ::signum)
-ARRAY_MAPPER (sin, FloatNDArray::dmapper, ::sinf)
-ARRAY_MAPPER (sinh, FloatNDArray::dmapper, ::sinhf)
-CD_ARRAY_MAPPER (sqrt, ::sqrtf, std::sqrt, 0.0, octave_Float_Inf)
-ARRAY_MAPPER (tan, FloatNDArray::dmapper, ::tanf)
-ARRAY_MAPPER (tanh, FloatNDArray::dmapper, ::tanhf)
-ARRAY_MAPPER (isna, FloatNDArray::bmapper, octave_is_NA)
+      ARRAY_MAPPER (acos, FloatComplex, rc_acos);
+      ARRAY_MAPPER (acosh, FloatComplex, rc_acosh);
+      ARRAY_MAPPER (angle, float, ::arg);
+      ARRAY_MAPPER (arg, float, ::arg);
+      ARRAY_MAPPER (asin, FloatComplex, rc_asin);
+      ARRAY_MAPPER (asinh, float, ::asinhf);
+      ARRAY_MAPPER (atan, float, ::atanf);
+      ARRAY_MAPPER (atanh, FloatComplex, rc_atanh);
+      ARRAY_MAPPER (erf, float, ::erff);
+      ARRAY_MAPPER (erfc, float, ::erfcf);
+      ARRAY_MAPPER (gamma, float, xgamma);
+      ARRAY_MAPPER (lgamma, FloatComplex, rc_lgamma);
+      ARRAY_MAPPER (ceil, float, ::ceilf);
+      ARRAY_MAPPER (cos, float, ::cosf);
+      ARRAY_MAPPER (cosh, float, ::coshf);
+      ARRAY_MAPPER (exp, float, ::expf);
+      ARRAY_MAPPER (expm1, float, ::expm1f);
+      ARRAY_MAPPER (fix, float, ::fix);
+      ARRAY_MAPPER (floor, float, ::floorf);
+      ARRAY_MAPPER (log, FloatComplex, rc_log);
+      ARRAY_MAPPER (log2, FloatComplex, rc_log2);
+      ARRAY_MAPPER (log10, FloatComplex, rc_log10);
+      ARRAY_MAPPER (log1p, FloatComplex, rc_log1p);
+      ARRAY_MAPPER (round, float, xround);
+      ARRAY_MAPPER (roundb, float, xroundb);
+      ARRAY_MAPPER (signum, float, ::signum);
+      ARRAY_MAPPER (sin, float, ::sinf);
+      ARRAY_MAPPER (sinh, float, ::sinhf);
+      ARRAY_MAPPER (sqrt, FloatComplex, rc_sqrt);
+      ARRAY_MAPPER (tan, float, ::tanf);
+      ARRAY_MAPPER (tanh, float, ::tanhf);
+      ARRAY_MAPPER (isna, bool, octave_is_NA);
+
+    default:
+      return octave_base_value::map (umap);
+    }
+}
 
 DEFUN (single, args, ,
   "-*- texinfo -*-\n\
--- a/src/ov-flt-re-mat.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-flt-re-mat.h	Thu Nov 12 15:47:58 2009 +0100
@@ -202,45 +202,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
   DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-intx.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-intx.h	Thu Nov 12 15:47:58 2009 +0100
@@ -355,42 +355,37 @@
     return retval;
   }
 
-#define MAT_MAPPER(FCN) \
-  octave_value FCN (void) const { return matrix.FCN (); }
-
-  MAT_MAPPER (abs)
-  MAT_MAPPER (signum)
-
-#undef MAT_MAPPER
-
-  octave_value imag (void) const
-  {
-    return intNDArray<OCTAVE_INT_T> (matrix.dims (),
-				     static_cast<OCTAVE_INT_T>(0));
-  }
-
-#define NO_OP_MAPPER(FCN) \
-  octave_value FCN (void) const { return octave_value (matrix); }
+  octave_value map (unary_mapper_t umap) const
+    {
+      switch (umap)
+        {
+        case umap_abs:
+          return matrix.abs ();
+        case umap_signum:
+          return matrix.signum ();
+        case umap_ceil:
+        case umap_conj:
+        case umap_fix:
+        case umap_floor:
+        case umap_real:
+        case umap_round:
+          return matrix;
+        case umap_imag:
+          return intNDArray<OCTAVE_INT_T> (matrix.dims (), OCTAVE_INT_T ());
+        case umap_isnan:
+        case umap_isna:
+        case umap_isinf:
+          return boolNDArray (matrix.dims (), false);
+        case umap_finite:
+          return boolNDArray (matrix.dims (), true);
 
-  NO_OP_MAPPER (ceil)
-  NO_OP_MAPPER (conj)
-  NO_OP_MAPPER (fix)
-  NO_OP_MAPPER (floor)
-  NO_OP_MAPPER (real)
-  NO_OP_MAPPER (round)
-  NO_OP_MAPPER (roundb)
-
-#undef NO_OP_MAPPER
-
-#define BOOL_MAPPER(FCN, VAL) \
-  octave_value FCN (void) const { return boolNDArray (matrix.dims (), VAL); }
-
-  BOOL_MAPPER (finite, true)
-  BOOL_MAPPER (isinf, false)
-  BOOL_MAPPER (isna, false)
-  BOOL_MAPPER (isnan, false)
-
-#undef BOOL_MAPPER
+        default: 
+          {
+            octave_matrix m (array_value ());
+            return m.map (umap);
+          }
+        }
+    }
 
 private:
 
@@ -673,37 +668,37 @@
     return retval;
   }
 
-#define SCALAR_MAPPER(FCN) \
-  octave_value FCN (void) const { return scalar.FCN (); }
-
-  SCALAR_MAPPER (abs)
-  SCALAR_MAPPER (signum)
-
-#undef SCALAR_MAPPER
-
-  octave_value imag (void) const { return static_cast<OCTAVE_INT_T>(0); }
-
-#define NO_OP_MAPPER(FCN) \
-  octave_value FCN (void) const { return octave_value (scalar); }
+  octave_value map (unary_mapper_t umap) const
+    {
+      switch (umap)
+        {
+        case umap_abs:
+          return scalar.abs ();
+        case umap_signum:
+          return scalar.signum ();
+        case umap_ceil:
+        case umap_conj:
+        case umap_fix:
+        case umap_floor:
+        case umap_real:
+        case umap_round:
+          return scalar;
+        case umap_imag:
+          return OCTAVE_INT_T ();
+        case umap_isnan:
+        case umap_isna:
+        case umap_isinf:
+          return false;
+        case umap_finite:
+          return true;
 
-  NO_OP_MAPPER (ceil)
-  NO_OP_MAPPER (conj)
-  NO_OP_MAPPER (fix)
-  NO_OP_MAPPER (floor)
-  NO_OP_MAPPER (real)
-  NO_OP_MAPPER (round)
-  NO_OP_MAPPER (roundb)
-
-#undef NO_OP_MAPPER
-
-#define BOOL_MAPPER(FCN, VAL) octave_value FCN (void) const { return VAL; }
-
-  BOOL_MAPPER (finite, true)
-  BOOL_MAPPER (isinf, false)
-  BOOL_MAPPER (isna, false)
-  BOOL_MAPPER (isnan, false)
-
-#undef BOOL_MAPPER
+        default: 
+          {
+            octave_scalar m (scalar_value ());
+            return m.map (umap);
+          }
+        }
+    }
 
 private:
 
--- a/src/ov-perm.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-perm.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -411,53 +411,6 @@
   return dense_cache;
 }
 
-#define FORWARD_MAPPER(MAP) \
-  octave_value \
-  octave_perm_matrix::MAP (void) const \
-  { \
-    return to_dense ().MAP (); \
-  }
-
-FORWARD_MAPPER (erf)
-FORWARD_MAPPER (erfc)
-FORWARD_MAPPER (gamma)
-FORWARD_MAPPER (lgamma)
-FORWARD_MAPPER (abs)
-FORWARD_MAPPER (acos)
-FORWARD_MAPPER (acosh)
-FORWARD_MAPPER (angle)
-FORWARD_MAPPER (arg)
-FORWARD_MAPPER (asin)
-FORWARD_MAPPER (asinh)
-FORWARD_MAPPER (atan)
-FORWARD_MAPPER (atanh)
-FORWARD_MAPPER (ceil)
-FORWARD_MAPPER (conj)
-FORWARD_MAPPER (cos)
-FORWARD_MAPPER (cosh)
-FORWARD_MAPPER (exp)
-FORWARD_MAPPER (expm1)
-FORWARD_MAPPER (fix)
-FORWARD_MAPPER (floor)
-FORWARD_MAPPER (imag)
-FORWARD_MAPPER (log)
-FORWARD_MAPPER (log2)
-FORWARD_MAPPER (log10)
-FORWARD_MAPPER (log1p)
-FORWARD_MAPPER (real)
-FORWARD_MAPPER (round)
-FORWARD_MAPPER (roundb)
-FORWARD_MAPPER (signum)
-FORWARD_MAPPER (sin)
-FORWARD_MAPPER (sinh)
-FORWARD_MAPPER (sqrt)
-FORWARD_MAPPER (tan)
-FORWARD_MAPPER (tanh)
-FORWARD_MAPPER (finite)
-FORWARD_MAPPER (isinf)
-FORWARD_MAPPER (isna)
-FORWARD_MAPPER (isnan)
-
 DEFINE_OCTAVE_ALLOCATOR (octave_perm_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_perm_matrix, 
--- a/src/ov-perm.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-perm.h	Thu Nov 12 15:47:58 2009 +0100
@@ -209,45 +209,8 @@
 
   void print_info (std::ostream& os, const std::string& prefix) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const
+    { return to_dense ().map (umap); }
 
 protected:
 
--- a/src/ov-range.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-range.h	Thu Nov 12 15:47:58 2009 +0100
@@ -294,54 +294,12 @@
 
   mxArray *as_mxArray (void) const;
 
-  // Mapper functions are converted to double for treatment
-#define RANGE_MAPPER(MAP) \
-  octave_value MAP (void) const \
-    { \
-      octave_matrix m (array_value ()); \
-      return m.MAP (); \
+  octave_value map (unary_mapper_t umap) const
+    {
+      octave_matrix m (matrix_value ());
+      return m.map (umap);
     }
 
-  RANGE_MAPPER (abs)
-  RANGE_MAPPER (acos)
-  RANGE_MAPPER (acosh)
-  RANGE_MAPPER (angle)
-  RANGE_MAPPER (arg)
-  RANGE_MAPPER (asin)
-  RANGE_MAPPER (asinh)
-  RANGE_MAPPER (atan)
-  RANGE_MAPPER (atanh)
-  RANGE_MAPPER (ceil)
-  RANGE_MAPPER (conj)
-  RANGE_MAPPER (cos)
-  RANGE_MAPPER (cosh)
-  RANGE_MAPPER (erf)
-  RANGE_MAPPER (erfc)
-  RANGE_MAPPER (exp)
-  RANGE_MAPPER (expm1)
-  RANGE_MAPPER (finite)
-  RANGE_MAPPER (fix)
-  RANGE_MAPPER (floor)
-  RANGE_MAPPER (gamma)
-  RANGE_MAPPER (imag)
-  RANGE_MAPPER (isinf)
-  RANGE_MAPPER (isna)
-  RANGE_MAPPER (isnan)
-  RANGE_MAPPER (lgamma)
-  RANGE_MAPPER (log)
-  RANGE_MAPPER (log2)
-  RANGE_MAPPER (log10)
-  RANGE_MAPPER (log1p)
-  RANGE_MAPPER (real)
-  RANGE_MAPPER (round)
-  RANGE_MAPPER (roundb)
-  RANGE_MAPPER (signum)
-  RANGE_MAPPER (sin)
-  RANGE_MAPPER (sinh)
-  RANGE_MAPPER (sqrt)
-  RANGE_MAPPER (tan)
-  RANGE_MAPPER (tanh)
-
 private:
 
   Range range;
--- a/src/ov-re-diag.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-re-diag.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -151,46 +151,27 @@
 }
 
 octave_value
-octave_diag_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_diag_matrix::real (void) const
-{
-  return matrix;
-}
-
-octave_value
-octave_diag_matrix::conj (void) const
-{
-  return matrix;
-}
-
-octave_value
-octave_diag_matrix::imag (void) const
+octave_diag_matrix::map (unary_mapper_t umap) const
 {
-  return DiagMatrix (matrix.rows (), matrix.cols (), 0.0);
-}
-
-octave_value
-octave_diag_matrix::sqrt (void) const
-{    
-  octave_value retval;
-
-  static NDArray::dmapper dsqrt = ::sqrt;
-  static NDArray::cmapper csqrt = std::sqrt;
-
-  ColumnVector dvec = matrix.diag ();
-  if (Matrix (dvec).any_element_is_negative ())
-    retval = ComplexDiagMatrix (dvec.map (csqrt));
-  else
-    retval = DiagMatrix (dvec.map (dsqrt));
-
-  retval.resize (dims ());
-
-  return retval;
+  switch (umap)
+    {
+    case umap_abs:
+      return matrix.abs ();
+    case umap_real:
+    case umap_conj:
+      return matrix;
+    case umap_imag:
+      return DiagMatrix (matrix.rows (), matrix.cols (), 0.0);
+    case umap_sqrt:
+      {
+        ComplexColumnVector tmp = matrix.diag ().map<Complex> (rc_sqrt);
+        ComplexDiagMatrix retval (tmp);
+        retval.resize (matrix.rows (), matrix.columns ());
+        return retval;
+      }
+    default:
+      return to_dense ().map (umap);
+    }
 }
 
 bool 
--- a/src/ov-re-diag.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-re-diag.h	Thu Nov 12 15:47:58 2009 +0100
@@ -83,11 +83,7 @@
   bool load_binary (std::istream& is, bool swap, 
 		    oct_mach_info::float_format fmt);
 
-  octave_value abs (void) const;
-  octave_value conj (void) const;
-  octave_value imag (void) const;
-  octave_value real (void) const;
-  octave_value sqrt (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
 
--- a/src/ov-re-mat.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-re-mat.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -708,137 +708,69 @@
   return retval;
 }
 
-static bool
-any_element_less_than (const NDArray& a, double val)
-{
-  octave_idx_type len = a.length ();
-  const double *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (m[i] < val)
-	return true;
-    }
-
-  return false;
-}
-
-static bool
-any_element_greater_than (const NDArray& a, double val)
-{
-  octave_idx_type len = a.length ();
-  const double *m = a.fortran_vec ();
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (m[i] > val)
-	return true;
-    }
-
-  return false;
-}
-
-#define ARRAY_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_matrix::MAP (void) const \
-  { \
-    static AMAP dmap = FCN; \
-    return matrix.map (dmap); \
-  }
-
-#define CD_ARRAY_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_matrix::MAP (void) const \
-  { \
-    static NDArray::dmapper dmap = RFCN; \
-    static NDArray::cmapper cmap = CFCN; \
- \
-    return (any_element_less_than (matrix, L1) \
-            ? octave_value (matrix.map (cmap)) \
-	    : (any_element_greater_than (matrix, L2) \
-	       ? octave_value (matrix.map (cmap)) \
-	       : octave_value (matrix.map (dmap)))); \
-  }
-
-// The fast mappers.
 octave_value
-octave_matrix::abs (void) const
-{
-  return matrix.abs ();
-}
-
-octave_value
-octave_matrix::real (void) const
+octave_matrix::map (unary_mapper_t umap) const
 {
-  return matrix;
-}
+  switch (umap)
+    {
+    case umap_imag:
+      return NDArray (matrix.dims (), 0.0);
 
-octave_value
-octave_matrix::conj (void) const
-{
-  return matrix;
-}
-
-octave_value
-octave_matrix::imag (void) const
-{
-  return NDArray (matrix.dims (), 0.0);
-}
+    case umap_real:
+    case umap_conj:
+      return matrix;
 
-octave_value
-octave_matrix::isnan (void) const
-{
-  return matrix.isnan ();
-}
+    // Mappers handled specially.
+#define ARRAY_METHOD_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.FCN ())
 
-octave_value
-octave_matrix::isinf (void) const
-{
-  return matrix.isinf ();
-}
+      ARRAY_METHOD_MAPPER (abs, abs);
+      ARRAY_METHOD_MAPPER (isnan, isnan);
+      ARRAY_METHOD_MAPPER (isinf, isinf);
+      ARRAY_METHOD_MAPPER (finite, isfinite);
 
-octave_value
-octave_matrix::finite (void) const
-{
-  return matrix.isfinite ();
-}
+#define ARRAY_MAPPER(UMAP, TYPE, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.map<TYPE> (FCN))
 
-ARRAY_MAPPER (erf, NDArray::dmapper, ::erf)
-ARRAY_MAPPER (erfc, NDArray::dmapper, ::erfc)
-ARRAY_MAPPER (gamma, NDArray::dmapper, xgamma)
-CD_ARRAY_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
-CD_ARRAY_MAPPER (acos, ::acos, ::acos, -1.0, 1.0)
-CD_ARRAY_MAPPER (acosh, ::acosh, ::acosh, 1.0, octave_Inf)
-ARRAY_MAPPER (angle, NDArray::dmapper, ::arg)
-ARRAY_MAPPER (arg, NDArray::dmapper, ::arg)
-CD_ARRAY_MAPPER (asin, ::asin, ::asin, -1.0, 1.0)
-ARRAY_MAPPER (asinh, NDArray::dmapper,::asinh)
-ARRAY_MAPPER (atan, NDArray::dmapper, ::atan)
-CD_ARRAY_MAPPER (atanh, ::atanh, ::atanh, -1.0, 1.0)
-ARRAY_MAPPER (ceil, NDArray::dmapper, ::ceil)
-ARRAY_MAPPER (cos, NDArray::dmapper, ::cos)
-ARRAY_MAPPER (cosh, NDArray::dmapper, ::cosh)
-ARRAY_MAPPER (exp, NDArray::dmapper, ::exp)
-ARRAY_MAPPER (expm1, NDArray::dmapper, ::expm1)
-ARRAY_MAPPER (fix, NDArray::dmapper, ::fix)
-ARRAY_MAPPER (floor, NDArray::dmapper, ::floor)
-CD_ARRAY_MAPPER (log, ::log, std::log, 0.0, octave_Inf)
-CD_ARRAY_MAPPER (log2, xlog2, xlog2, 0.0, octave_Inf)
-CD_ARRAY_MAPPER (log10, ::log10, std::log10, 0.0, octave_Inf)
-CD_ARRAY_MAPPER (log1p, ::log1p, ::log1p, -1.0, octave_Inf)
-ARRAY_MAPPER (round, NDArray::dmapper, xround)
-ARRAY_MAPPER (roundb, NDArray::dmapper, xroundb)
-ARRAY_MAPPER (signum, NDArray::dmapper, ::signum)
-ARRAY_MAPPER (sin, NDArray::dmapper, ::sin)
-ARRAY_MAPPER (sinh, NDArray::dmapper, ::sinh)
-CD_ARRAY_MAPPER (sqrt, ::sqrt, std::sqrt, 0.0, octave_Inf)
-ARRAY_MAPPER (tan, NDArray::dmapper, ::tan)
-ARRAY_MAPPER (tanh, NDArray::dmapper, ::tanh)
-ARRAY_MAPPER (isna, NDArray::bmapper, octave_is_NA)
+      ARRAY_MAPPER (acos, Complex, rc_acos);
+      ARRAY_MAPPER (acosh, Complex, rc_acosh);
+      ARRAY_MAPPER (angle, double, ::arg);
+      ARRAY_MAPPER (arg, double, ::arg);
+      ARRAY_MAPPER (asin, Complex, rc_asin);
+      ARRAY_MAPPER (asinh, double, ::asinh);
+      ARRAY_MAPPER (atan, double, ::atan);
+      ARRAY_MAPPER (atanh, Complex, rc_atanh);
+      ARRAY_MAPPER (erf, double, ::erf);
+      ARRAY_MAPPER (erfc, double, ::erfc);
+      ARRAY_MAPPER (gamma, double, xgamma);
+      ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
+      ARRAY_MAPPER (ceil, double, ::ceil);
+      ARRAY_MAPPER (cos, double, ::cos);
+      ARRAY_MAPPER (cosh, double, ::cosh);
+      ARRAY_MAPPER (exp, double, ::exp);
+      ARRAY_MAPPER (expm1, double, ::expm1);
+      ARRAY_MAPPER (fix, double, ::fix);
+      ARRAY_MAPPER (floor, double, ::floor);
+      ARRAY_MAPPER (log, Complex, rc_log);
+      ARRAY_MAPPER (log2, Complex, rc_log2);
+      ARRAY_MAPPER (log10, Complex, rc_log10);
+      ARRAY_MAPPER (log1p, Complex, rc_log1p);
+      ARRAY_MAPPER (round, double, xround);
+      ARRAY_MAPPER (roundb, double, xroundb);
+      ARRAY_MAPPER (signum, double, ::signum);
+      ARRAY_MAPPER (sin, double, ::sin);
+      ARRAY_MAPPER (sinh, double, ::sinh);
+      ARRAY_MAPPER (sqrt, Complex, rc_sqrt);
+      ARRAY_MAPPER (tan, double, ::tan);
+      ARRAY_MAPPER (tanh, double, ::tanh);
+      ARRAY_MAPPER (isna, bool, octave_is_NA);
+
+    default:
+      return octave_base_value::map (umap);
+    }
+}
 
 DEFUN (double, args, ,
   "-*- texinfo -*-\n\
--- a/src/ov-re-mat.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-re-mat.h	Thu Nov 12 15:47:58 2009 +0100
@@ -216,45 +216,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
   DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-re-sparse.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-re-sparse.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -808,111 +808,70 @@
   return retval;
 }
 
-static bool
-any_element_less_than (const SparseMatrix& a, double val)
+octave_value
+octave_sparse_matrix::map (unary_mapper_t umap) const
 {
-  octave_idx_type len = a.nnz ();
-
-  if (val > 0. && len != a.numel ())
-    return true;
+  switch (umap)
+    {
+    case umap_imag:
+      return SparseMatrix (matrix.rows (), matrix.cols (), 0.0);
 
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
+    case umap_real:
+    case umap_conj:
+      return matrix;
 
-      if (a.data(i) < val)
-	return true;
-    }
+    // Mappers handled specially.
+#define ARRAY_METHOD_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.FCN ())
+
+      ARRAY_METHOD_MAPPER (abs, abs);
+
+#define ARRAY_MAPPER(UMAP, TYPE, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (matrix.map<TYPE> (FCN))
 
-  return false;
-}
-
-static bool
-any_element_greater_than (const SparseMatrix& a, double val)
-{
-  octave_idx_type len = a.nnz ();
+      ARRAY_MAPPER (acos, Complex, rc_acos);
+      ARRAY_MAPPER (acosh, Complex, rc_acosh);
+      ARRAY_MAPPER (angle, double, ::arg);
+      ARRAY_MAPPER (arg, double, ::arg);
+      ARRAY_MAPPER (asin, Complex, rc_asin);
+      ARRAY_MAPPER (asinh, double, ::asinh);
+      ARRAY_MAPPER (atan, double, ::atan);
+      ARRAY_MAPPER (atanh, Complex, rc_atanh);
+      ARRAY_MAPPER (erf, double, ::erf);
+      ARRAY_MAPPER (erfc, double, ::erfc);
+      ARRAY_MAPPER (gamma, double, xgamma);
+      ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
+      ARRAY_MAPPER (ceil, double, ::ceil);
+      ARRAY_MAPPER (cos, double, ::cos);
+      ARRAY_MAPPER (cosh, double, ::cosh);
+      ARRAY_MAPPER (exp, double, ::exp);
+      ARRAY_MAPPER (expm1, double, ::expm1);
+      ARRAY_MAPPER (fix, double, ::fix);
+      ARRAY_MAPPER (floor, double, ::floor);
+      ARRAY_MAPPER (log, Complex, rc_log);
+      ARRAY_MAPPER (log2, Complex, rc_log2);
+      ARRAY_MAPPER (log10, Complex, rc_log10);
+      ARRAY_MAPPER (log1p, Complex, rc_log1p);
+      ARRAY_MAPPER (round, double, xround);
+      ARRAY_MAPPER (roundb, double, xroundb);
+      ARRAY_MAPPER (signum, double, ::signum);
+      ARRAY_MAPPER (sin, double, ::sin);
+      ARRAY_MAPPER (sinh, double, ::sinh);
+      ARRAY_MAPPER (sqrt, Complex, rc_sqrt);
+      ARRAY_MAPPER (tan, double, ::tan);
+      ARRAY_MAPPER (tanh, double, ::tanh);
+      ARRAY_MAPPER (isnan, bool, xisnan);
+      ARRAY_MAPPER (isna, bool, octave_is_NA);
+      ARRAY_MAPPER (isinf, bool, xisinf);
+      ARRAY_MAPPER (finite, bool, xfinite);
 
-  if (val < 0. && len != a.numel ())
-    return true;
-
-  for (octave_idx_type i = 0; i < len; i++)
-    {
-      OCTAVE_QUIT;
-
-      if (a.data(i) > val)
-	return true;
+    default: // Attempt to go via dense matrix.
+      return full_value ().map (umap).sparse_matrix_value ();
     }
-
-  return false;
 }
 
-#define SPARSE_MAPPER(MAP, AMAP, FCN) \
-  octave_value \
-  octave_sparse_matrix::MAP (void) const \
-  { \
-    static AMAP dmap = FCN; \
-    return matrix.map (dmap); \
-  }
-
-#define CD_SPARSE_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_sparse_matrix::MAP (void) const \
-  { \
-    static SparseMatrix::dmapper dmap = RFCN; \
-    static SparseMatrix::cmapper cmap = CFCN; \
- \
-    return (any_element_less_than (matrix, L1) \
-            ? octave_value (matrix.map (cmap)) \
-            : (any_element_greater_than (matrix, L2) \
-               ? octave_value (matrix.map (cmap)) \
-	       : octave_value (matrix.map (dmap)))); \
-  }
-
-static double
-xconj (double x)
-{
-  return x;
-}
-
-SPARSE_MAPPER (erf, SparseMatrix::dmapper, ::erf)
-SPARSE_MAPPER (erfc, SparseMatrix::dmapper, ::erfc)
-SPARSE_MAPPER (gamma, SparseMatrix::dmapper, xgamma)
-CD_SPARSE_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
-SPARSE_MAPPER (abs, SparseMatrix::dmapper, ::fabs)
-CD_SPARSE_MAPPER (acos, ::acos, ::acos, -1.0, 1.0)
-CD_SPARSE_MAPPER (acosh, ::acosh, ::acosh, 1.0, octave_Inf)
-SPARSE_MAPPER (angle, SparseMatrix::dmapper, ::arg)
-SPARSE_MAPPER (arg, SparseMatrix::dmapper, ::arg)
-CD_SPARSE_MAPPER (asin, ::asin, ::asin, -1.0, 1.0)
-SPARSE_MAPPER (asinh, SparseMatrix::dmapper, ::asinh)
-SPARSE_MAPPER (atan, SparseMatrix::dmapper, ::atan)
-CD_SPARSE_MAPPER (atanh, ::atanh, ::atanh, -1.0, 1.0)
-SPARSE_MAPPER (ceil, SparseMatrix::dmapper, ::ceil)
-SPARSE_MAPPER (conj, SparseMatrix::dmapper, xconj)
-SPARSE_MAPPER (cos, SparseMatrix::dmapper, ::cos)
-SPARSE_MAPPER (cosh, SparseMatrix::dmapper, ::cosh)
-SPARSE_MAPPER (exp, SparseMatrix::dmapper, ::exp)
-SPARSE_MAPPER (expm1, SparseMatrix::dmapper, ::expm1)
-SPARSE_MAPPER (fix, SparseMatrix::dmapper, ::fix)
-SPARSE_MAPPER (floor, SparseMatrix::dmapper, ::floor)
-SPARSE_MAPPER (imag, SparseMatrix::dmapper, ::imag)
-CD_SPARSE_MAPPER (log, ::log, std::log, 0.0, octave_Inf)
-CD_SPARSE_MAPPER (log2, xlog2, xlog2, 0.0, octave_Inf)
-CD_SPARSE_MAPPER (log10, ::log10, std::log10, 0.0, octave_Inf)
-CD_SPARSE_MAPPER (log1p, ::log1p, ::log1p, 0.0, octave_Inf)
-SPARSE_MAPPER (real, SparseMatrix::dmapper, ::real)
-SPARSE_MAPPER (round, SparseMatrix::dmapper, xround)
-SPARSE_MAPPER (roundb, SparseMatrix::dmapper, xroundb)
-SPARSE_MAPPER (signum, SparseMatrix::dmapper, ::signum)
-SPARSE_MAPPER (sin, SparseMatrix::dmapper, ::sin)
-SPARSE_MAPPER (sinh, SparseMatrix::dmapper, ::sinh)
-CD_SPARSE_MAPPER (sqrt, ::sqrt, std::sqrt, 0.0, octave_Inf)
-SPARSE_MAPPER (tan, SparseMatrix::dmapper, ::tan)
-SPARSE_MAPPER (tanh, SparseMatrix::dmapper, ::tanh)
-SPARSE_MAPPER (finite, SparseMatrix::bmapper, xfinite)
-SPARSE_MAPPER (isinf, SparseMatrix::bmapper, xisinf)
-SPARSE_MAPPER (isna, SparseMatrix::bmapper, octave_is_NA)
-SPARSE_MAPPER (isnan, SparseMatrix::bmapper, xisnan)
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-re-sparse.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-re-sparse.h	Thu Nov 12 15:47:58 2009 +0100
@@ -150,45 +150,7 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
   octave_value map (double (*fcn) (double)) const;
--- a/src/ov-scalar.cc	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-scalar.cc	Thu Nov 12 15:47:58 2009 +0100
@@ -267,67 +267,63 @@
   return retval;
 }
 
-#define SCALAR_MAPPER(MAP, FCN) \
-  octave_value \
-  octave_scalar::MAP (void) const \
-  { \
-    return octave_value (FCN (scalar)); \
-  }
+octave_value
+octave_scalar::map (unary_mapper_t umap) const
+{
+  switch (umap)
+    {
+    case umap_imag:
+      return 0.0;
 
-#define CD_SCALAR_MAPPER(MAP, RFCN, CFCN, L1, L2) \
-  octave_value \
-  octave_scalar::MAP (void) const \
-  { \
-    return (scalar < L1 || scalar > L2 \
-            ? octave_value (CFCN (Complex (scalar))) \
-	    : octave_value (RFCN (scalar))); \
-  }
+    case umap_real:
+    case umap_conj:
+      return scalar;
 
-static double
-xconj (double x)
-{
-  return x;
-}
+#define SCALAR_MAPPER(UMAP, FCN) \
+    case umap_ ## UMAP: \
+      return octave_value (FCN (scalar))
 
-SCALAR_MAPPER (erf, ::erf)
-SCALAR_MAPPER (erfc, ::erfc)
-SCALAR_MAPPER (gamma, xgamma)
-CD_SCALAR_MAPPER (lgamma, xlgamma, xlgamma, 0.0, octave_Inf)
-SCALAR_MAPPER (abs, ::fabs)
-CD_SCALAR_MAPPER (acos, ::acos, ::acos, -1.0, 1.0)
-CD_SCALAR_MAPPER (acosh, ::acosh, ::acosh, 1.0, octave_Inf)
-SCALAR_MAPPER (angle, ::arg)
-SCALAR_MAPPER (arg, ::arg)
-CD_SCALAR_MAPPER (asin, ::asin, ::asin, -1.0, 1.0)
-SCALAR_MAPPER (asinh, ::asinh)
-SCALAR_MAPPER (atan, ::atan)
-CD_SCALAR_MAPPER (atanh, ::atanh, ::atanh, -1.0, 1.0)
-SCALAR_MAPPER (ceil, ::ceil)
-SCALAR_MAPPER (conj, xconj)
-SCALAR_MAPPER (cos, ::cos)
-SCALAR_MAPPER (cosh, ::cosh)
-SCALAR_MAPPER (exp, ::exp)
-SCALAR_MAPPER (expm1, ::expm1)
-SCALAR_MAPPER (fix, ::fix)
-SCALAR_MAPPER (floor, ::floor)
-SCALAR_MAPPER (imag, ::imag)
-CD_SCALAR_MAPPER (log, ::log, std::log, 0.0, octave_Inf)
-CD_SCALAR_MAPPER (log2, xlog2, xlog2, 0.0, octave_Inf)
-CD_SCALAR_MAPPER (log10, ::log10, std::log10, 0.0, octave_Inf)
-CD_SCALAR_MAPPER (log1p, ::log1p, ::log1p, -1.0, octave_Inf)
-SCALAR_MAPPER (real, ::real)
-SCALAR_MAPPER (round, xround)
-SCALAR_MAPPER (roundb, xroundb)
-SCALAR_MAPPER (signum, ::signum)
-SCALAR_MAPPER (sin, ::sin)
-SCALAR_MAPPER (sinh, ::sinh)
-CD_SCALAR_MAPPER (sqrt, ::sqrt, std::sqrt, 0.0, octave_Inf)
-SCALAR_MAPPER (tan, ::tan)
-SCALAR_MAPPER (tanh, ::tanh)
-SCALAR_MAPPER (finite, xfinite)
-SCALAR_MAPPER (isinf, xisinf)
-SCALAR_MAPPER (isna, octave_is_NA)
-SCALAR_MAPPER (isnan, xisnan)
+      SCALAR_MAPPER (abs, ::fabs);
+      SCALAR_MAPPER (acos, rc_acos);
+      SCALAR_MAPPER (acosh, rc_acosh);
+      SCALAR_MAPPER (angle, ::arg);
+      SCALAR_MAPPER (arg, ::arg);
+      SCALAR_MAPPER (asin, rc_asin);
+      SCALAR_MAPPER (asinh, ::asinh);
+      SCALAR_MAPPER (atan, ::atan);
+      SCALAR_MAPPER (atanh, rc_atanh);
+      SCALAR_MAPPER (erf, ::erf);
+      SCALAR_MAPPER (erfc, ::erfc);
+      SCALAR_MAPPER (gamma, xgamma);
+      SCALAR_MAPPER (lgamma, rc_lgamma);
+      SCALAR_MAPPER (ceil, ::ceil);
+      SCALAR_MAPPER (cos, ::cos);
+      SCALAR_MAPPER (cosh, ::cosh);
+      SCALAR_MAPPER (exp, ::exp);
+      SCALAR_MAPPER (expm1, ::expm1);
+      SCALAR_MAPPER (fix, ::fix);
+      SCALAR_MAPPER (floor, ::floor);
+      SCALAR_MAPPER (log, rc_log);
+      SCALAR_MAPPER (log2, rc_log2);
+      SCALAR_MAPPER (log10, rc_log10);
+      SCALAR_MAPPER (log1p, rc_log1p);
+      SCALAR_MAPPER (round, xround);
+      SCALAR_MAPPER (roundb, xroundb);
+      SCALAR_MAPPER (signum, ::signum);
+      SCALAR_MAPPER (sin, ::sin);
+      SCALAR_MAPPER (sinh, ::sinh);
+      SCALAR_MAPPER (sqrt, rc_sqrt);
+      SCALAR_MAPPER (tan, ::tan);
+      SCALAR_MAPPER (tanh, ::tanh);
+      SCALAR_MAPPER (finite, xfinite);
+      SCALAR_MAPPER (isinf, xisinf);
+      SCALAR_MAPPER (isna, octave_is_NA);
+      SCALAR_MAPPER (isnan, xisnan);
+
+    default:
+      return octave_base_value::map (umap);
+    }
+}
 
 /*
 ;;; Local Variables: ***
--- a/src/ov-scalar.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov-scalar.h	Thu Nov 12 15:47:58 2009 +0100
@@ -245,48 +245,9 @@
 
   mxArray *as_mxArray (void) const;
 
-  octave_value erf (void) const;
-  octave_value erfc (void) const;
-  octave_value gamma (void) const;
-  octave_value lgamma (void) const;
-  octave_value abs (void) const;
-  octave_value acos (void) const;
-  octave_value acosh (void) const;
-  octave_value angle (void) const;
-  octave_value arg (void) const;
-  octave_value asin (void) const;
-  octave_value asinh (void) const;
-  octave_value atan (void) const;
-  octave_value atanh (void) const;
-  octave_value ceil (void) const;
-  octave_value conj (void) const;
-  octave_value cos (void) const;
-  octave_value cosh (void) const;
-  octave_value exp (void) const;
-  octave_value expm1 (void) const;
-  octave_value fix (void) const;
-  octave_value floor (void) const;
-  octave_value imag (void) const;
-  octave_value log (void) const;
-  octave_value log2 (void) const;
-  octave_value log10 (void) const;
-  octave_value log1p (void) const;
-  octave_value real (void) const;
-  octave_value round (void) const;
-  octave_value roundb (void) const;
-  octave_value signum (void) const;
-  octave_value sin (void) const;
-  octave_value sinh (void) const;
-  octave_value sqrt (void) const;
-  octave_value tan (void) const;
-  octave_value tanh (void) const;
-  octave_value finite (void) const;
-  octave_value isinf (void) const;
-  octave_value isna (void) const;
-  octave_value isnan (void) const;
+  octave_value map (unary_mapper_t umap) const;
 
 private:
-  octave_value map (double (*fcn) (double)) const;
 
   DECLARE_OCTAVE_ALLOCATOR
 
--- a/src/ov.h	Wed Nov 11 17:43:45 2009 -0800
+++ b/src/ov.h	Thu Nov 12 15:47:58 2009 +0100
@@ -1076,69 +1076,8 @@
 
   void dump (std::ostream& os) const { rep->dump (os); }
 
-#define MAPPER_FORWARD(F) \
-  octave_value F (void) const { return rep->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 (unary_mapper_t umap) const
+    { return rep->map (umap); } 
 
 protected: