changeset 5533:667ad2becb63

[project @ 2005-11-10 21:40:48 by jwe]
author jwe
date Thu, 10 Nov 2005 21:40:49 +0000
parents 8ad54ce6a831
children e107161b8ca3
files liboctave/ChangeLog liboctave/oct-inttypes.h src/ChangeLog src/OPERATORS/op-int-concat.cc src/OPERATORS/op-int.h src/OPERATORS/op-s-scm.cc src/OPERATORS/op-s-sm.cc src/OPERATORS/op-str-m.cc src/OPERATORS/op-str-s.cc src/OPERATORS/op-str-str.cc src/data.cc src/ops.h src/ov-bool-mat.h src/ov-bool.h src/ov-intx.h src/ov-re-mat.h src/ov-scalar.h src/ov-str-mat.h src/pt-mat.cc
diffstat 19 files changed, 552 insertions(+), 114 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Mon Nov 07 20:15:39 2005 +0000
+++ b/liboctave/ChangeLog	Thu Nov 10 21:40:49 2005 +0000
@@ -1,3 +1,8 @@
+2005-11-09  John W. Eaton  <jwe@octave.org>
+
+	* oct-inttypes.h (octave_int::operator char (void) const):
+	New conversion op.
+
 2005-11-01  John W. Eaton  <jwe@octave.org>
 
 	* Makefile.in (distclean): Also remove oct-types.h.
--- a/liboctave/oct-inttypes.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/liboctave/oct-inttypes.h	Thu Nov 10 21:40:49 2005 +0000
@@ -257,6 +257,8 @@
       OCTAVE_INT_FIT_TO_RANGE (- static_cast<double> (ival), T) : 0;
   }
 
+  operator char (void) const { return static_cast<char> (value ()); }
+
   operator double (void) const { return static_cast<double> (value ()); }
 
   operator float (void) const { return static_cast<float> (value ()); }
--- a/src/ChangeLog	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ChangeLog	Thu Nov 10 21:40:49 2005 +0000
@@ -1,3 +1,47 @@
+2005-11-10  John W. Eaton  <jwe@octave.org>
+
+	* ov-str-mat.h (octave_char_matrix_str::permute,
+	octave_char_matrix_str::resize): New functions.
+	(octave_char_matrix_sq_str::reshape,
+	octave_char_matrix_sq_str::permute,
+	octave_char_matrix_sq_str::resize): New functions.
+
+	* OPERATORS/op-str-str.cc, OPERATORS/op-str-s.cc,
+	OPERATORS/op-str-m.cc: Use DEFNDCHARCATOP_FN.
+
+	* data.cc (do_cat): No need to handle character arrays specially here.
+
+	* ops.h (DEFNDCHARCATOP_FN): New macro.
+	* OPERATORS/op-int.h (OCTAVE_INT_CHAR_CONCAT_FN, 
+	OCTAVE_CHAR_INT_CONCAT_FN, OCTAVE_INSTALL_INT_CHAR_CONCAT_FN,
+	OCTAVE_INSTALL_CHAR_INT_CONCAT_FN): New macros.
+	* OPERATORS/op-int-concat.cc: Use them do define char/int op functions.
+	(install_int_concat_ops): Install char/int concat ops.
+
+	* ov-scalar.h (class octave_scalar): Provide extractors
+	for all int array types and char array type.
+
+2005-11-09  John W. Eaton  <jwe@octave.org>
+
+	* ov-bool-mat.h (class octave_bool_matrix): Provide extractors
+	for all int array types and char array type.
+	* ov-bool.h (class octave_bool): Likewise.
+
+	* ov-intx.h (class OCTAVE_VALUE_INT_MATRIX_T): Provide extractors
+	for all int array types and char array type.
+	(class OCTAVE_VALUE_INT_SCALAR_T): Provide extractors for all int
+	scalar and array types and char array type.
+
+	* pt-mat.cc (tm_const::class_nm): New data member.
+	(tm_const::tm_const): Initialize it.
+	(tm_const::class_name): New function.
+	(tm_row_const::tm_row_const_rep::class_nm): New data member.
+	(tm_row_const::tm_row_const_rep::tm_row_const_rep): Initialize it.
+	(tm_row_const::class_name): New function.
+	(get_concat_class): New function.
+	(tm_row_const::tm_row_const_rep::do_init_element): Use it.
+	(tm_const::init): Use it.
+
 2005-11-07  John W. Eaton  <jwe@octave.org>
 
 	* strfns.cc (Fstrcmp): If args are not strings or cell arrays of
--- a/src/OPERATORS/op-int-concat.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/OPERATORS/op-int-concat.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -140,6 +140,26 @@
 OCTAVE_DOUBLE_INT_CONCAT_FN (uint32)
 OCTAVE_DOUBLE_INT_CONCAT_FN (uint64)
 
