changeset 3573:6ae6f1180e62

[project @ 2000-02-04 09:01:59 by jwe]
author jwe
date Fri, 04 Feb 2000 09:02:04 +0000
parents 8d641545e006
children 787bb9d8f60e
files liboctave/CColVector.cc liboctave/CColVector.h liboctave/CMatrix.h liboctave/CRowVector.cc liboctave/CRowVector.h liboctave/ChangeLog liboctave/MArray-defs.h liboctave/MArray.cc liboctave/MArray.h liboctave/MArray2.h liboctave/dColVector.h liboctave/dMatrix.cc liboctave/dMatrix.h liboctave/dRowVector.h
diffstat 14 files changed, 235 insertions(+), 264 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/CColVector.cc	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/CColVector.cc	Fri Feb 04 09:02:04 2000 +0000
@@ -270,50 +270,6 @@
   return *this;
 }
 
-ComplexColumnVector&
-ComplexColumnVector::operator += (const ComplexColumnVector& a)
-{
-  int len = length ();
-
-  int a_len = a.length ();
-
-  if (len != a_len)
-    {
-      gripe_nonconformant ("operator +=", len, a_len);
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
-
-  add2 (d, a.data (), len);
-  return *this;
-}
-
-ComplexColumnVector&
-ComplexColumnVector::operator -= (const ComplexColumnVector& a)
-{
-  int len = length ();
-
-  int a_len = a.length ();
-
-  if (len != a_len)
-    {
-      gripe_nonconformant ("operator -=", len, a_len);
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
-
-  subtract2 (d, a.data (), len);
-  return *this;
-}
-
 // column vector by scalar -> column vector operations
 
 ComplexColumnVector
--- a/liboctave/CColVector.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/CColVector.h	Fri Feb 04 09:02:04 2000 +0000
@@ -81,9 +81,6 @@
   ComplexColumnVector& operator += (const ColumnVector& a);
   ComplexColumnVector& operator -= (const ColumnVector& a);
 
-  ComplexColumnVector& operator += (const ComplexColumnVector& a);
-  ComplexColumnVector& operator -= (const ComplexColumnVector& a);
-
   // column vector by scalar -> column vector operations
 
   friend ComplexColumnVector operator + (const ComplexColumnVector& a,
@@ -190,6 +187,8 @@
   ComplexColumnVector (Complex *d, int l) : MArray<Complex> (d, l) { }
 };
 
+MARRAY_FORWARD_DEFS (MArray, ComplexColumnVector, Complex)
+
 #endif
 
 /*
--- a/liboctave/CMatrix.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/CMatrix.h	Fri Feb 04 09:02:04 2000 +0000
@@ -271,6 +271,8 @@
 MM_CMP_OP_DECLS (ComplexMatrix, ComplexMatrix)
 MM_BOOL_OP_DECLS (ComplexMatrix, ComplexMatrix)
 
+MARRAY_FORWARD_DEFS (MArray2, ComplexMatrix, Complex)
+
 #endif
 
 /*
--- a/liboctave/CRowVector.cc	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/CRowVector.cc	Fri Feb 04 09:02:04 2000 +0000
@@ -270,50 +270,6 @@
   return *this;
 }
 
-ComplexRowVector&
-ComplexRowVector::operator += (const ComplexRowVector& a)
-{
-  int len = length ();
-
-  int a_len = a.length ();
-
-  if (len != a_len)
-    {
-      gripe_nonconformant ("operator +=", len, a_len);
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
-
-  add2 (d, a.data (), len);
-  return *this;
-}
-
-ComplexRowVector&
-ComplexRowVector::operator -= (const ComplexRowVector& a)
-{
-  int len = length ();
-
-  int a_len = a.length ();
-
-  if (len != a_len)
-    {
-      gripe_nonconformant ("operator -=", len, a_len);
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
-
-  subtract2 (d, a.data (), len);
-  return *this;
-}
-
 // row vector by scalar -> row vector operations
 
 ComplexRowVector
--- a/liboctave/CRowVector.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/CRowVector.h	Fri Feb 04 09:02:04 2000 +0000
@@ -80,9 +80,6 @@
   ComplexRowVector& operator += (const RowVector& a);
   ComplexRowVector& operator -= (const RowVector& a);
 
-  ComplexRowVector& operator += (const ComplexRowVector& a);
-  ComplexRowVector& operator -= (const ComplexRowVector& a);
-
   // row vector by scalar -> row vector operations
 
   friend ComplexRowVector operator + (const ComplexRowVector& a, double s);
@@ -167,6 +164,8 @@
 
 ComplexRowVector linspace (const Complex& x1, const Complex& x2, int n);
 
+MARRAY_FORWARD_DEFS (MArray, ComplexRowVector, Complex)
+
 #endif
 
 /*
--- a/liboctave/ChangeLog	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/ChangeLog	Fri Feb 04 09:02:04 2000 +0000
@@ -1,3 +1,8 @@
+2000-02-04  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* dColVector.h, dRowVector.h, CColVector.h, CRowVector.h:
+	Use MARRAY_FORWARD_DEFS here.
+
 2000-02-03  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* dMatrix.cc (Matrix::ifourier): Cast divisor to double.
--- a/liboctave/MArray-defs.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/MArray-defs.h	Fri Feb 04 09:02:04 2000 +0000
@@ -49,3 +49,193 @@
     } \
   while (0)
 
+// A macro that can be used to declare and instantiate OP= operators.
+#define MARRAY_OP_ASSIGN_DECL(A_T, E_T, OP, PFX, LTGT, RHS_T) \
+  PFX A_T<E_T>& \
+  operator OP LTGT (A_T<E_T>&, const RHS_T&)
+
+// All the OP= operators that we care about.
+#define MARRAY_OP_ASSIGN_DECLS(A_T, E_T, PFX, LTGT, RHS_T) \
+  MARRAY_OP_ASSIGN_DECL (A_T, E_T, +=, PFX, LTGT, RHS_T); \
+  MARRAY_OP_ASSIGN_DECL (A_T, E_T, -=, PFX, LTGT, RHS_T);
+
+// Generate forward declarations for OP= operators.
+#define MARRAY_OP_ASSIGN_FWD_DECLS(A_T) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, T, template <typename T>, , T) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, T, template <typename T>, , A_T<T>) \
+
+// Generate friend declarations for the OP= operators.
+#define MARRAY_OP_ASSIGN_FRIENDS(A_T) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, T, friend, <>, T) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, T, friend, <>, A_T<T>)
+
+// Instantiate the OP= operators.
+#define MARRAY_OP_ASSIGN_DEFS(A_T, E_T) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, E_T, template, , T) \
+  MARRAY_OP_ASSIGN_DECLS (A_T, E_T, template, , A_T<E_T>)
+
+// A function that can be used to forward OP= operations from derived
+// classes back to us.
+#define MARRAY_OP_ASSIGN_FWD_FCN(R, F, T, C_X, X_T, C_Y, Y_T) \
+  inline R \
+  F (X_T& x, const Y_T& y) \
+  { \
+    return R (F (C_X (x), C_Y (y))); \
+  }
+
+// All the OP= operators that we care about forwarding.
+#define MARRAY_OP_ASSIGN_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_OP_ASSIGN_FWD_FCN (R, operator +=, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_OP_ASSIGN_FWD_FCN (R, operator -=, T, C_X, X_T, C_Y, Y_T)
+
+// A macro that can be used to declare and instantiate unary operators.
+#define MARRAY_UNOP(A_T, E_T, F, PFX, LTGT) \
+  PFX A_T<E_T> \
+  F LTGT (const A_T<E_T>&)
+
+// All the unary operators that we care about.
+#define MARRAY_UNOP_DECLS(A_T, E_T, PFX, LTGT) \
+  MARRAY_UNOP (A_T, E_T, operator +, PFX, LTGT); \
+  MARRAY_UNOP (A_T, E_T, operator -, PFX, LTGT);
+
+// Generate forward declarations for unary operators.
+#define MARRAY_UNOP_FWD_DECLS(A_T) \
+  MARRAY_UNOP_DECLS (A_T, T, template <typename T>, )
+
+// Generate friend declarations for the unary operators.
+#define MARRAY_UNOP_FRIENDS(A_T) \
+  MARRAY_UNOP_DECLS (A_T, T, friend, <>)
+
+// Instantiate the unary operators.
+#define MARRAY_UNOP_DEFS(A_T, E_T) \
+  MARRAY_UNOP_DECLS (A_T, E_T, template, )
+
+// A function that can be used to forward unary operations from derived
+// classes back to us.
+#define MARRAY_UNOP_FWD_FCN(R, F, T, C_X, X_T) \
+  inline R \
+  F (const X_T& x) \
+  { \
+    return R (F (C_X (x))); \
+  }
+
+// All the unary operators that we care about forwarding.
+#define MARRAY_UNOP_FWD_DEFS(R, T, C_X, X_T) \
+  MARRAY_UNOP_FWD_FCN (R, operator +, T, C_X, X_T) \
+  MARRAY_UNOP_FWD_FCN (R, operator -, T, C_X, X_T)
+
+// A macro that can be used to declare and instantiate binary operators.
+#define MARRAY_BINOP_DECL(A_T, E_T, F, PFX, LTGT, X_T, Y_T) \
+  PFX A_T<E_T> \
+  F LTGT (const X_T&, const Y_T&)
+
+// All the binary operators that we care about.  We have two
+// sets of macros since the MArray OP MArray operations use functions
+// (product and quotient) instead of operators (*, /).
+#define MARRAY_BINOP_DECLS(A_T, E_T, PFX, LTGT, X_T, Y_T) \
+  MARRAY_BINOP_DECL (A_T, E_T, operator +, PFX, LTGT, X_T, Y_T); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator -, PFX, LTGT, X_T, Y_T); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator *, PFX, LTGT, X_T, Y_T); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator /, PFX, LTGT, X_T, Y_T);
+
+#define MARRAY_AA_BINOP_DECLS(A_T, E_T, PFX, LTGT) \
+  MARRAY_BINOP_DECL (A_T, E_T, operator +, PFX, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, operator -, PFX, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, quotient,   PFX, LTGT, A_T<E_T>, A_T<E_T>); \
+  MARRAY_BINOP_DECL (A_T, E_T, product,    PFX, LTGT, A_T<E_T>, A_T<E_T>);
+
+// Generate forward declarations for binary operators.
+#define MARRAY_BINOP_FWD_DECLS(A_T) \
+  MARRAY_BINOP_DECLS (A_T, T, template <typename T>, , A_T<T>, T) \
+  MARRAY_BINOP_DECLS (A_T, T, template <typename T>, , T, A_T<T>) \
+  MARRAY_AA_BINOP_DECLS (A_T, T, template <typename T>, )
+
+// Generate friend declarations for the binary operators.
+#define MARRAY_BINOP_FRIENDS(A_T) \
+  MARRAY_BINOP_DECLS (A_T, T, friend, <>, A_T<T>, T) \
+  MARRAY_BINOP_DECLS (A_T, T, friend, <>, T, A_T<T>) \
+  MARRAY_AA_BINOP_DECLS (A_T, T, friend, <>)
+
+// Instantiate the binary operators.
+#define MARRAY_BINOP_DEFS(A_T, E_T) \
+  MARRAY_BINOP_DECLS (A_T, E_T, template, , A_T<E_T>, E_T) \
+  MARRAY_BINOP_DECLS (A_T, E_T, template, , E_T, A_T<E_T>) \
+  MARRAY_AA_BINOP_DECLS (A_T, E_T, template, )
+
+// A function that can be used to forward binary operations from derived
+// classes back to us.
+#define MARRAY_BINOP_FWD_FCN(R, F, T, C_X, X_T, C_Y, Y_T) \
+  inline R \
+  F (const X_T& x, const Y_T& y) \
+  { \
+    return R (F (C_X (x), C_Y (y))); \
+  }
+
+// The binary operators that we care about forwarding.  We have two
+// sets of macros since the MArray OP MArray operations use functions
+// (product and quotient) instead of operators (*, /).
+#define MARRAY_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator +, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator -, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator *, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator /, T, C_X, X_T, C_Y, Y_T)
+
+#define MARRAY_AA_BINOP_FWD_DEFS(R, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator +, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, operator -, T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, product,    T, C_X, X_T, C_Y, Y_T) \
+  MARRAY_BINOP_FWD_FCN (R, quotient,   T, C_X, X_T, C_Y, Y_T)
+
+// Forward declarations for the MArray operators.
+#define MARRAY_OPS_FORWARD_DECLS(A_T) \
+  template <class T> \
+  class A_T; \
+ \
+  MARRAY_OP_ASSIGN_FWD_DECLS (A_T) \
+  MARRAY_UNOP_FWD_DECLS (A_T) \
+  MARRAY_BINOP_FWD_DECLS (A_T)
+
+// Friend declarations for the MArray operators.
+#define MARRAY_OPS_FRIEND_DECLS(A_T) \
+  MARRAY_OP_ASSIGN_FRIENDS (A_T) \
+  MARRAY_UNOP_FRIENDS (A_T) \
+  MARRAY_BINOP_FRIENDS (A_T)
+
+// The following macros are for external use.
+
+// Instantiate all the MArray friends for MArray element type T.
+#define INSTANTIATE_MARRAY_FRIENDS(T) \
+  MARRAY_OP_ASSIGN_DEFS (MArray, T) \
+  MARRAY_UNOP_DEFS (MArray, T) \
+  MARRAY_BINOP_DEFS (MArray, T)
+
+// Instantiate all the MArray friends for MArray element type T.
+#define INSTANTIATE_MARRAY2_FRIENDS(T) \
+  MARRAY_OP_ASSIGN_DEFS (MArray2, T) \
+  MARRAY_UNOP_DEFS (MArray2, T) \
+  MARRAY_BINOP_DEFS (MArray2, T)
+
+// Define all the MArray forwarding functions for return type R and
+// MArray element type T
+#define MARRAY_FORWARD_DEFS(B, R, T) \
+  MARRAY_OP_ASSIGN_FWD_DEFS \
+    (R, T, dynamic_cast<B<T>&>, R, , T) \
+ \
+  MARRAY_OP_ASSIGN_FWD_DEFS \
+    (R, T, \
+     dynamic_cast<B<T>&>, R, dynamic_cast<const B<T>&>, R) \
+ \
+  MARRAY_UNOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R) \
+ \
+  MARRAY_BINOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R, , T) \
+ \
+  MARRAY_BINOP_FWD_DEFS \
+    (R, T, , T, dynamic_cast<const B<T>&>, R) \
+ \
+  MARRAY_AA_BINOP_FWD_DEFS \
+    (R, T, dynamic_cast<const B<T>&>, R, dynamic_cast<const B<T>&>, R)
+
+// Now we have all the definitions we need.
+
--- a/liboctave/MArray.cc	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/MArray.cc	Fri Feb 04 09:02:04 2000 +0000
@@ -170,6 +170,13 @@
   return result;
 }
 
+template <class T>
+MArray<T>
+operator + (const MArray<T>& a)
+{
+  return a;
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/MArray.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/MArray.h	Fri Feb 04 09:02:04 2000 +0000
@@ -30,72 +30,13 @@
 
 #include "Array.h"
 
-#if defined (LTGT)
-#undef LTGT
-#endif
-
-#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
-#define LTGT
-#else
-
-#define LTGT <>
-
-template <class T> 
-class MArray;
+// One dimensional array with math ops.
 
-template <typename T> MArray<T>& 
-operator += (MArray<T>& a, const T& s);
-
-template <typename T> MArray<T>& 
-operator -= (MArray<T>& a, const T& s);
-
-template <typename T> MArray<T>& 
-operator += (MArray<T>& a, const MArray<T>& b);
-
-template <typename T> MArray<T>& 
-operator -= (MArray<T>& a, const MArray<T>& b);
-
-template <typename T> MArray<T> 
-operator + (const MArray<T>& a, const T& s);
-
-template <typename T> MArray<T> 
-operator - (const MArray<T>& a, const T& s);
+// But first, some preprocessor abuse...
 
-template <typename T> MArray<T> 
-operator * (const MArray<T>& a, const T& s);
-
-template <typename T> MArray<T> 
-operator / (const MArray<T>& a, const T& s);
-
-template <typename T> MArray<T> 
-operator + (const T& s, const MArray<T>& a);
-
-template <typename T> MArray<T> 
-operator - (const T& s, const MArray<T>& a);
-
-template <typename T> MArray<T> 
-operator * (const T& s, const MArray<T>& a);
-
-template <typename T> MArray<T> 
-operator / (const T& s, const MArray<T>& a);
+#include "MArray-defs.h"
 
-template <typename T> MArray<T> 
-operator + (const MArray<T>& a, const MArray<T>& b);
-
-template <typename T> MArray<T> 
-operator - (const MArray<T>& a, const MArray<T>& b);
-
-template <class T> MArray<T> 
-product (const MArray<T>& a, const MArray<T>& b);
-
-template <typename T> MArray<T> 
-quotient (const MArray<T>& a, const MArray<T>& b);
-
-template <typename T> MArray<T> 
-operator - (const MArray<T>& a);
-#endif
-
-// One dimensional array with math ops.
+MARRAY_OPS_FORWARD_DECLS (MArray)
 
 template <class T>
 class MArray : public Array<T>
@@ -119,32 +60,17 @@
       Array<T>::operator = (a);
       return *this;
     }
+
+  // Currently, the OPS functions don't need to be friends, but that
+  // may change.
+
+  MARRAY_OPS_FRIEND_DECLS (MArray)
 };
 
-#undef LTGT
-
+// XXX FIXME XXX -- there must be a better place for this...
 extern void
 gripe_nonconformant (const char *op, int op1_len, int op2_len);
 
-#define INSTANTIATE_MARRAY_FRIENDS(T) \
-  template MArray<T>& operator += (MArray<T>& a, const T& s); \
-  template MArray<T>& operator -= (MArray<T>& a, const T& s); \
-  template MArray<T>& operator += (MArray<T>& a, const MArray<T>& b); \
-  template MArray<T>& operator -= (MArray<T>& a, const MArray<T>& b); \
-  template MArray<T> operator + (const MArray<T>& a, const T& s); \
-  template MArray<T> operator - (const MArray<T>& a, const T& s); \
-  template MArray<T> operator * (const MArray<T>& a, const T& s); \
-  template MArray<T> operator / (const MArray<T>& a, const T& s); \
-  template MArray<T> operator + (const T& s, const MArray<T>& a); \
-  template MArray<T> operator - (const T& s, const MArray<T>& a); \
-  template MArray<T> operator * (const T& s, const MArray<T>& a); \
-  template MArray<T> operator / (const T& s, const MArray<T>& a); \
-  template MArray<T> operator + (const MArray<T>& a, const MArray<T>& b); \
-  template MArray<T> operator - (const MArray<T>& a, const MArray<T>& b); \
-  template MArray<T> product (const MArray<T>& a, const MArray<T>& b); \
-  template MArray<T> quotient (const MArray<T>& a, const MArray<T>& b); \
-  template MArray<T> operator - (const MArray<T>& a);
-
 #endif
 
 /*
--- a/liboctave/MArray2.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/MArray2.h	Fri Feb 04 09:02:04 2000 +0000
@@ -30,72 +30,13 @@
 
 #include "Array2.h"
 
-#if defined (LTGT)
-#undef LTGT
-#endif
-
-#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
-#define LTGT
-#else
-
-#define LTGT <>
-
-template <class T>
-class MArray2;
+// Two dimensional array with math ops.
 
-template <typename T> MArray2<T>& 
-operator += (MArray2<T>& a, const T& s);
-
-template <typename T> MArray2<T>& 
-operator -= (MArray2<T>& a, const T& s);
-
-template <typename T> MArray2<T>& 
-operator += (MArray2<T>& a, const MArray2<T>& b);
-
-template <typename T> MArray2<T>& 
-operator -= (MArray2<T>& a, const MArray2<T>& b);
-
-template <typename T> MArray2<T> 
-operator + (const MArray2<T>& a, const T& s);
-
-template <typename T> MArray2<T> 
-operator - (const MArray2<T>& a, const T& s);
+// But first, some preprocessor abuse...
 
-template <typename T> MArray2<T> 
-operator * (const MArray2<T>& a, const T& s);
-
-template <typename T> MArray2<T> 
-operator / (const MArray2<T>& a, const T& s);
-
-template <typename T> MArray2<T> 
-operator + (const T& s, const MArray2<T>& a);
-
-template <typename T> MArray2<T> 
-operator - (const T& s, const MArray2<T>& a);
-
-template <typename T> MArray2<T> 
-operator * (const T& s, const MArray2<T>& a);
-
-template <typename T> MArray2<T> 
-operator / (const T& s, const MArray2<T>& a);
+#include "MArray-defs.h"
 
-template <typename T> MArray2<T> 
-operator + (const MArray2<T>& a, const MArray2<T>& b);
-
-template <typename T> MArray2<T> 
-operator - (const MArray2<T>& a, const MArray2<T>& b);
-
-template <typename T> MArray2<T> 
-product (const MArray2<T>& a, const MArray2<T>& b);
-
-template <typename T> MArray2<T> 
-quotient (const MArray2<T>& a, const MArray2<T>& b);
-
-template <typename T> MArray2<T> 
-operator - (const MArray2<T>& a);
-#endif
-
-// Two dimensional array with math ops.
+MARRAY_OPS_FORWARD_DECLS (MArray2)
 
 template <class T>
 class MArray2 : public Array2<T>
@@ -127,33 +68,17 @@
   }
 
   MArray2<T> transpose (void) const { return Array2<T>::transpose (); }
-};
 
-#undef LTGT
+  // Currently, the OPS functions don't need to be friends, but that
+  // may change.
+
+  MARRAY_OPS_FRIEND_DECLS (MArray2)
+};
 
 extern void
 gripe_nonconformant (const char *op, int op1_nr, int op1_nc,
 		     int op2_nr, int op2_nc);
 
-#define INSTANTIATE_MARRAY2_FRIENDS(T) \
-  template MArray2<T>& operator += (MArray2<T>& a, const T& s); \
-  template MArray2<T>& operator -= (MArray2<T>& a, const T& s); \
-  template MArray2<T>& operator += (MArray2<T>& a, const MArray2<T>& b); \
-  template MArray2<T>& operator -= (MArray2<T>& a, const MArray2<T>& b); \
-  template MArray2<T> operator + (const MArray2<T>& a, const T& s); \
-  template MArray2<T> operator - (const MArray2<T>& a, const T& s); \
-  template MArray2<T> operator * (const MArray2<T>& a, const T& s); \
-  template MArray2<T> operator / (const MArray2<T>& a, const T& s); \
-  template MArray2<T> operator + (const T& s, const MArray2<T>& a); \
-  template MArray2<T> operator - (const T& s, const MArray2<T>& a); \
-  template MArray2<T> operator * (const T& s, const MArray2<T>& a); \
-  template MArray2<T> operator / (const T& s, const MArray2<T>& a); \
-  template MArray2<T> operator + (const MArray2<T>& a, const MArray2<T>& b); \
-  template MArray2<T> operator - (const MArray2<T>& a, const MArray2<T>& b); \
-  template MArray2<T> product (const MArray2<T>& a, const MArray2<T>& b); \
-  template MArray2<T> quotient (const MArray2<T>& a, const MArray2<T>& b); \
-  template MArray2<T> operator - (const MArray2<T>& a);
-
 #endif
 
 /*
--- a/liboctave/dColVector.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/dColVector.h	Fri Feb 04 09:02:04 2000 +0000
@@ -100,6 +100,8 @@
   ColumnVector (double *d, int l) : MArray<double> (d, l) { }
 };
 
+MARRAY_FORWARD_DEFS (MArray, ColumnVector, double)
+
 #endif
 
 /*
--- a/liboctave/dMatrix.cc	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/dMatrix.cc	Fri Feb 04 09:02:04 2000 +0000
@@ -1462,8 +1462,8 @@
   int minus_one_j = -1;
   for (int j = 7; j >= 0; j--)
     {
-      npp = (m * npp) + (m * padec[j]);
-      dpp = (m * dpp) + (m * (minus_one_j * padec[j]));
+      npp = m * npp + padec[j] * m;
+      dpp = m * dpp + (minus_one_j * padec[j]) * m;
       minus_one_j *= -1;
     }
   
--- a/liboctave/dMatrix.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/dMatrix.h	Fri Feb 04 09:02:04 2000 +0000
@@ -248,6 +248,8 @@
 MM_CMP_OP_DECLS (Matrix, Matrix)
 MM_BOOL_OP_DECLS (Matrix, Matrix)
 
+MARRAY_FORWARD_DEFS (MArray2, Matrix, double)
+
 #endif
 
 /*
--- a/liboctave/dRowVector.h	Thu Feb 03 21:39:50 2000 +0000
+++ b/liboctave/dRowVector.h	Fri Feb 04 09:02:04 2000 +0000
@@ -106,6 +106,8 @@
 
 RowVector linspace (double x1, double x2, int n);
 
+MARRAY_FORWARD_DEFS (MArray, RowVector, double)
+
 #endif
 
 /*