00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if !defined (octave_DiagArray2_h)
00025 #define octave_DiagArray2_h 1
00026
00027 #if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
00028 #pragma interface
00029 #endif
00030
00031 #include <cassert>
00032 #include <cstdlib>
00033
00034 #include "Array.h"
00035 #include "lo-error.h"
00036
00037 class idx_vector;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 template <class T>
00053 class
00054 DiagArray2 : public Array<T>
00055 {
00056 private:
00057
00058 T get (int i) { return Array<T>::xelem (i); }
00059
00060 void set (const T& val, int i) { Array<T>::xelem (i) = val; }
00061
00062 class Proxy
00063 {
00064 public:
00065
00066 Proxy (DiagArray2<T> *ref, int r, int c)
00067 : i (r), j (c), object (ref) { }
00068
00069 const Proxy& operator = (const T& val) const
00070 {
00071 if (i == j)
00072 {
00073 if (object)
00074 object->set (val, i);
00075 }
00076 else
00077 (*current_liboctave_error_handler)
00078 ("invalid assignment to off-diagonal in diagonal array");
00079
00080 return *this;
00081 }
00082
00083 operator T () const
00084 {
00085 if (object && i == j)
00086 return object->get (i);
00087 else
00088 {
00089 static T foo (0);
00090 return foo;
00091 }
00092 }
00093
00094 private:
00095
00096
00097
00098
00099
00100 T *operator& () const { assert (0); return (T *) 0; }
00101
00102 int i;
00103 int j;
00104
00105 DiagArray2<T> *object;
00106
00107 };
00108
00109 friend class Proxy;
00110
00111 protected:
00112
00113 DiagArray2 (T *d, int r, int c) : Array<T> (d, r < c ? r : c)
00114 { Array<T>::dimensions = dim_vector (r, c); }
00115
00116 public:
00117
00118 DiagArray2 (void) : Array<T> (dim_vector (0, 0)) { }
00119
00120 DiagArray2 (int r, int c) : Array<T> (r < c ? r : c)
00121 { this->dimensions = dim_vector (r, c); }
00122
00123 DiagArray2 (int r, int c, const T& val) : Array<T> (r < c ? r : c)
00124 {
00125 this->dimensions = dim_vector (r, c);
00126
00127 fill (val);
00128 }
00129
00130 DiagArray2 (const Array<T>& a) : Array<T> (a)
00131 { this->dimensions = dim_vector (a.length (), a.length ()); }
00132
00133 DiagArray2 (const DiagArray2<T>& a) : Array<T> (a)
00134 { this->dimensions = a.dims (); }
00135
00136 ~DiagArray2 (void) { }
00137
00138 DiagArray2<T>& operator = (const DiagArray2<T>& a)
00139 {
00140 if (this != &a)
00141 Array<T>::operator = (a);
00142
00143 return *this;
00144 }
00145
00146 Proxy elem (int r, int c)
00147 {
00148 return Proxy (this, r, c);
00149 }
00150
00151 Proxy checkelem (int r, int c)
00152 {
00153 if (r < 0 || c < 0 || r >= this->dim1 () || c >= this->dim2 ())
00154 {
00155 (*current_liboctave_error_handler) ("range error in DiagArray2");
00156 return Proxy (0, r, c);
00157 }
00158 else
00159 return Proxy (this, r, c);
00160 }
00161
00162 Proxy operator () (int r, int c)
00163 {
00164 if (r < 0 || c < 0 || r >= this->dim1 () || c >= this->dim2 ())
00165 {
00166 (*current_liboctave_error_handler) ("range error in DiagArray2");
00167 return Proxy (0, r, c);
00168 }
00169 else
00170 return Proxy (this, r, c);
00171 }
00172
00173 T elem (int r, int c) const;
00174 T checkelem (int r, int c) const;
00175 T operator () (int r, int c) const;
00176
00177
00178
00179 T& xelem (int r, int c);
00180 T xelem (int r, int c) const;
00181
00182 void resize (int n, int m);
00183 void resize (int n, int m, const T& val);
00184
00185 void maybe_delete_elements (idx_vector& i, idx_vector& j);
00186 };
00187
00188 #endif
00189
00190
00191
00192
00193
00194