+OCTAVE_INT_CHAR_CONCAT_FN (int8)
+OCTAVE_INT_CHAR_CONCAT_FN (int16)
+OCTAVE_INT_CHAR_CONCAT_FN (int32)
+OCTAVE_INT_CHAR_CONCAT_FN (int64)
+
+OCTAVE_INT_CHAR_CONCAT_FN (uint8)
+OCTAVE_INT_CHAR_CONCAT_FN (uint16)
+OCTAVE_INT_CHAR_CONCAT_FN (uint32)
+OCTAVE_INT_CHAR_CONCAT_FN (uint64)
+
+OCTAVE_CHAR_INT_CONCAT_FN (int8)
+OCTAVE_CHAR_INT_CONCAT_FN (int16)
+OCTAVE_CHAR_INT_CONCAT_FN (int32)
+OCTAVE_CHAR_INT_CONCAT_FN (int64)
+	      	   
+OCTAVE_CHAR_INT_CONCAT_FN (uint8)
+OCTAVE_CHAR_INT_CONCAT_FN (uint16)
+OCTAVE_CHAR_INT_CONCAT_FN (uint32)
+OCTAVE_CHAR_INT_CONCAT_FN (uint64)
+
 void
 install_int_concat_ops (void)
 {
@@ -234,6 +254,26 @@
   OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (uint16);
   OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (uint32);
   OCTAVE_INSTALL_DOUBLE_INT_CONCAT_FN (uint64);
+
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int8);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int16);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int32);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_INT_CHAR_CONCAT_FN (uint64);
+
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int8);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int16);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int32);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (int64);
+
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint8);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint16);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint32);
+  OCTAVE_INSTALL_CHAR_INT_CONCAT_FN (uint64);
 }
 
 /*
--- a/src/OPERATORS/op-int.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/OPERATORS/op-int.h	Thu Nov 10 21:40:49 2005 +0000
@@ -59,6 +59,29 @@
   INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_scalar, TYPE ## _ ## double ## _m_s) \
   INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_matrix, TYPE ## _ ## double ## _m_m)
 
+// For compatibility, concatenation with a character always returns a
+// character.
+
+#define OCTAVE_CHAR_INT_CONCAT_FN(TYPE) \
+  DEFNDCHARCATOP_FN (char ## _ ## TYPE ## _m_s, char_matrix, TYPE ## _scalar, concat) \
+  DEFNDCHARCATOP_FN (char ## _ ## TYPE ## _m_m, char_matrix, TYPE ## _matrix, concat)
+
+#define OCTAVE_INSTALL_CHAR_INT_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_char_matrix_str, octave_ ## TYPE ## _scalar, char ## _ ## TYPE ## _m_s) \
+  INSTALL_CATOP (octave_char_matrix_str, octave_ ## TYPE ## _matrix, char ## _ ## TYPE ## _m_m) \
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_ ## TYPE ## _scalar, char ## _ ## TYPE ## _m_s) \
+  INSTALL_CATOP (octave_char_matrix_sq_str, octave_ ## TYPE ## _matrix, char ## _ ## TYPE ## _m_m)
+
+#define OCTAVE_INT_CHAR_CONCAT_FN(TYPE) \
+  DEFNDCHARCATOP_FN (TYPE ## _ ## char ## _s_m, TYPE ## _scalar, char_matrix, concat) \
+  DEFNDCHARCATOP_FN (TYPE ## _ ## char ## _m_m, TYPE ## _matrix, char_matrix, concat)
+
+#define OCTAVE_INSTALL_INT_CHAR_CONCAT_FN(TYPE) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_char_matrix_str, TYPE ## _ ## char ## _s_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_char_matrix_str, TYPE ## _ ## char ## _m_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_char_matrix_sq_str, TYPE ## _ ## char ## _s_m) \
+  INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_char_matrix_sq_str, TYPE ## _ ## char ## _m_m)
+
 #define OCTAVE_CONCAT_FN(TYPE) \
   DEFNDCATOP_FN (TYPE ## _s_s, TYPE ## _scalar, TYPE ## _scalar, TYPE ## _array, TYPE ## _array, concat) \
   DEFNDCATOP_FN (TYPE ## _s_m, TYPE ## _scalar, TYPE ## _matrix, TYPE ## _array, TYPE ## _array, concat) \
--- a/src/OPERATORS/op-s-scm.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/OPERATORS/op-s-scm.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -125,7 +125,7 @@
   CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_complex_matrix&);
   SparseMatrix tmp (1, 1, v1.scalar_value ());
   return octave_value
-    (tmp. concat (v2.sparse_complex_matrix_value (), ra_idx));
+    (tmp.concat (v2.sparse_complex_matrix_value (), ra_idx));
 }
 
 DEFCONV (sparse_complex_matrix_conv, scalar, sparse_complex_matrix)
--- a/src/OPERATORS/op-s-sm.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/OPERATORS/op-s-sm.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -117,7 +117,7 @@
 {
   CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_matrix&);
   SparseMatrix tmp (1, 1, v1.scalar_value ());
-  return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
+  return octave_value (tmp.concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCONV (sparse_matrix_conv, scalar, sparse_matrix)
--- a/src/OPERATORS/op-str-m.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/OPERATORS/op-str-m.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -47,29 +47,9 @@
   return octave_value ();
 }
 
-DEFCATOP (str_m, char_matrix_str, matrix)
-{
-  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_matrix&);
-
-  if (Vwarn_num_to_str)
-    gripe_implicit_conversion (v2.type_name (), v1.type_name ());
-
-  return octave_value (v1.char_array_value (). concat (v2.array_value (), 
-						       ra_idx),
-		       true, a1.is_sq_string () ? '\'' : '"');
-}
+DEFNDCHARCATOP_FN (str_m, char_matrix_str, matrix, concat)
 
-DEFCATOP (m_str, matrix, char_matrix_str)
-{
-  CAST_BINOP_ARGS (octave_matrix&, const octave_char_matrix_str&);
-
-  if (Vwarn_num_to_str)
-    gripe_implicit_conversion (v1.type_name (), v2.type_name ());
-
-  return octave_value (v1.array_value (). concat (v2.char_array_value (), 
-						  ra_idx),
-		       true, a2.is_sq_string () ? '\'' : '"');
-}
+DEFNDCHARCATOP_FN (m_str, matrix, char_matrix_str, concat)
 
 void
 install_str_m_ops (void)
--- a/src/OPERATORS/op-str-s.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/OPERATORS/op-str-s.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -47,29 +47,9 @@
   return octave_value ();
 }
 
-DEFCATOP (str_s, char_matrix_str, scalar)
-{
-  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_scalar&);
-
-  if (Vwarn_num_to_str)
-    gripe_implicit_conversion (v2.type_name (), v1.type_name ());
-
-  return octave_value (v1.char_array_value (). concat (v2.array_value (),
-						       ra_idx),
-		       true, a1.is_sq_string () ? '\'' : '"');
-}
+DEFNDCHARCATOP_FN (str_s, char_matrix_str, scalar, concat)
 
-DEFCATOP (s_str, scalar, char_matrix_str)
-{
-  CAST_BINOP_ARGS (octave_scalar&, const octave_char_matrix_str&);
-
-  if (Vwarn_num_to_str)
-    gripe_implicit_conversion (v1.type_name (), v2.type_name ());
-
-  return octave_value (v1.array_value (). concat (v2.char_array_value (), 
-						  ra_idx),
-		       true, a2.is_sq_string () ? '\'' : '"');
-}
+DEFNDCHARCATOP_FN (s_str, scalar, char_matrix_str, concat)
 
 void
 install_str_s_ops (void)
--- a/src/OPERATORS/op-str-str.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/OPERATORS/op-str-str.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -115,15 +115,7 @@
   return octave_value ();
 }
 
-DEFCATOP (str_str, char_matrix_str, char_matrix_str)
-{
-  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_char_matrix_str&);
-  return octave_value (v1.char_array_value (). concat (v2.char_array_value (), 
-						       ra_idx),
-		       true,
-		       (a1.is_sq_string () && a2.is_sq_string ()
-			? '\'' : '"'));
-}
+DEFNDCHARCATOP_FN (str_str, char_matrix_str, char_matrix_str, concat)
 
 void
 install_str_str_ops (void)
--- a/src/data.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/data.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -731,34 +731,25 @@
 	  //   tmp = octave_value_typeinfo::lookup_type (args(1).type_name());
 	  // and then directly resize. However, for some types there might be
 	  // some additional setup needed, and so this should be avoided.
+
 	  octave_value tmp;
-          bool any_strings = false;
-          bool all_strings = true;
-	  bool first_non_empty_arg = true;
+
           for (int i = 1; i < n_args; i++)
-	    if (! args (i).all_zero_dims ())
-	      {
-		if (first_non_empty_arg)
-		  {
-		    first_non_empty_arg = false;
-		    tmp = args (i);
-		  }
+	    {
+	      if (! args (i).all_zero_dims ())
+		{
+		  tmp = args (i);
+		  break;
+		}
+	    }
 
-		if (args(i).is_string ())
-		  any_strings = true;
-		else
-		  all_strings = false;
-	      }
-
-	  if (all_strings)
-	    tmp = octave_value (charNDArray (dv, Vstring_fill_char), true);
-	  else
-	    tmp = tmp.resize (dim_vector (0,0)).resize (dv);
+	  tmp = tmp.resize (dim_vector (0,0)).resize (dv);
 
 	  if (error_state)
 	    return retval;
 
 	  Array<int> ra_idx (dv.length (), 0);
+
 	  for (int i = 1; i < n_args; i++)
 	    {
 	      tmp = do_cat_op (tmp, args (i), ra_idx);
@@ -767,15 +758,14 @@
 		return retval;
 
 	      dim_vector dv_tmp = args (i).dims ();
+
 	      ra_idx (dim) += (dim < dv_tmp.length () ? dv_tmp (dim) : 1);
 	    }
 
-          if (any_strings && !all_strings)
-            retval = tmp.convert_to_str ();
-          else
-	    retval = tmp;
+	  retval = tmp;
 	}
-      else print_usage (fname);
+      else
+	error ("%s: invalid dimension argument", fname.c_str ());
     }
   else
     print_usage (fname);
--- a/src/ops.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ops.h	Thu Nov 10 21:40:49 2005 +0000
@@ -334,14 +334,24 @@
   CATOPDECL (name, a1, a2) \
   { \
     CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \
-    return octave_value (v1.t1 ## _value (). f (v2.t2 ## _value (), ra_idx)); \
+    return octave_value (v1.t1 ## _value () . f (v2.t2 ## _value (), ra_idx)); \
   }
 
 #define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
   CATOPDECL (name, a1, a2) \
   { \
     CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \
-    return octave_value (v1.e1 ## _value (). f (v2.e2 ## _value (), ra_idx)); \
+    return octave_value (v1.e1 ## _value () . f (v2.e2 ## _value (), ra_idx)); \
+  }
+
+#define DEFNDCHARCATOP_FN(name, t1, t2, f) \
+  CATOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \
+ \
+    return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
+			 true, ((a1.is_sq_string () || a2.is_sq_string ()) \
+				? '\'' : '"')); \
   }
 
 // For compatibility, the second arg is always converted to the type
--- a/src/ov-bool-mat.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ov-bool-mat.h	Thu Nov 10 21:40:49 2005 +0000
@@ -84,6 +84,30 @@
 
   bool valid_as_scalar_index (void) const;
 
+  int8NDArray
+  int8_array_value (void) const { return int8NDArray (matrix); }
+
+  int16NDArray
+  int16_array_value (void) const { return int16NDArray (matrix); }
+
+  int32NDArray
+  int32_array_value (void) const { return int32NDArray (matrix); }
+
+  int64NDArray
+  int64_array_value (void) const { return int64NDArray (matrix); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return uint8NDArray (matrix); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return uint16NDArray (matrix); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return uint32NDArray (matrix); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return uint64NDArray (matrix); }
+
   double double_value (bool = false) const;
 
   double scalar_value (bool frc_str_conv = false) const
@@ -103,6 +127,19 @@
   ComplexNDArray complex_array_value (bool = false) const
     { return ComplexNDArray (matrix); }
 
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dims ());
+
+    octave_idx_type nel = numel ();
+  
+    for (octave_idx_type i = 0; i < nel; i++)
+      retval(i) = static_cast<char>(matrix(i));
+
+    return retval;
+  }
+
   boolMatrix bool_matrix_value (void) const
     { return matrix.matrix_value (); }
 
--- a/src/ov-bool.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ov-bool.h	Thu Nov 10 21:40:49 2005 +0000
@@ -83,6 +83,38 @@
 
   bool is_true (void) const { return scalar; }
 
+  int8NDArray
+  int8_array_value (void) const
+    { return int8NDArray (dim_vector (1, 1), scalar); }
+
+  int16NDArray
+  int16_array_value (void) const
+    { return int16NDArray (dim_vector (1, 1), scalar); }
+
+  int32NDArray
+  int32_array_value (void) const
+    { return int32NDArray (dim_vector (1, 1), scalar); }
+
+  int64NDArray
+  int64_array_value (void) const
+    { return int64NDArray (dim_vector (1, 1), scalar); }
+
+  uint8NDArray
+  uint8_array_value (void) const
+    { return uint8NDArray (dim_vector (1, 1), scalar); }
+
+  uint16NDArray
+  uint16_array_value (void) const
+    { return uint16NDArray (dim_vector (1, 1), scalar); }
+
+  uint32NDArray
+  uint32_array_value (void) const
+    { return uint32NDArray (dim_vector (1, 1), scalar); }
+
+  uint64NDArray
+  uint64_array_value (void) const
+    { return uint64NDArray (dim_vector (1, 1), scalar); }
+
   double double_value (bool = false) const { return scalar; }
 
   double scalar_value (bool = false) const { return scalar; }
@@ -101,6 +133,14 @@
   ComplexNDArray complex_array_value (bool = false) const
     { return ComplexNDArray (dim_vector (1, 1), Complex (scalar)); }
 
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dim_vector (1, 1));
+    retval(0) = static_cast<char> (scalar);
+    return retval;
+  }
+
   bool bool_value (void) const { return scalar; }
 
   boolMatrix bool_matrix_value (void) const
--- a/src/ov-intx.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ov-intx.h	Thu Nov 10 21:40:49 2005 +0000
@@ -58,9 +58,29 @@
   octave_value *empty_clone (void) const
     { return new OCTAVE_VALUE_INT_MATRIX_T (); }
 
-  OCTAVE_INT_NDARRAY_T
-  OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION (void) const
-    { return matrix; }
+  int8NDArray
+  int8_array_value (void) const { return int8NDArray (matrix); }
+
+  int16NDArray
+  int16_array_value (void) const { return int16NDArray (matrix); }
+
+  int32NDArray
+  int32_array_value (void) const { return int32NDArray (matrix); }
+
+  int64NDArray
+  int64_array_value (void) const { return int64NDArray (matrix); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return uint8NDArray (matrix); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return uint16NDArray (matrix); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return uint32NDArray (matrix); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return uint64NDArray (matrix); }
 
   double
   double_value (bool = false) const
@@ -104,6 +124,19 @@
       return retval;
     }
 
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dims ());
+
+    octave_idx_type nel = numel ();
+  
+    for (octave_idx_type i = 0; i < nel; i++)
+      retval(i) = static_cast<char>(matrix(i));
+
+    return retval;
+  }
+
   idx_vector index_vector (void) const { return idx_vector (matrix); }
 
   int write (octave_stream& os, int block_size,
@@ -166,13 +199,61 @@
       return retval;
     }
 
-  OCTAVE_INT_T
-  OCTAVE_VALUE_INT_SCALAR_EXTRACTOR_FUNCTION (void) const
-    { return scalar; }
+  octave_int8
+  int8_scalar_value (void) const { return octave_int8 (scalar); }
+
+  octave_int16
+  int16_scalar_value (void) const { return octave_int16 (scalar); }
+
+  octave_int32
+  int32_scalar_value (void) const { return octave_int32 (scalar); }
+
+  octave_int64
+  int64_scalar_value (void) const { return octave_int64 (scalar); }
+
+  octave_uint8
+  uint8_scalar_value (void) const { return octave_uint8 (scalar); }
+
+  octave_uint16
+  uint16_scalar_value (void) const { return octave_uint16 (scalar); }
+
+  octave_uint32
+  uint32_scalar_value (void) const { return octave_uint32 (scalar); }
+
+  octave_uint64
+  uint64_scalar_value (void) const { return octave_uint64 (scalar); }
+
+  int8NDArray
+  int8_array_value (void) const
+    { return int8NDArray (dim_vector (1, 1), scalar); }
 
-  OCTAVE_INT_NDARRAY_T
-  OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION (void) const
-    { return OCTAVE_INT_NDARRAY_T (dim_vector (1, 1), scalar); }
+  int16NDArray
+  int16_array_value (void) const
+    { return int16NDArray (dim_vector (1, 1), scalar); }
+
+  int32NDArray
+  int32_array_value (void) const
+    { return int32NDArray (dim_vector (1, 1), scalar); }
+
+  int64NDArray
+  int64_array_value (void) const
+    { return int64NDArray (dim_vector (1, 1), scalar); }
+
+  uint8NDArray
+  uint8_array_value (void) const
+    { return uint8NDArray (dim_vector (1, 1), scalar); }
+
+  uint16NDArray
+  uint16_array_value (void) const
+    { return uint16NDArray (dim_vector (1, 1), scalar); }
+
+  uint32NDArray
+  uint32_array_value (void) const
+    { return uint32NDArray (dim_vector (1, 1), scalar); }
+
+  uint64NDArray
+  uint64_array_value (void) const
+    { return uint64NDArray (dim_vector (1, 1), scalar); }
 
   octave_value resize (const dim_vector& dv) const
     {
@@ -189,7 +270,7 @@
   NDArray
   array_value (bool = false) const
     { 
-      NDArray retval (dim_vector (1,1)); 
+      NDArray retval (dim_vector (1, 1)); 
       retval(0) = double (scalar);
       return retval;
     }
@@ -197,11 +278,19 @@
   ComplexNDArray
   complex_array_value (bool = false) const
     { 
-      ComplexNDArray retval (dim_vector (1,1)); 
+      ComplexNDArray retval (dim_vector (1, 1));
       retval(0) = Complex (double (scalar));
       return retval;
     }
 
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dim_vector (1, 1));
+    retval(0) = static_cast<char>(scalar);
+    return retval;
+  }
+
   idx_vector index_vector (void) const { return idx_vector (scalar); }
 
   int write (octave_stream& os, int block_size,
--- a/src/ov-re-mat.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ov-re-mat.h	Thu Nov 10 21:40:49 2005 +0000
@@ -91,6 +91,30 @@
 
   bool valid_as_scalar_index (void) const;
 
+  int8NDArray
+  int8_array_value (void) const { return int8NDArray (matrix); }
+
+  int16NDArray
+  int16_array_value (void) const { return int16NDArray (matrix); }
+
+  int32NDArray
+  int32_array_value (void) const { return int32NDArray (matrix); }
+
+  int64NDArray
+  int64_array_value (void) const { return int64NDArray (matrix); }
+
+  uint8NDArray
+  uint8_array_value (void) const { return uint8NDArray (matrix); }
+
+  uint16NDArray
+  uint16_array_value (void) const { return uint16NDArray (matrix); }
+
+  uint32NDArray
+  uint32_array_value (void) const { return uint32NDArray (matrix); }
+
+  uint64NDArray
+  uint64_array_value (void) const { return uint64NDArray (matrix); }
+
   double double_value (bool = false) const;
 
   double scalar_value (bool frc_str_conv = false) const
--- a/src/ov-scalar.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ov-scalar.h	Thu Nov 10 21:40:49 2005 +0000
@@ -96,6 +96,38 @@
 	      && NINTbig (scalar) == 0);
     }
 
+  int8NDArray
+  int8_array_value (void) const
+    { return int8NDArray (dim_vector (1, 1), scalar); }
+
+  int16NDArray
+  int16_array_value (void) const
+    { return int16NDArray (dim_vector (1, 1), scalar); }
+
+  int32NDArray
+  int32_array_value (void) const
+    { return int32NDArray (dim_vector (1, 1), scalar); }
+
+  int64NDArray
+  int64_array_value (void) const
+    { return int64NDArray (dim_vector (1, 1), scalar); }
+
+  uint8NDArray
+  uint8_array_value (void) const
+    { return uint8NDArray (dim_vector (1, 1), scalar); }
+
+  uint16NDArray
+  uint16_array_value (void) const
+    { return uint16NDArray (dim_vector (1, 1), scalar); }
+
+  uint32NDArray
+  uint32_array_value (void) const
+    { return uint32NDArray (dim_vector (1, 1), scalar); }
+
+  uint64NDArray
+  uint64_array_value (void) const
+    { return uint64NDArray (dim_vector (1, 1), scalar); }
+
   double double_value (bool = false) const { return scalar; }
 
   double scalar_value (bool = false) const { return scalar; }
@@ -124,6 +156,19 @@
   ComplexNDArray complex_array_value (bool = false) const
     { return ComplexNDArray (dim_vector (1, 1), Complex (scalar)); }
 
+  charNDArray
+  char_array_value (bool = false) const
+  {
+    charNDArray retval (dim_vector (1, 1));
+    retval(0) = static_cast<char> (scalar);
+    return retval;
+  }
+
+  bool bool_value (void) const { return scalar; }
+
+  boolNDArray bool_array_value (void) const
+    { return boolNDArray (dim_vector (1, 1), scalar); }
+
   std::streamoff streamoff_value (void) const;
 
   streamoff_array streamoff_array_value (void) const;
--- a/src/ov-str-mat.h	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/ov-str-mat.h	Thu Nov 10 21:40:49 2005 +0000
@@ -93,6 +93,16 @@
   octave_value reshape (const dim_vector& new_dims) const
     { return octave_value (charNDArray (matrix.reshape (new_dims)), true); }
 
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return octave_value (charNDArray (matrix.permute (vec, inv)), true); }
+
+  octave_value resize (const dim_vector& dv) const
+    {
+      charNDArray retval (matrix);
+      retval.resize (dv);
+      return octave_value (retval, true);
+    }
+
   bool is_string (void) const { return true; }
 
   bool is_real_type (void) const { return false; }
@@ -195,6 +205,19 @@
   octave_value *clone (void) const { return new octave_char_matrix_sq_str (*this); }
   octave_value *empty_clone (void) const { return new octave_char_matrix_sq_str (); }
 
+  octave_value reshape (const dim_vector& new_dims) const
+    { return octave_value (charNDArray (matrix.reshape (new_dims)), true, '\''); }
+
+  octave_value permute (const Array<int>& vec, bool inv = false) const
+    { return octave_value (charNDArray (matrix.permute (vec, inv)), true, '\''); }
+
+  octave_value resize (const dim_vector& dv) const
+    {
+      charNDArray retval (matrix);
+      retval.resize (dv);
+      return octave_value (retval, true, '\'');
+    }
+
   bool is_sq_string (void) const { return true; }
 
   octave_value do_index_op (const octave_value_list& idx, int resize_ok)
--- a/src/pt-mat.cc	Mon Nov 07 20:15:39 2005 +0000
+++ b/src/pt-mat.cc	Thu Nov 10 21:40:49 2005 +0000
@@ -70,12 +70,15 @@
       : count (1), dv (0, 0), all_str (false),
 	all_sq_str (false), all_dq_str (false),
 	some_str (false), all_real (false), all_cmplx (false),
-	all_mt (true), ok (false) { }
+	all_mt (true), class_nm (octave_base_value::static_class_name ()),
+	ok (false)
+    { }
 
     tm_row_const_rep (const tree_argument_list& row)
       : count (1), dv (0, 0), all_str (false), all_sq_str (false),
 	some_str (false), all_real (false), all_cmplx (false),
-	all_mt (true), ok (false)
+	all_mt (true), class_nm (octave_base_value::static_class_name ()),
+	ok (false)
     { init (row); }
 
     ~tm_row_const_rep (void) { }
@@ -92,6 +95,8 @@
     bool all_cmplx;
     bool all_mt;
 
+    std::string class_nm;
+
     bool ok;
 
     bool do_init_element (tree_expression *, const octave_value&, bool&);
@@ -163,6 +168,8 @@
   bool all_complex_p (void) const { return rep->all_cmplx; }
   bool all_empty_p (void) const { return rep->all_mt; }
 
+  std::string class_name (void) const { return rep->class_nm; }
+
   operator bool () const { return (rep && rep->ok); }
 
   iterator begin (void) { return rep->begin (); }
@@ -176,6 +183,69 @@
   tm_row_const_rep *rep;
 };
 
+static std::string
+get_concat_class (const std::string& c1, const std::string& c2)
+{
+  std::string retval = octave_base_value::static_class_name ();
+
+  if (c1 == c2)
+    retval = c1;
+  else
+    {
+      bool c1_is_int = (c1 == "int8" || c1 == "uint8"
+			|| c1 == "int16" || c1 == "uint16"
+			|| c1 == "int32" || c1 == "uint32"
+			|| c1 == "int64" || c1 == "uint64");
+      bool c2_is_int = (c2 == "int8" || c2 == "uint8"
+			|| c2 == "int16" || c2 == "uint16"
+			|| c2 == "int32" || c2 == "uint32"
+			|| c2 == "int64" || c2 == "uint64");
+
+      bool c1_is_char = (c1 == "char");
+      bool c2_is_char = (c2 == "char");
+
+      bool c1_is_double = (c1 == "double");
+      bool c2_is_double = (c2 == "double");
+
+      bool c1_is_single = (c1 == "single");
+      bool c2_is_single = (c2 == "single");
+
+      bool c1_is_logical = (c1 == "logical");
+      bool c2_is_logical = (c2 == "logical");
+
+      bool c1_is_built_in_type
+	= (c1_is_int || c1_is_char || c1_is_double || c1_is_single
+	   || c1_is_logical);
+
+      bool c2_is_built_in_type
+	= (c2_is_int || c2_is_char ||  c2_is_double || c2_is_single
+	   || c2_is_logical);
+
+      // Order is important here...
+
+      if (c1_is_char && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_char && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_int && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_int && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_single && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_single && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_double && c2_is_built_in_type)
+	retval = c1;
+      else if (c2_is_double && c1_is_built_in_type)
+	retval = c2;
+      else if (c1_is_logical && c2_is_logical)
+	retval = c1;
+    }
+
+  return retval;    
+}
+
 bool
 tm_row_const::tm_row_const_rep::do_init_element (tree_expression *elt,
 						 const octave_value& val,
@@ -184,6 +254,8 @@
   octave_idx_type this_elt_nr = val.rows ();
   octave_idx_type this_elt_nc = val.columns ();
 
+  std::string this_elt_class_nm = val.class_name ();
+
   dim_vector this_elt_dv = val.dims ();
 
   if (! this_elt_dv.all_zero ())
@@ -194,6 +266,8 @@
 	{
 	  first_elem = false;
 
+	  class_nm = this_elt_class_nm;
+
 	  dv.resize (this_elt_dv.length ());
 	  for (int i = 2; i < dv.length (); i++)
 	    dv.elem (i) = this_elt_dv.elem (i);
@@ -204,6 +278,8 @@
 	}
       else
 	{
+	  class_nm = get_concat_class (class_nm, this_elt_class_nm);
+
 	  int len = (this_elt_dv.length () < dv.length ()
 		     ? this_elt_dv.length () : dv.length ());
 
@@ -356,8 +432,9 @@
   tm_const (const tree_matrix& tm)
     : dv (0, 0), all_str (false), all_sq_str (false), all_dq_str (false),
       some_str (false), all_real (false), all_cmplx (false),
-      all_mt (true), ok (false)
-      { init (tm); }
+      all_mt (true), class_nm (octave_base_value::static_class_name ()),
+      ok (false)
+  { init (tm); }
 
   ~tm_const (void) { }
 
@@ -374,6 +451,8 @@
   bool all_complex_p (void) const { return all_cmplx; }
   bool all_empty_p (void) const { return all_mt; }
 
+  std::string class_name (void) const { return class_nm; }
+
   operator bool () const { return ok; }
 
 private:
@@ -388,6 +467,8 @@
   bool all_cmplx;
   bool all_mt;
 
+  std::string class_nm;
+
   bool ok;
 
   tm_const (void);
@@ -463,6 +544,8 @@
 	  octave_idx_type this_elt_nr = elt.rows ();
 	  octave_idx_type this_elt_nc = elt.cols ();
 
+	  std::string this_elt_class_nm = elt.class_name ();
+
 	  dim_vector this_elt_dv = elt.dims ();
 
 	  if (!this_elt_dv.all_zero ())
@@ -473,6 +556,8 @@
 		{
 		  first_elem = false;
 
+		  class_nm = this_elt_class_nm;
+
 		  dv.resize (this_elt_dv.length ());
 		  for (int i = 2; i < dv.length (); i++)
 		    dv.elem (i) = this_elt_dv.elem (i);
@@ -483,11 +568,15 @@
 		}
 	      else if (all_str)
 		{
+		  class_nm = get_concat_class (class_nm, this_elt_class_nm);
+
 		  if (this_elt_nc > cols ())
 		    dv.elem (1) = this_elt_nc;
 		}
 	      else
 		{
+		  class_nm = get_concat_class (class_nm, this_elt_class_nm);
+
 		  bool get_out = false;
 		  int len = (this_elt_dv.length () < dv.length ()
 			     ? this_elt_dv.length () : dv.length ());
@@ -643,6 +732,17 @@
     } \
  while (0)
 
+#define DO_SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR) \
+  do \
+    { \
+      TYPE result (dv); \
+ \
+      SINGLE_TYPE_CONCAT(TYPE, EXTRACTOR); \
+ \
+      retval = result; \
+    } \
+  while (0)
+
 octave_value
 tree_matrix::rvalue (void)
 {
@@ -671,7 +771,19 @@
 
       // Try to speed up the common cases.
 
-      if (all_strings_p)
+      std::string result_type = tmp.class_name ();
+
+      if (result_type == "double")
+	{
+	  if (all_real_p)
+	    DO_SINGLE_TYPE_CONCAT (NDArray, array_value);
+	  else
+	    DO_SINGLE_TYPE_CONCAT (ComplexNDArray, complex_array_value);
+	}
+#if 0
+      else if (result_type == "single")
+#endif
+      else if (result_type == "char")
 	{
 	  char type = all_sq_strings_p ? '\'' : '"';
 
@@ -683,22 +795,24 @@
 
 	  retval = octave_value (result, true, type);
 	}
-      else if (all_real_p)
-	{
-	  NDArray result (dv);
-
-	  SINGLE_TYPE_CONCAT (NDArray, array_value);
-
-	  retval = result;
-	}
-      else if (all_complex_p)
-	{
-	  ComplexNDArray result (dv);
-
-	  SINGLE_TYPE_CONCAT (ComplexNDArray, complex_array_value);
-
-	  retval = result;
-	}
+      else if (result_type == "logical")
+	DO_SINGLE_TYPE_CONCAT (boolNDArray, bool_array_value);
+      else if (result_type == "int8")
+	DO_SINGLE_TYPE_CONCAT (int8NDArray, int8_array_value);
+      else if (result_type == "int16")
+	DO_SINGLE_TYPE_CONCAT (int16NDArray, int16_array_value);
+      else if (result_type == "int32")
+	DO_SINGLE_TYPE_CONCAT (int32NDArray, int32_array_value);
+      else if (result_type == "int64")
+	DO_SINGLE_TYPE_CONCAT (int64NDArray, int64_array_value);
+      else if (result_type == "uint8")
+	DO_SINGLE_TYPE_CONCAT (uint8NDArray, uint8_array_value);
+      else if (result_type == "uint16")
+	DO_SINGLE_TYPE_CONCAT (uint16NDArray, uint16_array_value);
+      else if (result_type == "uint32")
+	DO_SINGLE_TYPE_CONCAT (uint32NDArray, uint32_array_value);
+      else if (result_type == "uint64")
+	DO_SINGLE_TYPE_CONCAT (uint64NDArray, uint64_array_value);
       else
 	{
 	  // The line below might seem crazy, since we take a copy of