changeset 8725:d5af326a3ede

[mq]: sort-traits
author John W. Eaton <jwe@octave.org>
date Thu, 12 Feb 2009 02:49:14 -0500
parents a50228129dba
children 0f6683a8150a
files liboctave/Array-C.cc liboctave/Array-d.cc liboctave/Array-f.cc liboctave/Array-fC.cc liboctave/Array.cc liboctave/Array.h liboctave/ChangeLog liboctave/Makefile.in liboctave/lo-traits.h liboctave/oct-sort.cc liboctave/oct-sort.h src/ChangeLog src/TEMPLATE-INST/Array-tc.cc
diffstat 13 files changed, 221 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array-C.cc	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/Array-C.cc	Thu Feb 12 02:49:14 2009 -0500
@@ -35,14 +35,15 @@
 #include "oct-sort.cc"
 
 template <>
-inline bool _sort_isnan (Complex x)
+inline bool
+sort_isnan<Complex> (const Complex& x)
 {
   return xisnan (x);
 }
 
 template <>
 bool
-octave_sort<Complex>::ascending_compare (Complex a, Complex b)
+octave_sort<Complex>::ascending_compare (const Complex& a, const Complex& b)
 {
   return ((std::abs (a) < std::abs (b))
 	  || ((std::abs (a) == std::abs (b)) && (arg (a) < arg (b))));
@@ -50,29 +51,34 @@
 
 template <>
 bool
-octave_sort<Complex>::descending_compare (Complex a, Complex b)
+octave_sort<Complex>::descending_compare (const Complex& a, const Complex& b)
 {
   return ((std::abs (a) > std::abs (b))
 	  || ((std::abs (a) == std::abs (b)) && (arg (a) > arg (b))));
 }
 
-static bool nan_ascending_compare (Complex x, Complex y)
+static bool
+nan_ascending_compare (const Complex& x, const Complex& y)
 {
-  return xisnan (y) ? ! xisnan (x) : ((std::abs (x) < std::abs (x))
-	  || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x))));
+  return (xisnan (y)
+	  ? ! xisnan (x)
+	  : ((std::abs (x) < std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x)))));
 }
 
-static bool nan_descending_compare (Complex x, Complex y)
+static bool
+nan_descending_compare (const Complex& x, const Complex& y)
 {
-  return xisnan (x) ? ! xisnan (y) : ((std::abs (x) > std::abs (x))
-	  || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x))));
+  return (xisnan (x)
+	  ? ! xisnan (y)
+	  : ((std::abs (x) > std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x)))));
 }
 
