comparison liboctave/operators/mx-inlines.cc @ 21139:538b57866b90

consistently use "typename" intead of "class" in template declarations * Object.h, QtHandlesUtils.cc, QtHandlesUtils.h, ToolBarButton.cc, ToolBarButton.h, Cell.h, __lin_interpn__.cc, bitfcns.cc, bsxfun.cc, cellfun.cc, data.cc, filter.cc, gcd.cc, graphics.cc, help.cc, kron.cc, lookup.cc, ls-mat5.cc, ls-oct-text.h, lu.cc, max.cc, mgorth.cc, oct-map.cc, oct-map.h, oct-stream.cc, oct-stream.h, octave-link.h, pr-output.cc, profiler.h, schur.cc, sparse-xdiv.cc, sparse-xpow.cc, sqrtm.cc, symtab.h, tril.cc, typecast.cc, variables.cc, xdiv.cc, zfstream.h, __init_fltk__.cc, __magick_read__.cc, chol.cc, qr.cc, ov-base-diag.cc, ov-base-diag.h, ov-base-int.cc, ov-base-int.h, ov-base-mat.cc, ov-base-mat.h, ov-base-scalar.cc, ov-base-scalar.h, ov-base-sparse.cc, ov-base-sparse.h, ov-base.h, ov-classdef.cc, ov-int-traits.h, ov-java.h, ov-usr-fcn.h, ov.cc, ov.h, op-dms-template.cc, oct-parse.in.yy, parse.h, pt-mat.cc, Array-b.cc, Array.cc, Array.h, CDiagMatrix.h, CMatrix.h, CNDArray.h, DiagArray2.cc, DiagArray2.h, MArray.cc, MArray.h, MDiagArray2.cc, MDiagArray2.h, MSparse.cc, MSparse.h, MatrixType.cc, Sparse.cc, Sparse.h, dDiagMatrix.h, dMatrix.h, dNDArray.h, fCDiagMatrix.h, fCMatrix.h, fCNDArray.h, fDiagMatrix.h, fMatrix.h, fNDArray.h, idx-vector.cc, idx-vector.h, intNDArray.cc, intNDArray.h, DET.h, base-aepbal.h, base-lu.cc, base-lu.h, base-qr.cc, base-qr.h, bsxfun-defs.cc, eigs-base.cc, lo-mappers.h, lo-specfun.cc, lo-specfun.h, oct-convn.cc, oct-fftw.cc, oct-norm.cc, sparse-base-chol.cc, sparse-base-chol.h, sparse-base-lu.cc, sparse-base-lu.h, sparse-dmsolve.cc, mx-inlines.cc, action-container.h, base-list.h, lo-traits.h, lo-utils.h, oct-base64.h, oct-binmap.h, oct-cmplx.h, oct-inttypes.cc, oct-inttypes.h, oct-locbuf.h, oct-refcount.h, oct-sort.cc, oct-sort.h: Use "typename" instead of "class" in template declarations.
author John W. Eaton <jwe@octave.org>
date Sun, 24 Jan 2016 13:50:04 -0500
parents 228b65504557
children 53728df3e4c9
comparison
equal deleted inserted replaced
21138:e2fca7d79169 21139:538b57866b90
40 40
41 #include "bsxfun.h" 41 #include "bsxfun.h"
42 42
43 // Provides some commonly repeated, basic loop templates. 43 // Provides some commonly repeated, basic loop templates.
44 44
45 template <class R, class S> 45 template <typename R, typename S>
46 inline void mx_inline_fill (size_t n, R *r, S s) throw () 46 inline void mx_inline_fill (size_t n, R *r, S s) throw ()
47 { for (size_t i = 0; i < n; i++) r[i] = s; } 47 { for (size_t i = 0; i < n; i++) r[i] = s; }
48 48
49 #define DEFMXUNOP(F, OP) \ 49 #define DEFMXUNOP(F, OP) \
50 template <class R, class X> \ 50 template <typename R, typename X> \
51 inline void F (size_t n, R *r, const X *x) throw () \ 51 inline void F (size_t n, R *r, const X *x) throw () \
52 { for (size_t i = 0; i < n; i++) r[i] = OP x[i]; } 52 { for (size_t i = 0; i < n; i++) r[i] = OP x[i]; }
53 53
54 DEFMXUNOP (mx_inline_uminus, -) 54 DEFMXUNOP (mx_inline_uminus, -)
55 55
56 #define DEFMXUNOPEQ(F, OP) \ 56 #define DEFMXUNOPEQ(F, OP) \
57 template <class R> \ 57 template <typename R> \
58 inline void F (size_t n, R *r) throw () \ 58 inline void F (size_t n, R *r) throw () \
59 { for (size_t i = 0; i < n; i++) r[i] = OP r[i]; } 59 { for (size_t i = 0; i < n; i++) r[i] = OP r[i]; }
60 60
61 DEFMXUNOPEQ (mx_inline_uminus2, -) 61 DEFMXUNOPEQ (mx_inline_uminus2, -)
62 62
63 #define DEFMXUNBOOLOP(F, OP) \ 63 #define DEFMXUNBOOLOP(F, OP) \
64 template <class X> \ 64 template <typename X> \
65 inline void F (size_t n, bool *r, const X *x) throw () \ 65 inline void F (size_t n, bool *r, const X *x) throw () \
66 { const X zero = X (); for (size_t i = 0; i < n; i++) r[i] = x[i] OP zero; } 66 { const X zero = X (); for (size_t i = 0; i < n; i++) r[i] = x[i] OP zero; }
67 67
68 DEFMXUNBOOLOP (mx_inline_iszero, ==) 68 DEFMXUNBOOLOP (mx_inline_iszero, ==)
69 DEFMXUNBOOLOP (mx_inline_notzero, !=) 69 DEFMXUNBOOLOP (mx_inline_notzero, !=)
70 70
71 #define DEFMXBINOP(F, OP) \ 71 #define DEFMXBINOP(F, OP) \
72 template <class R, class X, class Y> \ 72 template <typename R, typename X, typename Y> \
73 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \ 73 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \
74 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \ 74 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \
75 template <class R, class X, class Y> \ 75 template <typename R, typename X, typename Y> \
76 inline void F (size_t n, R *r, const X *x, Y y) throw () \ 76 inline void F (size_t n, R *r, const X *x, Y y) throw () \
77 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \ 77 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \
78 template <class R, class X, class Y> \ 78 template <typename R, typename X, typename Y> \
79 inline void F (size_t n, R *r, X x, const Y *y) throw () \ 79 inline void F (size_t n, R *r, X x, const Y *y) throw () \
80 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; } 80 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; }
81 81
82 DEFMXBINOP (mx_inline_add, +) 82 DEFMXBINOP (mx_inline_add, +)
83 DEFMXBINOP (mx_inline_sub, -) 83 DEFMXBINOP (mx_inline_sub, -)
84 DEFMXBINOP (mx_inline_mul, *) 84 DEFMXBINOP (mx_inline_mul, *)
85 DEFMXBINOP (mx_inline_div, /) 85 DEFMXBINOP (mx_inline_div, /)
86 86
87 #define DEFMXBINOPEQ(F, OP) \ 87 #define DEFMXBINOPEQ(F, OP) \
88 template <class R, class X> \ 88 template <typename R, typename X> \
89 inline void F (size_t n, R *r, const X *x) throw () \ 89 inline void F (size_t n, R *r, const X *x) throw () \
90 { for (size_t i = 0; i < n; i++) r[i] OP x[i]; } \ 90 { for (size_t i = 0; i < n; i++) r[i] OP x[i]; } \
91 template <class R, class X> \ 91 template <typename R, typename X> \
92 inline void F (size_t n, R *r, X x) throw () \ 92 inline void F (size_t n, R *r, X x) throw () \
93 { for (size_t i = 0; i < n; i++) r[i] OP x; } 93 { for (size_t i = 0; i < n; i++) r[i] OP x; }
94 94
95 DEFMXBINOPEQ (mx_inline_add2, +=) 95 DEFMXBINOPEQ (mx_inline_add2, +=)
96 DEFMXBINOPEQ (mx_inline_sub2, -=) 96 DEFMXBINOPEQ (mx_inline_sub2, -=)
97 DEFMXBINOPEQ (mx_inline_mul2, *=) 97 DEFMXBINOPEQ (mx_inline_mul2, *=)
98 DEFMXBINOPEQ (mx_inline_div2, /=) 98 DEFMXBINOPEQ (mx_inline_div2, /=)
99 99
100 #define DEFMXCMPOP(F, OP) \ 100 #define DEFMXCMPOP(F, OP) \
101 template <class X, class Y> \ 101 template <typename X, typename Y> \
102 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \ 102 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \
103 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \ 103 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \
104 template <class X, class Y> \ 104 template <typename X, typename Y> \
105 inline void F (size_t n, bool *r, const X *x, Y y) throw () \ 105 inline void F (size_t n, bool *r, const X *x, Y y) throw () \
106 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \ 106 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \
107 template <class X, class Y> \ 107 template <typename X, typename Y> \
108 inline void F (size_t n, bool *r, X x, const Y *y) throw () \ 108 inline void F (size_t n, bool *r, X x, const Y *y) throw () \
109 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; } 109 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; }
110 110
111 DEFMXCMPOP (mx_inline_lt, <) 111 DEFMXCMPOP (mx_inline_lt, <)
112 DEFMXCMPOP (mx_inline_le, <=) 112 DEFMXCMPOP (mx_inline_le, <=)
114 DEFMXCMPOP (mx_inline_ge, >=) 114 DEFMXCMPOP (mx_inline_ge, >=)
115 DEFMXCMPOP (mx_inline_eq, ==) 115 DEFMXCMPOP (mx_inline_eq, ==)
116 DEFMXCMPOP (mx_inline_ne, !=) 116 DEFMXCMPOP (mx_inline_ne, !=)
117 117
118 // Convert to logical value, for logical op purposes. 118 // Convert to logical value, for logical op purposes.
119 template <class T> inline bool logical_value (T x) { return x; } 119 template <typename T> inline bool logical_value (T x) { return x; }
120 template <class T> inline bool logical_value (const std::complex<T>& x) 120 template <typename T> inline bool logical_value (const std::complex<T>& x)
121 { return x.real () != 0 || x.imag () != 0; } 121 { return x.real () != 0 || x.imag () != 0; }
122 template <class T> inline bool logical_value (const octave_int<T>& x) 122 template <typename T> inline bool logical_value (const octave_int<T>& x)
123 { return x.value (); } 123 { return x.value (); }
124 124
125 template <class X> 125 template <typename X>
126 void mx_inline_not (size_t n, bool *r, const X* x) throw () 126 void mx_inline_not (size_t n, bool *r, const X* x) throw ()
127 { 127 {
128 for (size_t i = 0; i < n; i++) 128 for (size_t i = 0; i < n; i++)
129 r[i] = ! logical_value (x[i]); 129 r[i] = ! logical_value (x[i]);
130 } 130 }
133 { 133 {
134 for (size_t i = 0; i < n; i++) r[i] = ! r[i]; 134 for (size_t i = 0; i < n; i++) r[i] = ! r[i];
135 } 135 }
136 136
137 #define DEFMXBOOLOP(F, NOT1, OP, NOT2) \ 137 #define DEFMXBOOLOP(F, NOT1, OP, NOT2) \
138 template <class X, class Y> \ 138 template <typename X, typename Y> \
139 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \ 139 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \
140 { \ 140 { \
141 for (size_t i = 0; i < n; i++) \ 141 for (size_t i = 0; i < n; i++) \
142 r[i] = (NOT1 logical_value (x[i])) OP (NOT2 logical_value (y[i])); \ 142 r[i] = (NOT1 logical_value (x[i])) OP (NOT2 logical_value (y[i])); \
143 } \ 143 } \
144 template <class X, class Y> \ 144 template <typename X, typename Y> \
145 inline void F (size_t n, bool *r, const X *x, Y y) throw () \ 145 inline void F (size_t n, bool *r, const X *x, Y y) throw () \
146 { \ 146 { \
147 const bool yy = (NOT2 logical_value (y)); \ 147 const bool yy = (NOT2 logical_value (y)); \
148 for (size_t i = 0; i < n; i++) \ 148 for (size_t i = 0; i < n; i++) \
149 r[i] = (NOT1 logical_value (x[i])) OP yy; \ 149 r[i] = (NOT1 logical_value (x[i])) OP yy; \
150 } \ 150 } \
151 template <class X, class Y> \ 151 template <typename X, typename Y> \
152 inline void F (size_t n, bool *r, X x, const Y *y) throw () \ 152 inline void F (size_t n, bool *r, X x, const Y *y) throw () \
153 { \ 153 { \
154 const bool xx = (NOT1 logical_value (x)); \ 154 const bool xx = (NOT1 logical_value (x)); \
155 for (size_t i = 0; i < n; i++) \ 155 for (size_t i = 0; i < n; i++) \
156 r[i] = xx OP (NOT2 logical_value (y[i])); \ 156 r[i] = xx OP (NOT2 logical_value (y[i])); \
162 DEFMXBOOLOP (mx_inline_not_or, !, |, ) 162 DEFMXBOOLOP (mx_inline_not_or, !, |, )
163 DEFMXBOOLOP (mx_inline_and_not, , &, !) 163 DEFMXBOOLOP (mx_inline_and_not, , &, !)
164 DEFMXBOOLOP (mx_inline_or_not, , |, !) 164 DEFMXBOOLOP (mx_inline_or_not, , |, !)
165 165
166 #define DEFMXBOOLOPEQ(F, OP) \ 166 #define DEFMXBOOLOPEQ(F, OP) \
167 template <class X> \ 167 template <typename X> \
168 inline void F (size_t n, bool *r, const X *x) throw () \ 168 inline void F (size_t n, bool *r, const X *x) throw () \
169 { \ 169 { \
170 for (size_t i = 0; i < n; i++) \ 170 for (size_t i = 0; i < n; i++) \
171 r[i] OP logical_value (x[i]); \ 171 r[i] OP logical_value (x[i]); \
172 } \ 172 } \
173 template <class X> \ 173 template <typename X> \
174 inline void F (size_t n, bool *r, X x) throw () \ 174 inline void F (size_t n, bool *r, X x) throw () \
175 { for (size_t i = 0; i < n; i++) r[i] OP x; } 175 { for (size_t i = 0; i < n; i++) r[i] OP x; }
176 176
177 DEFMXBOOLOPEQ (mx_inline_and2, &=) 177 DEFMXBOOLOPEQ (mx_inline_and2, &=)
178 DEFMXBOOLOPEQ (mx_inline_or2, |=) 178 DEFMXBOOLOPEQ (mx_inline_or2, |=)
179 179
180 template <class T> 180 template <typename T>
181 inline bool 181 inline bool
182 mx_inline_any_nan (size_t n, const T* x) throw () 182 mx_inline_any_nan (size_t n, const T* x) throw ()
183 { 183 {
184 for (size_t i = 0; i < n; i++) 184 for (size_t i = 0; i < n; i++)
185 { 185 {
188 } 188 }
189 189
190 return false; 190 return false;
191 } 191 }
192 192
193 template <class T> 193 template <typename T>
194 inline bool 194 inline bool
195 mx_inline_all_finite (size_t n, const T* x) throw () 195 mx_inline_all_finite (size_t n, const T* x) throw ()
196 { 196 {
197 for (size_t i = 0; i < n; i++) 197 for (size_t i = 0; i < n; i++)
198 { 198 {
201 } 201 }
202 202
203 return true; 203 return true;
204 } 204 }
205 205
206 template <class T> 206 template <typename T>
207 inline bool 207 inline bool
208 mx_inline_any_negative (size_t n, const T* x) throw () 208 mx_inline_any_negative (size_t n, const T* x) throw ()
209 { 209 {
210 for (size_t i = 0; i < n; i++) 210 for (size_t i = 0; i < n; i++)
211 { 211 {
214 } 214 }
215 215
216 return false; 216 return false;
217 } 217 }
218 218
219 template <class T> 219 template <typename T>
220 inline bool 220 inline bool
221 mx_inline_any_positive (size_t n, const T* x) throw () 221 mx_inline_any_positive (size_t n, const T* x) throw ()
222 { 222 {
223 for (size_t i = 0; i < n; i++) 223 for (size_t i = 0; i < n; i++)
224 { 224 {
227 } 227 }
228 228
229 return false; 229 return false;
230 } 230 }
231 231
232 template<class T> 232 template <typename T>
233 inline bool 233 inline bool
234 mx_inline_all_real (size_t n, const std::complex<T>* x) throw () 234 mx_inline_all_real (size_t n, const std::complex<T>* x) throw ()
235 { 235 {
236 for (size_t i = 0; i < n; i++) 236 for (size_t i = 0; i < n; i++)
237 { 237 {
241 241
242 return true; 242 return true;
243 } 243 }
244 244
245 #define DEFMXMAPPER(F, FUN) \ 245 #define DEFMXMAPPER(F, FUN) \
246 template <class T> \ 246 template <typename T> \
247 inline void F (size_t n, T *r, const T *x) throw () \ 247 inline void F (size_t n, T *r, const T *x) throw () \
248 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i]); } 248 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i]); }
249 249
250 template<class T> 250 template <typename T>
251 inline void mx_inline_real (size_t n, T *r, const std::complex<T>* x) throw () 251 inline void mx_inline_real (size_t n, T *r, const std::complex<T>* x) throw ()
252 { for (size_t i = 0; i < n; i++) r[i] = x[i].real (); } 252 { for (size_t i = 0; i < n; i++) r[i] = x[i].real (); }
253 template<class T> 253 template <typename T>
254 inline void mx_inline_imag (size_t n, T *r, const std::complex<T>* x) throw () 254 inline void mx_inline_imag (size_t n, T *r, const std::complex<T>* x) throw ()
255 { for (size_t i = 0; i < n; i++) r[i] = x[i].imag (); } 255 { for (size_t i = 0; i < n; i++) r[i] = x[i].imag (); }
256 256
257 // Pairwise minimums/maximums 257 // Pairwise minimums/maximums
258 #define DEFMXMAPPER2(F, FUN) \ 258 #define DEFMXMAPPER2(F, FUN) \
259 template <class T> \ 259 template <typename T> \
260 inline void F (size_t n, T *r, const T *x, const T *y) throw () \ 260 inline void F (size_t n, T *r, const T *x, const T *y) throw () \
261 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ 261 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \
262 template <class T> \ 262 template <typename T> \
263 inline void F (size_t n, T *r, const T *x, T y) throw () \ 263 inline void F (size_t n, T *r, const T *x, T y) throw () \
264 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \ 264 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \
265 template <class T> \ 265 template <typename T> \
266 inline void F (size_t n, T *r, T x, const T *y) throw () \ 266 inline void F (size_t n, T *r, T x, const T *y) throw () \
267 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } 267 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); }
268 268
269 DEFMXMAPPER2 (mx_inline_xmin, xmin) 269 DEFMXMAPPER2 (mx_inline_xmin, xmin)
270 DEFMXMAPPER2 (mx_inline_xmax, xmax) 270 DEFMXMAPPER2 (mx_inline_xmax, xmax)
293 DEFMINMAXSPEC (float, mx_inline_xmin, <=) 293 DEFMINMAXSPEC (float, mx_inline_xmin, <=)
294 DEFMINMAXSPEC (float, mx_inline_xmax, >=) 294 DEFMINMAXSPEC (float, mx_inline_xmax, >=)
295 295
296 // Pairwise power 296 // Pairwise power
297 #define DEFMXMAPPER2X(F, FUN) \ 297 #define DEFMXMAPPER2X(F, FUN) \
298 template <class R, class X, class Y> \ 298 template <typename R, typename X, typename Y> \
299 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \ 299 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \
300 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ 300 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \
301 template <class R, class X, class Y> \ 301 template <typename R, typename X, typename Y> \
302 inline void F (size_t n, R *r, const X *x, Y y) throw () \ 302 inline void F (size_t n, R *r, const X *x, Y y) throw () \
303 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \ 303 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \
304 template <class R, class X, class Y> \ 304 template <typename R, typename X, typename Y> \
305 inline void F (size_t n, R *r, X x, const Y *y) throw () \ 305 inline void F (size_t n, R *r, X x, const Y *y) throw () \
306 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } 306 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); }
307 307
308 // Let the compiler decide which pow to use, whichever best matches the 308 // Let the compiler decide which pow to use, whichever best matches the
309 // arguments provided. 309 // arguments provided.
310 using std::pow; 310 using std::pow;
311 DEFMXMAPPER2X (mx_inline_pow, pow) 311 DEFMXMAPPER2X (mx_inline_pow, pow)
312 312
313 // Arbitrary function appliers. The function is a template parameter to enable 313 // Arbitrary function appliers. The function is a template parameter to enable
314 // inlining. 314 // inlining.
315 template <class R, class X, R fun (X x)> 315 template <typename R, typename X, R fun (X x)>
316 inline void mx_inline_map (size_t n, R *r, const X *x) throw () 316 inline void mx_inline_map (size_t n, R *r, const X *x) throw ()
317 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } 317 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); }
318 318
319 template <class R, class X, R fun (const X& x)> 319 template <typename R, typename X, R fun (const X& x)>
320 inline void mx_inline_map (size_t n, R *r, const X *x) throw () 320 inline void mx_inline_map (size_t n, R *r, const X *x) throw ()
321 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } 321 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); }
322 322
323 // Appliers. Since these call the operation just once, we pass it as 323 // Appliers. Since these call the operation just once, we pass it as
324 // a pointer, to allow the compiler reduce number of instances. 324 // a pointer, to allow the compiler reduce number of instances.
325 325
326 template <class R, class X> 326 template <typename R, typename X>
327 inline Array<R> 327 inline Array<R>
328 do_mx_unary_op (const Array<X>& x, 328 do_mx_unary_op (const Array<X>& x,
329 void (*op) (size_t, R *, const X *) throw ()) 329 void (*op) (size_t, R *, const X *) throw ())
330 { 330 {
331 Array<R> r (x.dims ()); 331 Array<R> r (x.dims ());
333 return r; 333 return r;
334 } 334 }
335 335
336 // Shortcuts for applying mx_inline_map. 336 // Shortcuts for applying mx_inline_map.
337 337
338 template <class R, class X, R fun (X)> 338 template <typename R, typename X, R fun (X)>
339 inline Array<R> 339 inline Array<R>
340 do_mx_unary_map (const Array<X>& x) 340 do_mx_unary_map (const Array<X>& x)
341 { 341 {
342 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>); 342 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>);
343 } 343 }
344 344
345 template <class R, class X, R fun (const X&)> 345 template <typename R, typename X, R fun (const X&)>
346 inline Array<R> 346 inline Array<R>
347 do_mx_unary_map (const Array<X>& x) 347 do_mx_unary_map (const Array<X>& x)
348 { 348 {
349 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>); 349 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>);
350 } 350 }
351 351
352 template <class R> 352 template <typename R>
353 inline Array<R>& 353 inline Array<R>&
354 do_mx_inplace_op (Array<R>& r, 354 do_mx_inplace_op (Array<R>& r,
355 void (*op) (size_t, R *) throw ()) 355 void (*op) (size_t, R *) throw ())
356 { 356 {
357 op (r.numel (), r.fortran_vec ()); 357 op (r.numel (), r.fortran_vec ());
358 return r; 358 return r;
359 } 359 }
360 360
361 template <class R, class X, class Y> 361 template <typename R, typename X, typename Y>
362 inline Array<R> 362 inline Array<R>
363 do_mm_binary_op (const Array<X>& x, const Array<Y>& y, 363 do_mm_binary_op (const Array<X>& x, const Array<Y>& y,
364 void (*op) (size_t, R *, const X *, const Y *) throw (), 364 void (*op) (size_t, R *, const X *, const Y *) throw (),
365 void (*op1) (size_t, R *, X, const Y *) throw (), 365 void (*op1) (size_t, R *, X, const Y *) throw (),
366 void (*op2) (size_t, R *, const X *, Y) throw (), 366 void (*op2) (size_t, R *, const X *, Y) throw (),
380 } 380 }
381 else 381 else
382 err_nonconformant (opname, dx, dy); 382 err_nonconformant (opname, dx, dy);
383 } 383 }
384 384
385 template <class R, class X, class Y> 385 template <typename R, typename X, typename Y>
386 inline Array<R> 386 inline Array<R>
387 do_ms_binary_op (const Array<X>& x, const Y& y, 387 do_ms_binary_op (const Array<X>& x, const Y& y,
388 void (*op) (size_t, R *, const X *, Y) throw ()) 388 void (*op) (size_t, R *, const X *, Y) throw ())
389 { 389 {
390 Array<R> r (x.dims ()); 390 Array<R> r (x.dims ());
391 op (r.numel (), r.fortran_vec (), x.data (), y); 391 op (r.numel (), r.fortran_vec (), x.data (), y);
392 return r; 392 return r;
393 } 393 }
394 394
395 template <class R, class X, class Y> 395 template <typename R, typename X, typename Y>
396 inline Array<R> 396 inline Array<R>
397 do_sm_binary_op (const X& x, const Array<Y>& y, 397 do_sm_binary_op (const X& x, const Array<Y>& y,
398 void (*op) (size_t, R *, X, const Y *) throw ()) 398 void (*op) (size_t, R *, X, const Y *) throw ())
399 { 399 {
400 Array<R> r (y.dims ()); 400 Array<R> r (y.dims ());
401 op (r.numel (), r.fortran_vec (), x, y.data ()); 401 op (r.numel (), r.fortran_vec (), x, y.data ());
402 return r; 402 return r;
403 } 403 }
404 404
405 template <class R, class X> 405 template <typename R, typename X>
406 inline Array<R>& 406 inline Array<R>&
407 do_mm_inplace_op (Array<R>& r, const Array<X>& x, 407 do_mm_inplace_op (Array<R>& r, const Array<X>& x,
408 void (*op) (size_t, R *, const X *) throw (), 408 void (*op) (size_t, R *, const X *) throw (),
409 void (*op1) (size_t, R *, X) throw (), 409 void (*op1) (size_t, R *, X) throw (),
410 const char *opname) 410 const char *opname)
419 err_nonconformant (opname, dr, dx); 419 err_nonconformant (opname, dr, dx);
420 420
421 return r; 421 return r;
422 } 422 }
423 423
424 template <class R, class X> 424 template <typename R, typename X>
425 inline Array<R>& 425 inline Array<R>&
426 do_ms_inplace_op (Array<R>& r, const X& x, 426 do_ms_inplace_op (Array<R>& r, const X& x,
427 void (*op) (size_t, R *, X) throw ()) 427 void (*op) (size_t, R *, X) throw ())
428 { 428 {
429 op (r.numel (), r.fortran_vec (), x); 429 op (r.numel (), r.fortran_vec (), x);
430 return r; 430 return r;
431 } 431 }
432 432
433 template <class T1, class T2> 433 template <typename T1, typename T2>
434 inline bool 434 inline bool
435 mx_inline_equal (size_t n, const T1 *x, const T2 *y) throw () 435 mx_inline_equal (size_t n, const T1 *x, const T2 *y) throw ()
436 { 436 {
437 for (size_t i = 0; i < n; i++) 437 for (size_t i = 0; i < n; i++)
438 if (x[i] != y[i]) 438 if (x[i] != y[i])
439 return false; 439 return false;
440 return true; 440 return true;
441 } 441 }
442 442
443 template <class T> 443 template <typename T>
444 inline bool 444 inline bool
445 do_mx_check (const Array<T>& a, 445 do_mx_check (const Array<T>& a,
446 bool (*op) (size_t, const T *) throw ()) 446 bool (*op) (size_t, const T *) throw ())
447 { 447 {
448 return op (a.numel (), a.data ()); 448 return op (a.numel (), a.data ());
449 } 449 }
450 450
451 // NOTE: we don't use std::norm because it typically does some heavyweight 451 // NOTE: we don't use std::norm because it typically does some heavyweight
452 // magic to avoid underflows, which we don't need here. 452 // magic to avoid underflows, which we don't need here.
453 template <class T> 453 template <typename T>
454 inline T cabsq (const std::complex<T>& c) 454 inline T cabsq (const std::complex<T>& c)
455 { return c.real () * c.real () + c.imag () * c.imag (); } 455 { return c.real () * c.real () + c.imag () * c.imag (); }
456 456
457 // default. works for integers and bool. 457 // default. works for integers and bool.
458 template <class T> 458 template <typename T>
459 inline bool xis_true (T x) { return x; } 459 inline bool xis_true (T x) { return x; }
460 template <class T> 460 template <typename T>
461 inline bool xis_false (T x) { return ! x; } 461 inline bool xis_false (T x) { return ! x; }
462 // for octave_ints 462 // for octave_ints
463 template <class T> 463 template <typename T>
464 inline bool xis_true (const octave_int<T>& x) { return x.value (); } 464 inline bool xis_true (const octave_int<T>& x) { return x.value (); }
465 template <class T> 465 template <typename T>
466 inline bool xis_false (const octave_int<T>& x) { return ! x.value (); } 466 inline bool xis_false (const octave_int<T>& x) { return ! x.value (); }
467 // for reals, we want to ignore NaNs. 467 // for reals, we want to ignore NaNs.
468 inline bool xis_true (double x) { return ! xisnan (x) && x != 0.0; } 468 inline bool xis_true (double x) { return ! xisnan (x) && x != 0.0; }
469 inline bool xis_false (double x) { return x == 0.0; } 469 inline bool xis_false (double x) { return x == 0.0; }
470 inline bool xis_true (float x) { return ! xisnan (x) && x != 0.0f; } 470 inline bool xis_true (float x) { return ! xisnan (x) && x != 0.0f; }
482 482
483 inline void op_dble_prod (double& ac, float el) 483 inline void op_dble_prod (double& ac, float el)
484 { ac *= el; } 484 { ac *= el; }
485 inline void op_dble_prod (Complex& ac, const FloatComplex& el) 485 inline void op_dble_prod (Complex& ac, const FloatComplex& el)
486 { ac *= el; } // FIXME: guaranteed? 486 { ac *= el; } // FIXME: guaranteed?
487 template <class T> 487 template <typename T>
488 inline void op_dble_prod (double& ac, const octave_int<T>& el) 488 inline void op_dble_prod (double& ac, const octave_int<T>& el)
489 { ac *= el.double_value (); } 489 { ac *= el.double_value (); }
490 490
491 inline void op_dble_sum (double& ac, float el) 491 inline void op_dble_sum (double& ac, float el)
492 { ac += el; } 492 { ac += el; }
493 inline void op_dble_sum (Complex& ac, const FloatComplex& el) 493 inline void op_dble_sum (Complex& ac, const FloatComplex& el)
494 { ac += el; } // FIXME: guaranteed? 494 { ac += el; } // FIXME: guaranteed?
495 template <class T> 495 template <typename T>
496 inline void op_dble_sum (double& ac, const octave_int<T>& el) 496 inline void op_dble_sum (double& ac, const octave_int<T>& el)
497 { ac += el.double_value (); } 497 { ac += el.double_value (); }
498 498
499 // The following two implement a simple short-circuiting. 499 // The following two implement a simple short-circuiting.
500 #define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue 500 #define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue
501 #define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue 501 #define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue
502 502
503 #define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \ 503 #define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \
504 template <class T> \ 504 template <typename T> \
505 inline TRES \ 505 inline TRES \
506 F (const TSRC* v, octave_idx_type n) \ 506 F (const TSRC* v, octave_idx_type n) \
507 { \ 507 { \
508 TRES ac = ZERO; \ 508 TRES ac = ZERO; \
509 for (octave_idx_type i = 0; i < n; i++) \ 509 for (octave_idx_type i = 0; i < n; i++) \
523 OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false) 523 OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false)
524 OP_RED_FCN (mx_inline_all, T, bool, OP_RED_ALLC, true) 524 OP_RED_FCN (mx_inline_all, T, bool, OP_RED_ALLC, true)
525 525
526 526
527 #define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \ 527 #define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \
528 template <class T> \ 528 template <typename T> \
529 inline void \ 529 inline void \
530 F (const TSRC* v, TRES *r, octave_idx_type m, octave_idx_type n) \ 530 F (const TSRC* v, TRES *r, octave_idx_type m, octave_idx_type n) \
531 { \ 531 { \
532 for (octave_idx_type i = 0; i < m; i++) \ 532 for (octave_idx_type i = 0; i < m; i++) \
533 r[i] = ZERO; \ 533 r[i] = ZERO; \
556 // Using the general code for any/all would sacrifice short-circuiting. 556 // Using the general code for any/all would sacrifice short-circuiting.
557 // OTOH, going by rows would sacrifice cache-coherence. The following algorithm 557 // OTOH, going by rows would sacrifice cache-coherence. The following algorithm
558 // will achieve both, at the cost of a temporary octave_idx_type array. 558 // will achieve both, at the cost of a temporary octave_idx_type array.
559 559
560 #define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO) \ 560 #define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO) \
561 template <class T> \ 561 template <typename T> \
562 inline void \ 562 inline void \
563 F (const T* v, bool *r, octave_idx_type m, octave_idx_type n) \ 563 F (const T* v, bool *r, octave_idx_type m, octave_idx_type n) \
564 { \ 564 { \
565 if (n <= 8) \ 565 if (n <= 8) \
566 return F ## _r (v, r, m, n); \ 566 return F ## _r (v, r, m, n); \
587 587
588 OP_ROW_SHORT_CIRCUIT (mx_inline_any, xis_true, false) 588 OP_ROW_SHORT_CIRCUIT (mx_inline_any, xis_true, false)
589 OP_ROW_SHORT_CIRCUIT (mx_inline_all, xis_false, true) 589 OP_ROW_SHORT_CIRCUIT (mx_inline_all, xis_false, true)
590 590
591 #define OP_RED_FCNN(F, TSRC, TRES) \ 591 #define OP_RED_FCNN(F, TSRC, TRES) \
592 template <class T> \ 592 template <typename T> \
593 inline void \ 593 inline void \
594 F (const TSRC *v, TRES *r, octave_idx_type l, \ 594 F (const TSRC *v, TRES *r, octave_idx_type l, \
595 octave_idx_type n, octave_idx_type u) \ 595 octave_idx_type n, octave_idx_type u) \
596 { \ 596 { \
597 if (l == 1) \ 597 if (l == 1) \
622 OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T) 622 OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T)
623 OP_RED_FCNN (mx_inline_any, T, bool) 623 OP_RED_FCNN (mx_inline_any, T, bool)
624 OP_RED_FCNN (mx_inline_all, T, bool) 624 OP_RED_FCNN (mx_inline_all, T, bool)
625 625
626 #define OP_CUM_FCN(F, TSRC, TRES, OP) \ 626 #define OP_CUM_FCN(F, TSRC, TRES, OP) \
627 template <class T> \ 627 template <typename T> \
628 inline void \ 628 inline void \
629 F (const TSRC *v, TRES *r, octave_idx_type n) \ 629 F (const TSRC *v, TRES *r, octave_idx_type n) \
630 { \ 630 { \
631 if (n) \ 631 if (n) \
632 { \ 632 { \
639 OP_CUM_FCN (mx_inline_cumsum, T, T, +) 639 OP_CUM_FCN (mx_inline_cumsum, T, T, +)
640 OP_CUM_FCN (mx_inline_cumprod, T, T, *) 640 OP_CUM_FCN (mx_inline_cumprod, T, T, *)
641 OP_CUM_FCN (mx_inline_cumcount, bool, T, +) 641 OP_CUM_FCN (mx_inline_cumcount, bool, T, +)
642 642
643 #define OP_CUM_FCN2(F, TSRC, TRES, OP) \ 643 #define OP_CUM_FCN2(F, TSRC, TRES, OP) \
644 template <class T> \ 644 template <typename T> \
645 inline void \ 645 inline void \
646 F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \ 646 F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \
647 { \ 647 { \
648 if (n) \ 648 if (n) \
649 { \ 649 { \
663 OP_CUM_FCN2 (mx_inline_cumsum, T, T, +) 663 OP_CUM_FCN2 (mx_inline_cumsum, T, T, +)
664 OP_CUM_FCN2 (mx_inline_cumprod, T, T, *) 664 OP_CUM_FCN2 (mx_inline_cumprod, T, T, *)
665 OP_CUM_FCN2 (mx_inline_cumcount, bool, T, +) 665 OP_CUM_FCN2 (mx_inline_cumcount, bool, T, +)
666 666
667 #define OP_CUM_FCNN(F, TSRC, TRES) \ 667 #define OP_CUM_FCNN(F, TSRC, TRES) \
668 template <class T> \ 668 template <typename T> \
669 inline void \ 669 inline void \
670 F (const TSRC *v, TRES *r, octave_idx_type l, \ 670 F (const TSRC *v, TRES *r, octave_idx_type l, \
671 octave_idx_type n, octave_idx_type u) \ 671 octave_idx_type n, octave_idx_type u) \
672 { \ 672 { \
673 if (l == 1) \ 673 if (l == 1) \
692 OP_CUM_FCNN (mx_inline_cumsum, T, T) 692 OP_CUM_FCNN (mx_inline_cumsum, T, T)
693 OP_CUM_FCNN (mx_inline_cumprod, T, T) 693 OP_CUM_FCNN (mx_inline_cumprod, T, T)
694 OP_CUM_FCNN (mx_inline_cumcount, bool, T) 694 OP_CUM_FCNN (mx_inline_cumcount, bool, T)
695 695
696 #define OP_MINMAX_FCN(F, OP) \ 696 #define OP_MINMAX_FCN(F, OP) \
697 template <class T> \ 697 template <typename T> \
698 void F (const T *v, T *r, octave_idx_type n) \ 698 void F (const T *v, T *r, octave_idx_type n) \
699 { \ 699 { \
700 if (! n) return; \ 700 if (! n) return; \
701 T tmp = v[0]; \ 701 T tmp = v[0]; \
702 octave_idx_type i = 1; \ 702 octave_idx_type i = 1; \
707 } \ 707 } \
708 for (; i < n; i++) \ 708 for (; i < n; i++) \
709 if (v[i] OP tmp) tmp = v[i]; \ 709 if (v[i] OP tmp) tmp = v[i]; \
710 *r = tmp; \ 710 *r = tmp; \
711 } \ 711 } \
712 template <class T> \ 712 template <typename T> \
713 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \ 713 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
714 { \ 714 { \
715 if (! n) return; \ 715 if (! n) return; \
716 T tmp = v[0]; \ 716 T tmp = v[0]; \
717 octave_idx_type tmpi = 0; \ 717 octave_idx_type tmpi = 0; \
733 // Row reductions will be slightly complicated. We will proceed with checks 733 // Row reductions will be slightly complicated. We will proceed with checks
734 // for NaNs until we detect that no row will yield a NaN, in which case we 734 // for NaNs until we detect that no row will yield a NaN, in which case we
735 // proceed to a faster code. 735 // proceed to a faster code.
736 736
737 #define OP_MINMAX_FCN2(F, OP) \ 737 #define OP_MINMAX_FCN2(F, OP) \
738 template <class T> \ 738 template <typename T> \
739 inline void \ 739 inline void \
740 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ 740 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
741 { \ 741 { \
742 if (! n) return; \ 742 if (! n) return; \
743 bool nan = false; \ 743 bool nan = false; \
765 for (octave_idx_type i = 0; i < m; i++) \ 765 for (octave_idx_type i = 0; i < m; i++) \
766 if (v[i] OP r[i]) r[i] = v[i]; \ 766 if (v[i] OP r[i]) r[i] = v[i]; \
767 j++; v += m; \ 767 j++; v += m; \
768 } \ 768 } \
769 } \ 769 } \
770 template <class T> \ 770 template <typename T> \
771 inline void \ 771 inline void \
772 F (const T *v, T *r, octave_idx_type *ri, \ 772 F (const T *v, T *r, octave_idx_type *ri, \
773 octave_idx_type m, octave_idx_type n) \ 773 octave_idx_type m, octave_idx_type n) \
774 { \ 774 { \
775 if (! n) return; \ 775 if (! n) return; \
804 804
805 OP_MINMAX_FCN2 (mx_inline_min, <) 805 OP_MINMAX_FCN2 (mx_inline_min, <)
806 OP_MINMAX_FCN2 (mx_inline_max, >) 806 OP_MINMAX_FCN2 (mx_inline_max, >)
807 807
808 #define OP_MINMAX_FCNN(F) \ 808 #define OP_MINMAX_FCNN(F) \
809 template <class T> \ 809 template <typename T> \
810 inline void \ 810 inline void \
811 F (const T *v, T *r, octave_idx_type l, \ 811 F (const T *v, T *r, octave_idx_type l, \
812 octave_idx_type n, octave_idx_type u) \ 812 octave_idx_type n, octave_idx_type u) \
813 { \ 813 { \
814 if (! n) return; \ 814 if (! n) return; \
828 v += l*n; \ 828 v += l*n; \
829 r += l; \ 829 r += l; \
830 } \ 830 } \
831 } \ 831 } \
832 } \ 832 } \
833 template <class T> \ 833 template <typename T> \
834 inline void \ 834 inline void \
835 F (const T *v, T *r, octave_idx_type *ri, \ 835 F (const T *v, T *r, octave_idx_type *ri, \
836 octave_idx_type l, octave_idx_type n, octave_idx_type u) \ 836 octave_idx_type l, octave_idx_type n, octave_idx_type u) \
837 { \ 837 { \
838 if (! n) return; \ 838 if (! n) return; \
857 857
858 OP_MINMAX_FCNN (mx_inline_min) 858 OP_MINMAX_FCNN (mx_inline_min)
859 OP_MINMAX_FCNN (mx_inline_max) 859 OP_MINMAX_FCNN (mx_inline_max)
860 860
861 #define OP_CUMMINMAX_FCN(F, OP) \ 861 #define OP_CUMMINMAX_FCN(F, OP) \
862 template <class T> \ 862 template <typename T> \
863 void F (const T *v, T *r, octave_idx_type n) \ 863 void F (const T *v, T *r, octave_idx_type n) \
864 { \ 864 { \
865 if (! n) return; \ 865 if (! n) return; \
866 T tmp = v[0]; \ 866 T tmp = v[0]; \
867 octave_idx_type i = 1; \ 867 octave_idx_type i = 1; \
878 for (; j < i; j++) r[j] = tmp; \ 878 for (; j < i; j++) r[j] = tmp; \
879 tmp = v[i]; \ 879 tmp = v[i]; \
880 } \ 880 } \
881 for (; j < i; j++) r[j] = tmp; \ 881 for (; j < i; j++) r[j] = tmp; \
882 } \ 882 } \
883 template <class T> \ 883 template <typename T> \
884 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \ 884 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
885 { \ 885 { \
886 if (! n) return; \ 886 if (! n) return; \
887 T tmp = v[0]; octave_idx_type tmpi = 0; \ 887 T tmp = v[0]; octave_idx_type tmpi = 0; \
888 octave_idx_type i = 1; \ 888 octave_idx_type i = 1; \
908 // Row reductions will be slightly complicated. We will proceed with checks 908 // Row reductions will be slightly complicated. We will proceed with checks
909 // for NaNs until we detect that no row will yield a NaN, in which case we 909 // for NaNs until we detect that no row will yield a NaN, in which case we
910 // proceed to a faster code. 910 // proceed to a faster code.
911 911
912 #define OP_CUMMINMAX_FCN2(F, OP) \ 912 #define OP_CUMMINMAX_FCN2(F, OP) \
913 template <class T> \ 913 template <typename T> \
914 inline void \ 914 inline void \
915 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ 915 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
916 { \ 916 { \
917 if (! n) return; \ 917 if (! n) return; \
918 bool nan = false; \ 918 bool nan = false; \
946 else \ 946 else \
947 r[i] = r0[i]; \ 947 r[i] = r0[i]; \
948 j++; v += m; r0 = r; r += m; \ 948 j++; v += m; r0 = r; r += m; \
949 } \ 949 } \
950 } \ 950 } \
951 template <class T> \ 951 template <typename T> \
952 inline void \ 952 inline void \
953 F (const T *v, T *r, octave_idx_type *ri, \ 953 F (const T *v, T *r, octave_idx_type *ri, \
954 octave_idx_type m, octave_idx_type n) \ 954 octave_idx_type m, octave_idx_type n) \
955 { \ 955 { \
956 if (! n) return; \ 956 if (! n) return; \
990 990
991 OP_CUMMINMAX_FCN2 (mx_inline_cummin, <) 991 OP_CUMMINMAX_FCN2 (mx_inline_cummin, <)
992 OP_CUMMINMAX_FCN2 (mx_inline_cummax, >) 992 OP_CUMMINMAX_FCN2 (mx_inline_cummax, >)
993 993
994 #define OP_CUMMINMAX_FCNN(F) \ 994 #define OP_CUMMINMAX_FCNN(F) \
995 template <class T> \ 995 template <typename T> \
996 inline void \ 996 inline void \
997 F (const T *v, T *r, octave_idx_type l, \ 997 F (const T *v, T *r, octave_idx_type l, \
998 octave_idx_type n, octave_idx_type u) \ 998 octave_idx_type n, octave_idx_type u) \
999 { \ 999 { \
1000 if (! n) return; \ 1000 if (! n) return; \
1014 v += l*n; \ 1014 v += l*n; \
1015 r += l*n; \ 1015 r += l*n; \
1016 } \ 1016 } \
1017 } \ 1017 } \
1018 } \ 1018 } \
1019 template <class T> \ 1019 template <typename T> \
1020 inline void \ 1020 inline void \
1021 F (const T *v, T *r, octave_idx_type *ri, \ 1021 F (const T *v, T *r, octave_idx_type *ri, \
1022 octave_idx_type l, octave_idx_type n, octave_idx_type u) \ 1022 octave_idx_type l, octave_idx_type n, octave_idx_type u) \
1023 { \ 1023 { \
1024 if (! n) return; \ 1024 if (! n) return; \
1042 } 1042 }
1043 1043
1044 OP_CUMMINMAX_FCNN (mx_inline_cummin) 1044 OP_CUMMINMAX_FCNN (mx_inline_cummin)
1045 OP_CUMMINMAX_FCNN (mx_inline_cummax) 1045 OP_CUMMINMAX_FCNN (mx_inline_cummax)
1046 1046
1047 template <class T> 1047 template <typename T>
1048 void mx_inline_diff (const T *v, T *r, octave_idx_type n, 1048 void mx_inline_diff (const T *v, T *r, octave_idx_type n,
1049 octave_idx_type order) 1049 octave_idx_type order)
1050 { 1050 {
1051 switch (order) 1051 switch (order)
1052 { 1052 {
1083 r[i] = buf[i]; 1083 r[i] = buf[i];
1084 } 1084 }
1085 } 1085 }
1086 } 1086 }
1087 1087
1088 template <class T> 1088 template <typename T>
1089 void mx_inline_diff (const T *v, T *r, 1089 void mx_inline_diff (const T *v, T *r,
1090 octave_idx_type m, octave_idx_type n, 1090 octave_idx_type m, octave_idx_type n,
1091 octave_idx_type order) 1091 octave_idx_type order)
1092 { 1092 {
1093 switch (order) 1093 switch (order)
1123 } 1123 }
1124 } 1124 }
1125 } 1125 }
1126 } 1126 }
1127 1127
1128 template <class T> 1128 template <typename T>
1129 inline void 1129 inline void
1130 mx_inline_diff (const T *v, T *r, 1130 mx_inline_diff (const T *v, T *r,
1131 octave_idx_type l, octave_idx_type n, octave_idx_type u, 1131 octave_idx_type l, octave_idx_type n, octave_idx_type u,
1132 octave_idx_type order) 1132 octave_idx_type order)
1133 { 1133 {
1181 1181
1182 // Appliers. 1182 // Appliers.
1183 // FIXME: is this the best design? C++ gives a lot of options here... 1183 // FIXME: is this the best design? C++ gives a lot of options here...
1184 // maybe it can be done without an explicit parameter? 1184 // maybe it can be done without an explicit parameter?
1185 1185
1186 template <class R, class T> 1186 template <typename R, typename T>
1187 inline Array<R> 1187 inline Array<R>
1188 do_mx_red_op (const Array<T>& src, int dim, 1188 do_mx_red_op (const Array<T>& src, int dim,
1189 void (*mx_red_op) (const T *, R *, octave_idx_type, 1189 void (*mx_red_op) (const T *, R *, octave_idx_type,
1190 octave_idx_type, octave_idx_type)) 1190 octave_idx_type, octave_idx_type))
1191 { 1191 {
1205 mx_red_op (src.data (), ret.fortran_vec (), l, n, u); 1205 mx_red_op (src.data (), ret.fortran_vec (), l, n, u);
1206 1206
1207 return ret; 1207 return ret;
1208 } 1208 }
1209 1209
1210 template <class R, class T> 1210 template <typename R, typename T>
1211 inline Array<R> 1211 inline Array<R>
1212 do_mx_cum_op (const Array<T>& src, int dim, 1212 do_mx_cum_op (const Array<T>& src, int dim,
1213 void (*mx_cum_op) (const T *, R *, octave_idx_type, 1213 void (*mx_cum_op) (const T *, R *, octave_idx_type,
1214 octave_idx_type, octave_idx_type)) 1214 octave_idx_type, octave_idx_type))
1215 { 1215 {
1222 mx_cum_op (src.data (), ret.fortran_vec (), l, n, u); 1222 mx_cum_op (src.data (), ret.fortran_vec (), l, n, u);
1223 1223
1224 return ret; 1224 return ret;
1225 } 1225 }
1226 1226
1227 template <class R> 1227 template <typename R>
1228 inline Array<R> 1228 inline Array<R>
1229 do_mx_minmax_op (const Array<R>& src, int dim, 1229 do_mx_minmax_op (const Array<R>& src, int dim,
1230 void (*mx_minmax_op) (const R *, R *, octave_idx_type, 1230 void (*mx_minmax_op) (const R *, R *, octave_idx_type,
1231 octave_idx_type, octave_idx_type)) 1231 octave_idx_type, octave_idx_type))
1232 { 1232 {
1242 mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u); 1242 mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u);
1243 1243
1244 return ret; 1244 return ret;
1245 } 1245 }
1246 1246
1247 template <class R> 1247 template <typename R>
1248 inline Array<R> 1248 inline Array<R>
1249 do_mx_minmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim, 1249 do_mx_minmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim,
1250 void (*mx_minmax_op) (const R *, R *, octave_idx_type *, 1250 void (*mx_minmax_op) (const R *, R *, octave_idx_type *,
1251 octave_idx_type, octave_idx_type, octave_idx_type)) 1251 octave_idx_type, octave_idx_type, octave_idx_type))
1252 { 1252 {
1265 l, n, u); 1265 l, n, u);
1266 1266
1267 return ret; 1267 return ret;
1268 } 1268 }
1269 1269
1270 template <class R> 1270 template <typename R>
1271 inline Array<R> 1271 inline Array<R>
1272 do_mx_cumminmax_op (const Array<R>& src, int dim, 1272 do_mx_cumminmax_op (const Array<R>& src, int dim,
1273 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type, 1273 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type,
1274 octave_idx_type, octave_idx_type)) 1274 octave_idx_type, octave_idx_type))
1275 { 1275 {
1281 mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u); 1281 mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u);
1282 1282
1283 return ret; 1283 return ret;
1284 } 1284 }
1285 1285
1286 template <class R> 1286 template <typename R>
1287 inline Array<R> 1287 inline Array<R>
1288 do_mx_cumminmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim, 1288 do_mx_cumminmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim,
1289 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type *, 1289 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type *,
1290 octave_idx_type, octave_idx_type, octave_idx_type)) 1290 octave_idx_type, octave_idx_type, octave_idx_type))
1291 { 1291 {
1300 l, n, u); 1300 l, n, u);
1301 1301
1302 return ret; 1302 return ret;
1303 } 1303 }
1304 1304
1305 template <class R> 1305 template <typename R>
1306 inline Array<R> 1306 inline Array<R>
1307 do_mx_diff_op (const Array<R>& src, int dim, octave_idx_type order, 1307 do_mx_diff_op (const Array<R>& src, int dim, octave_idx_type order,
1308 void (*mx_diff_op) (const R *, R *, 1308 void (*mx_diff_op) (const R *, R *,
1309 octave_idx_type, octave_idx_type, octave_idx_type, 1309 octave_idx_type, octave_idx_type, octave_idx_type,
1310 octave_idx_type)) 1310 octave_idx_type))
1338 // Fast extra-precise summation. According to 1338 // Fast extra-precise summation. According to
1339 // T. Ogita, S. M. Rump, S. Oishi: 1339 // T. Ogita, S. M. Rump, S. Oishi:
1340 // Accurate Sum And Dot Product, 1340 // Accurate Sum And Dot Product,
1341 // SIAM J. Sci. Computing, Vol. 26, 2005 1341 // SIAM J. Sci. Computing, Vol. 26, 2005
1342 1342
1343 template <class T> 1343 template <typename T>
1344 inline void twosum_accum (T& s, T& e, 1344 inline void twosum_accum (T& s, T& e,
1345 const T& x) 1345 const T& x)
1346 { 1346 {
1347 T s1 = s + x; 1347 T s1 = s + x;
1348 T t = s1 - s; 1348 T t = s1 - s;
1349 T e1 = (s - (s1 - t)) + (x - t); 1349 T e1 = (s - (s1 - t)) + (x - t);
1350 s = s1; 1350 s = s1;
1351 e += e1; 1351 e += e1;
1352 } 1352 }
1353 1353
1354 template <class T> 1354 template <typename T>
1355 inline T 1355 inline T
1356 mx_inline_xsum (const T *v, octave_idx_type n) 1356 mx_inline_xsum (const T *v, octave_idx_type n)
1357 { 1357 {
1358 T s, e; 1358 T s, e;
1359 s = e = 0; 1359 s = e = 0;
1361 twosum_accum (s, e, v[i]); 1361 twosum_accum (s, e, v[i]);
1362 1362
1363 return s + e; 1363 return s + e;
1364 } 1364 }
1365 1365
1366 template <class T> 1366 template <typename T>
1367 inline void 1367 inline void
1368 mx_inline_xsum (const T *v, T *r, 1368 mx_inline_xsum (const T *v, T *r,
1369 octave_idx_type m, octave_idx_type n) 1369 octave_idx_type m, octave_idx_type n)
1370 { 1370 {
1371 OCTAVE_LOCAL_BUFFER (T, e, m); 1371 OCTAVE_LOCAL_BUFFER (T, e, m);