-bool (*_sortrows_comparator (sortmode mode, 
-                             const Array<Complex>& a , bool allow_chk)) 
-(Complex, Complex)
+Array<Complex>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<Complex>& a , bool allow_chk)
 {
-  bool (*result) (Complex, Complex) = 0;
+  Array<Complex>::compare_fcn_type result = 0;
 
   if (allow_chk)
     {
--- a/liboctave/Array-d.cc	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/Array-d.cc	Thu Feb 12 02:49:14 2009 -0500
@@ -37,26 +37,28 @@
 #include "oct-sort.cc"
 
 template <>
-inline bool _sort_isnan (double x)
+inline bool
+sort_isnan<double> (double x)
 {
   return lo_ieee_isnan (x);
 }
 
-static bool nan_ascending_compare (double x, double y)
+static bool
+nan_ascending_compare (double x, double y)
 {
   return lo_ieee_isnan (y) ? ! lo_ieee_isnan (x) : x < y;
 }
 
-static bool nan_descending_compare (double x, double y)
+static bool
+nan_descending_compare (double x, double y)
 {
   return lo_ieee_isnan (x) ? ! lo_ieee_isnan (y) : x > y;
 }
 
-bool (*_sortrows_comparator (sortmode mode, 
-                             const Array<double>& a , bool allow_chk)) 
-(double, double)
+Array<double>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<double>& a , bool allow_chk)
 {
-  bool (*result) (double, double) = 0;
+  Array<double>::compare_fcn_type result = 0;
 
   if (allow_chk)
     {
--- a/liboctave/Array-f.cc	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/Array-f.cc	Thu Feb 12 02:49:14 2009 -0500
@@ -37,26 +37,28 @@
 #include "oct-sort.cc"
 
 template <>
-inline bool _sort_isnan (float x)
+inline bool
+sort_isnan<float> (float x)
 {
   return lo_ieee_isnan (x);
 }
 
-static bool nan_ascending_compare (float x, float y)
+static bool
+nan_ascending_compare (float x, float y)
 {
   return lo_ieee_isnan (y) ? ! lo_ieee_isnan (x) : x < y;
 }
 
-static bool nan_descending_compare (float x, float y)
+static bool
+nan_descending_compare (float x, float y)
 {
   return lo_ieee_isnan (x) ? ! lo_ieee_isnan (y) : x > y;
 }
 
-bool (*_sortrows_comparator (sortmode mode, 
-                             const Array<float>& a , bool allow_chk)) 
-(float, float)
+Array<float>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<float>& a , bool allow_chk)
 {
-  bool (*result) (float, float) = 0;
+  Array<float>::compare_fcn_type result = 0;
 
   if (allow_chk)
     {
--- a/liboctave/Array-fC.cc	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/Array-fC.cc	Thu Feb 12 02:49:14 2009 -0500
@@ -35,14 +35,16 @@
 #include "oct-sort.cc"
 
 template <>
-inline bool _sort_isnan (FloatComplex x)
+inline bool
+sort_isnan<FloatComplex> (const FloatComplex& x)
 {
   return xisnan (x);
 }
 
 template <>
 bool
-octave_sort<FloatComplex>::ascending_compare (FloatComplex a, FloatComplex b)
+octave_sort<FloatComplex>::ascending_compare (const FloatComplex& a,
+					      const FloatComplex& b)
 {
   return ((std::abs (a) < std::abs (b))
 	  || ((std::abs (a) == std::abs (b)) && (arg (a) < arg (b))));
@@ -50,29 +52,36 @@
 
 template <>
 bool
-octave_sort<FloatComplex>::descending_compare (FloatComplex a, FloatComplex b)
+octave_sort<FloatComplex>::descending_compare (const FloatComplex& a,
+					       const FloatComplex& b)
 {
   return ((std::abs (a) > std::abs (b))
 	  || ((std::abs (a) == std::abs (b)) && (arg (a) > arg (b))));
 }
 
-static bool nan_ascending_compare (FloatComplex x, FloatComplex y)
+static bool
+nan_ascending_compare (const FloatComplex& x, const FloatComplex& y)
 {
-  return xisnan (y) ? ! xisnan (x) : ((std::abs (x) < std::abs (x))
-	  || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x))));
+  return (xisnan (y)
+	  ? ! xisnan (x)
+	  : ((std::abs (x) < std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x)))));
 }
 
-static bool nan_descending_compare (FloatComplex x, FloatComplex y)
+static bool
+nan_descending_compare (const FloatComplex& x, const FloatComplex& y)
 {
-  return xisnan (x) ? ! xisnan (y) : ((std::abs (x) > std::abs (x))
-	  || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x))));
+  return (xisnan (x)
+	  ? ! xisnan (y)
+	  : ((std::abs (x) > std::abs (x))
+	     || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x)))));
 }
 
-bool (*_sortrows_comparator (sortmode mode, 
-                             const Array<FloatComplex>& a , bool allow_chk)) 
-(FloatComplex, FloatComplex)
+Array<FloatComplex>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<FloatComplex>& a,
+		     bool allow_chk)
 {
-  bool (*result) (FloatComplex, FloatComplex) = 0;
+  Array<FloatComplex>::compare_fcn_type result = 0;
 
   if (allow_chk)
     {
--- a/liboctave/Array.cc	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/Array.cc	Thu Feb 12 02:49:14 2009 -0500
@@ -1977,8 +1977,8 @@
 
 // Non-real types don't have NaNs.
 template <class T>
-inline
-bool _sort_isnan (T)
+inline bool
+sort_isnan (typename ref_param<T>::type)
 {
   return false;
 }
@@ -2028,7 +2028,7 @@
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i];
-              if (_sort_isnan (tmp))
+              if (sort_isnan<T> (tmp))
                 v[--ku] = tmp;
               else
                 v[kl++] = tmp;
@@ -2072,7 +2072,7 @@
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i*stride + offset];
-              if (_sort_isnan (tmp))
+              if (sort_isnan<T> (tmp))
                 buf[--ku] = tmp;
               else
                 buf[kl++] = tmp;
@@ -2150,7 +2150,7 @@
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i];
-              if (_sort_isnan (tmp))
+              if (sort_isnan<T> (tmp))
                 {
                   --ku;
                   v[ku] = tmp;
@@ -2208,7 +2208,7 @@
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i*stride + offset];
-              if (_sort_isnan (tmp))
+              if (sort_isnan<T> (tmp))
                 {
                   --ku;
                   buf[ku] = tmp;
@@ -2258,19 +2258,19 @@
   const T *lo = data (), *hi = data () + nelem () - 1;
 
   // Check for NaNs at the beginning and end.
-  if (mode != ASCENDING && _sort_isnan (*lo))
+  if (mode != ASCENDING && sort_isnan<T> (*lo))
     {
       mode = DESCENDING;
       do
         ++lo;
-      while (lo < hi && _sort_isnan (*lo));
+      while (lo < hi && sort_isnan<T> (*lo));
     }
-  else if (mode != DESCENDING && _sort_isnan (*hi))
+  else if (mode != DESCENDING && sort_isnan<T> (*hi))
     {
       mode = ASCENDING;
       do
         --hi;
-      while (lo < hi && _sort_isnan (*hi));
+      while (lo < hi && sort_isnan<T> (*hi));
     }
   
   octave_sort<T> lsort;
@@ -2295,8 +2295,9 @@
 }
 
 template <class T>
-bool (*_sortrows_comparator (sortmode mode, 
-                             const Array<T>& /* a */, bool /* allow_chk */)) (T, T)
+typename Array<T>::compare_fcn_type
+sortrows_comparator (sortmode mode, const Array<T>& /* a */,
+		     bool /* allow_chk */)
 {
   if (mode == ASCENDING)
     return octave_sort<T>::ascending_compare;
@@ -2314,7 +2315,7 @@
 
   octave_sort<T> lsort;
 
-  lsort.set_compare (_sortrows_comparator (mode, *this, true));
+  lsort.set_compare (sortrows_comparator (mode, *this, true));
 
   octave_idx_type r = rows (), c = cols ();
 
@@ -2340,7 +2341,8 @@
   if (! mode)
     {
       // Auto-detect mode.
-      bool (*compare) (T, T) = _sortrows_comparator (ASCENDING, *this, false);
+      compare_fcn_type compare
+	= sortrows_comparator (ASCENDING, *this, false);
 
       octave_idx_type i;
       for (i = 0; i < cols (); i++)
@@ -2373,7 +2375,7 @@
 
   if (mode)
     {
-      lsort.set_compare (_sortrows_comparator (mode, *this, false));
+      lsort.set_compare (sortrows_comparator (mode, *this, false));
 
       if (! lsort.is_sorted_rows (data (), r, c))
         mode = UNSORTED;
@@ -2398,9 +2400,8 @@
 Array<T>::is_sorted (sortmode) const  \
 { return UNSORTED; } \
  \
-template <> \
-bool (*_sortrows_comparator (sortmode,  \
-                             const Array<T>&, bool)) (T, T) \
+Array<T>::compare_fcn_type \
+sortrows_comparator (sortmode, const Array<T>&, bool) \
 { return 0; } \
  \
 template <> Array<octave_idx_type>  \
--- a/liboctave/Array.h	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/Array.h	Thu Feb 12 02:49:14 2009 -0500
@@ -34,6 +34,7 @@
 
 #include "dim-vector.h"
 #include "idx-vector.h"
+#include "lo-traits.h"
 #include "lo-utils.h"
 #include "oct-sort.h"
 #include "quit.h"
@@ -101,6 +102,9 @@
 
   typedef T element_type;
 
+  typedef bool (*compare_fcn_type) (typename ref_param<T>::type,
+				    typename ref_param<T>::type);
+
 protected:
 
   typename Array<T>::ArrayRep *rep;
--- a/liboctave/ChangeLog	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/ChangeLog	Thu Feb 12 02:49:14 2009 -0500
@@ -1,3 +1,32 @@
+2009-02-12  John W. Eaton  <jwe@octave.org>
+
+	* lo-traits.h: New file.
+	* Makefile.in (INCLUDES): Add it to the list.
+
+	* Array.h (compare_fcn_type): New typedef.
+	* oct-sort.h (compare_fcn_type): Ditto.
+
+	* oct-sort.h, oct-sort.cc (octave_sort<T>::octave_sort,
+	octave_sort<T>::set_compare, octave_sort<T>::compare): 
+	Use typedef to simplify decl.
+	(octave_sort<T>::ascending_compare,
+	octave_sort<T>::descending_compare):
+	Use ref_param<T>::type for parameter decl.
+
+	* Array.cc (sort_isnan): Use ref_param<T>::type for parameter decl.
+	(Array<T>::sort): Use explicit template parameter for sort_isnan calls.
+
+	* Array.cc, Array-C.cc, Array-fC.cc, Array-d.cc, Array-f.cc
+	(sortrows_comparator): Rename from _sortrows_comparator.  Change
+	all uses.  Use typedef for return value to simplify decl.
+	(sort_isnan): Rename from _sort_isnan.  Change all uses.
+	(NO_INSTANTIATE_ARRAY_SORT): Use typedef to simplify instantiation
+	of sortrows_comparator.
+
+	* Array-C.cc, Array-fC.cc (sort_isnan, ascending_compare,
+	descending_compare, nan_ascending_compare,
+	nan_descending_compare):
+
 2009-02-11  Jaroslav Hajek  <highegg@gmail.com>
 
 	* oct-sort.cc (octave_sort<T>::is_sorted, octave_sort<T>::sort_rows,
--- a/liboctave/Makefile.in	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/Makefile.in	Thu Feb 12 02:49:14 2009 -0500
@@ -85,8 +85,8 @@
 	base-de.h base-min.h byte-swap.h cmd-edit.h cmd-hist.h \
 	data-conv.h dir-ops.h file-ops.h file-stat.h functor.h getopt.h \
 	glob-match.h idx-vector.h kpse-xfns.h \
-	lo-ieee.h lo-mappers.h lo-math.h lo-specfun.h \
-	lo-sysdep.h lo-utils.h mach-info.h md5.h oct-alloc.h oct-cmplx.h \
+	lo-ieee.h lo-mappers.h lo-math.h lo-specfun.h lo-sysdep.h \
+	lo-traits.h lo-utils.h mach-info.h md5.h oct-alloc.h oct-cmplx.h \
 	oct-env.h oct-fftw.h oct-getopt.h oct-group.h oct-inttypes.h \
 	oct-locbuf.h oct-lookup.h oct-md5.h oct-mutex.h oct-norm.h \
         oct-passwd.h oct-rand.h oct-rl-edit.h oct-rl-hist.h oct-shlib.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/lo-traits.h	Thu Feb 12 02:49:14 2009 -0500
@@ -0,0 +1,80 @@
+/*
+
+Copyright (C) 2009 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_liboctave_traits_h)
+#define octave_liboctave_traits_h 1
+
+template <bool cond, typename T1, typename T2>
+class if_then_else;
+
+template<typename T1, typename T2>
+class if_then_else<true, T1, T2>
+{
+public:
+
+  typedef T1 result;
+};
+
+template<typename T1, typename T2>
+class if_then_else<false, T1, T2>
+{
+public:
+
+  typedef T2 result;
+};
+
+template<typename T1>
+class is_class_type
+{
+private:
+
+  typedef char one;
+  typedef struct { char c[2]; } two;
+
+  // Classes can have pointers to members.
+  template<typename T2> static one is_class_type_test (int T2::*);
+
+  // Catch everything else.
+  template<typename T2> static two is_class_type_test (...);
+
+public:
+
+  enum { yes = sizeof (is_class_type_test<T1> (0)) == 1 };
+  enum { no = ! yes };
+};
+
+template<typename T>
+class ref_param
+{
+public:
+
+  typedef typename if_then_else<is_class_type<T>::no, T, T const&>::result type;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C ***
+;;; page-delimiter: "^/\\*" ***
+;;; End: ***
+*/
--- a/liboctave/oct-sort.cc	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/oct-sort.cc	Thu Feb 12 02:49:14 2009 -0500
@@ -111,7 +111,7 @@
 }
 
 template <class T>
-octave_sort<T>::octave_sort (bool (*comp) (T, T)) : compare (comp) 
+octave_sort<T>::octave_sort (compare_fcn_type comp) : compare (comp) 
 { 
   merge_init (); 
 }
@@ -1763,14 +1763,16 @@
 
 template <class T>
 bool 
-octave_sort<T>::ascending_compare (T x, T y)
+octave_sort<T>::ascending_compare (typename ref_param<T>::type x,
+				   typename ref_param<T>::type y)
 {
   return x < y;
 }
 
 template <class T>
 bool 
-octave_sort<T>::descending_compare (T x, T y)
+octave_sort<T>::descending_compare (typename ref_param<T>::type x,
+				    typename ref_param<T>::type y)
 {
   return x > y;
 }
--- a/liboctave/oct-sort.h	Wed Feb 11 19:46:23 2009 -0500
+++ b/liboctave/oct-sort.h	Thu Feb 12 02:49:14 2009 -0500
@@ -82,6 +82,8 @@
 #if !defined (octave_sort_h)
 #define octave_sort_h 1
 
+#include "lo-traits.h"
+
 // The maximum number of entries in a MergeState's pending-runs stack.
 // This is enough to sort arrays of size up to about
 //     32 * phi ** MAX_MERGE_PENDING
@@ -105,13 +107,16 @@
 {
 public:
 
+  typedef bool (*compare_fcn_type) (typename ref_param<T>::type,
+				    typename ref_param<T>::type);
+
   octave_sort (void);
 
-  octave_sort (bool (*comp) (T, T));
+  octave_sort (compare_fcn_type);
   
   ~octave_sort (void) { merge_freemem (); }
 
-  void set_compare (bool (*comp) (T, T)) { compare = comp; }
+  void set_compare (compare_fcn_type comp) { compare = comp; }
 
   void set_compare (sortmode mode);
 
@@ -133,8 +138,11 @@
   bool is_sorted_rows (const T *data, 
                        octave_idx_type rows, octave_idx_type cols);
 
-  static bool ascending_compare (T, T);
-  static bool descending_compare (T, T);
+  static bool ascending_compare (typename ref_param<T>::type,
+				 typename ref_param<T>::type);
+
+  static bool descending_compare (typename ref_param<T>::type,
+				  typename ref_param<T>::type);
 
 private:
 
@@ -177,7 +185,7 @@
     struct s_slice pending[MAX_MERGE_PENDING];
   };
 
-  bool (*compare) (T, T);
+  compare_fcn_type compare;
   
   MergeState ms;
   
--- a/src/ChangeLog	Wed Feb 11 19:46:23 2009 -0500
+++ b/src/ChangeLog	Thu Feb 12 02:49:14 2009 -0500
@@ -1,3 +1,12 @@
+2009-02-12  John W. Eaton  <jwe@octave.org>
+
+	* TEMPLATE-INST/Array-tc.cc
+	(octave_sort<octave_value>::ascending_compare,
+	octave_sort<octave_value>::descending_compare):
+	Delete unused template specializations.
+	Use NO_INSTANTIATE_ARRAY_SORT instead of INSTANTIATE_ARRAY_SORT
+	for octave_values.
+
 2009-02-11  Thomas Treichl  <Thomas.Treichl@gmx.net>
 
 	* gl-render.h: Use HAVE_FRAMEWORK_OPENGL.
--- a/src/TEMPLATE-INST/Array-tc.cc	Wed Feb 11 19:46:23 2009 -0500
+++ b/src/TEMPLATE-INST/Array-tc.cc	Thu Feb 12 02:49:14 2009 -0500
@@ -42,21 +42,7 @@
 
 #include "oct-sort.cc"
 
-template <>
-bool
-octave_sort<octave_value>::ascending_compare (octave_value a, octave_value b)
-{
-  return (a.string_value () < b.string_value ());
-}
-
-template <>
-bool
-octave_sort<octave_value>::descending_compare (octave_value a, octave_value b)
-{
-  return (a.string_value () > b.string_value ());
-}
-
-INSTANTIATE_ARRAY_SORT (octave_value);
+NO_INSTANTIATE_ARRAY_SORT (octave_value);
 
 INSTANTIATE_ARRAY (octave_value, OCTINTERP_API);