comparison src/ops.h @ 8366:8b1a2555c4e2

implement diagonal matrix objects * * *
author Jaroslav Hajek <highegg@gmail.com>
date Wed, 03 Dec 2008 13:32:57 +0100
parents 283989f2da9b
children 86088b49a6d7
comparison
equal deleted inserted replaced
8365:65ca196fff28 8366:8b1a2555c4e2
24 #if !defined (octave_ops_h) 24 #if !defined (octave_ops_h)
25 #define octave_ops_h 1 25 #define octave_ops_h 1
26 26
27 #include "Array-util.h" 27 #include "Array-util.h"
28 28
29 // Concatenation macros that enforce argument prescan
30 #define CONCAT2X(x,y) x ## y
31 #define CONCAT2(x,y) CONCAT2X(x,y)
32
33 #define CONCAT3X(x,y,z) x ## y ## z
34 #define CONCAT3(x,y,z) CONCAT3X(x,y,z)
35
29 extern void install_ops (void); 36 extern void install_ops (void);
30 37
31 #define INSTALL_UNOP(op, t, f) \ 38 #define INSTALL_UNOP(op, t, f) \
32 octave_value_typeinfo::register_unary_op \ 39 octave_value_typeinfo::register_unary_op \
33 (octave_value::op, t::static_type_id (), oct_unop_ ## f); 40 (octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
34 41
35 #define INSTALL_NCUNOP(op, t, f) \ 42 #define INSTALL_NCUNOP(op, t, f) \
36 octave_value_typeinfo::register_non_const_unary_op \ 43 octave_value_typeinfo::register_non_const_unary_op \
37 (octave_value::op, t::static_type_id (), oct_unop_ ## f); 44 (octave_value::op, t::static_type_id (), CONCAT2(oct_unop_, f));
38 45
39 #define INSTALL_BINOP(op, t1, t2, f) \ 46 #define INSTALL_BINOP(op, t1, t2, f) \
40 octave_value_typeinfo::register_binary_op \ 47 octave_value_typeinfo::register_binary_op \
41 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ 48 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
42 oct_binop_ ## f); 49 CONCAT2(oct_binop_, f));
43 50
44 #define INSTALL_CATOP(t1, t2, f) \ 51 #define INSTALL_CATOP(t1, t2, f) \
45 octave_value_typeinfo::register_cat_op \ 52 octave_value_typeinfo::register_cat_op \
46 (t1::static_type_id (), t2::static_type_id (), oct_catop_ ## f); 53 (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_catop_, f));
47 54
48 #define INSTALL_ASSIGNOP(op, t1, t2, f) \ 55 #define INSTALL_ASSIGNOP(op, t1, t2, f) \
49 octave_value_typeinfo::register_assign_op \ 56 octave_value_typeinfo::register_assign_op \
50 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ 57 (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
51 oct_assignop_ ## f); 58 CONCAT2(oct_assignop_, f));
52 59
53 #define INSTALL_ASSIGNANYOP(op, t1, f) \ 60 #define INSTALL_ASSIGNANYOP(op, t1, f) \
54 octave_value_typeinfo::register_assignany_op \ 61 octave_value_typeinfo::register_assignany_op \
55 (octave_value::op, t1::static_type_id (), oct_assignop_ ## f); 62 (octave_value::op, t1::static_type_id (), CONCAT2(oct_assignop_, f));
56 63
57 #define INSTALL_ASSIGNCONV(t1, t2, tr) \ 64 #define INSTALL_ASSIGNCONV(t1, t2, tr) \
58 octave_value_typeinfo::register_pref_assign_conv \ 65 octave_value_typeinfo::register_pref_assign_conv \
59 (t1::static_type_id (), t2::static_type_id (), tr::static_type_id ()); 66 (t1::static_type_id (), t2::static_type_id (), tr::static_type_id ());
60 67
61 #define INSTALL_CONVOP(t1, t2, f) \ 68 #define INSTALL_CONVOP(t1, t2, f) \
62 octave_value_typeinfo::register_type_conv_op \ 69 octave_value_typeinfo::register_type_conv_op \
63 (t1::static_type_id (), t2::static_type_id (), oct_conv_ ## f); 70 (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
64 71
65 #define INSTALL_WIDENOP(t1, t2, f) \ 72 #define INSTALL_WIDENOP(t1, t2, f) \
66 octave_value_typeinfo::register_widening_op \ 73 octave_value_typeinfo::register_widening_op \
67 (t1::static_type_id (), t2::static_type_id (), oct_conv_ ## f); 74 (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
68 75
69 #define BOOL_OP1(xt, xn, get_x, yt, yn, get_y) \ 76 #define BOOL_OP1(xt, xn, get_x, yt, yn, get_y) \
70 xt xn = get_x; \ 77 xt xn = get_x; \
71 yt yn = get_y; 78 yt yn = get_y;
72 79
146 #define CAST_CONV_ARG(t) \ 153 #define CAST_CONV_ARG(t) \
147 t v = dynamic_cast<t> (a) 154 t v = dynamic_cast<t> (a)
148 155
149 #define ASSIGNOPDECL(name) \ 156 #define ASSIGNOPDECL(name) \
150 static octave_value \ 157 static octave_value \
151 oct_assignop_ ## name (octave_base_value& a1, \ 158 CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
152 const octave_value_list& idx, \ 159 const octave_value_list& idx, \
153 const octave_base_value& a2) 160 const octave_base_value& a2)
154 161
155 #define NULLASSIGNOPDECL(name) \ 162 #define NULLASSIGNOPDECL(name) \
156 static octave_value \ 163 static octave_value \
157 oct_assignop_ ## name (octave_base_value& a, \ 164 CONCAT2(oct_assignop_, name) (octave_base_value& a, \
158 const octave_value_list& idx, \ 165 const octave_value_list& idx, \
159 const octave_base_value&) 166 const octave_base_value&)
160 167
161 #define ASSIGNANYOPDECL(name) \ 168 #define ASSIGNANYOPDECL(name) \
162 static octave_value \ 169 static octave_value \
163 oct_assignop_ ## name (octave_base_value& a1, \ 170 CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
164 const octave_value_list& idx, \ 171 const octave_value_list& idx, \
165 const octave_value& a2) 172 const octave_value& a2)
166 173
167 #define DEFASSIGNOP(name, t1, t2) \ 174 #define DEFASSIGNOP(name, t1, t2) \
168 ASSIGNOPDECL (name) 175 ASSIGNOPDECL (name)
169 176
170 #define DEFASSIGNOP_FN(name, t1, t2, f) \ 177 #define DEFASSIGNOP_FN(name, t1, t2, f) \
171 ASSIGNOPDECL (name) \ 178 ASSIGNOPDECL (name) \
172 { \ 179 { \
173 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ 180 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
174 \ 181 \
175 v1.f (idx, v2.t1 ## _value ()); \ 182 v1.f (idx, v2.CONCAT2(t1, _value) ()); \
176 return octave_value (); \ 183 return octave_value (); \
177 } 184 }
178 185
179 #define DEFNULLASSIGNOP_FN(name, t, f) \ 186 #define DEFNULLASSIGNOP_FN(name, t, f) \
180 NULLASSIGNOPDECL (name) \ 187 NULLASSIGNOPDECL (name) \
181 { \ 188 { \
182 CAST_UNOP_ARG (octave_ ## t&); \ 189 CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
183 \ 190 \
184 v.f (idx); \ 191 v.f (idx); \
185 return octave_value (); \ 192 return octave_value (); \
186 } 193 }
187 194
188 #define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \ 195 #define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
189 ASSIGNOPDECL (name) \ 196 ASSIGNOPDECL (name) \
190 { \ 197 { \
191 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ 198 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
192 \ 199 \
193 v1.f (idx, v2.e ## _value ()); \ 200 v1.f (idx, v2.CONCAT2(e, _value) ()); \
194 return octave_value (); \ 201 return octave_value (); \
195 } 202 }
196 203
197 #define DEFASSIGNANYOP_FN(name, t1, f) \ 204 #define DEFASSIGNANYOP_FN(name, t1, f) \
198 ASSIGNANYOPDECL (name) \ 205 ASSIGNANYOPDECL (name) \
199 { \ 206 { \
200 octave_ ## t1& v1 = dynamic_cast<octave_ ## t1&> (a1); \ 207 CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
201 \ 208 \
202 v1.f (idx, a2); \ 209 v1.f (idx, a2); \
203 return octave_value (); \ 210 return octave_value (); \
204 } 211 }
205 212
206 #define CONVDECL(name) \ 213 #define CONVDECL(name) \
207 static octave_base_value * \ 214 static octave_base_value * \
208 oct_conv_ ## name (const octave_base_value& a) 215 CONCAT2(oct_conv_, name) (const octave_base_value& a)
209 216
210 #define CONVDECLX(name) \ 217 #define CONVDECLX(name) \
211 static octave_base_value * \ 218 static octave_base_value * \
212 oct_conv_ ## name (const octave_base_value&) 219 CONCAT2(oct_conv_, name) (const octave_base_value&)
213 220
214 #define DEFCONV(name, a_dummy, b_dummy) \ 221 #define DEFCONV(name, a_dummy, b_dummy) \
215 CONVDECL (name) 222 CONVDECL (name)
216 223
217 #define DEFCONVFNX(name, tfrom, ovtto, tto, e) \ 224 #define DEFCONVFNX(name, tfrom, ovtto, tto, e) \
218 CONVDECL (name) \ 225 CONVDECL (name) \
219 { \ 226 { \
220 CAST_CONV_ARG (const octave_ ## tfrom&); \ 227 CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
221 \ 228 \
222 return new octave_ ## ovtto (tto ## NDArray (v.e ## array_value ())); \ 229 return new CONCAT2(octave_, ovtto) (CONCAT2(tto, NDArray) (v.CONCAT2(e, array_value) ())); \
223 } 230 }
224 231
225 #define DEFCONVFNX2(name, tfrom, ovtto, e) \ 232 #define DEFCONVFNX2(name, tfrom, ovtto, e) \
226 CONVDECL (name) \ 233 CONVDECL (name) \
227 { \ 234 { \
228 CAST_CONV_ARG (const octave_ ## tfrom&); \ 235 CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
229 \ 236 \
230 return new octave_ ## ovtto (v.e ## array_value ()); \ 237 return new CONCAT2(octave_, ovtto) (v.CONCAT2(e, array_value) ()); \
231 } 238 }
232 239
233 #define DEFDBLCONVFN(name, ovtfrom, e) \ 240 #define DEFDBLCONVFN(name, ovtfrom, e) \
234 CONVDECL (name) \ 241 CONVDECL (name) \
235 { \ 242 { \
236 CAST_CONV_ARG (const octave_ ## ovtfrom&); \ 243 CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
237 \ 244 \
238 return new octave_matrix (NDArray (v.e ## _value ())); \ 245 return new octave_matrix (NDArray (v.CONCAT2(e, _value) ())); \
239 } 246 }
240 247
241 #define DEFSTRINTCONVFN(name, tto) \ 248 #define DEFSTRINTCONVFN(name, tto) \
242 DEFCONVFNX(name, char_matrix_str, tto ## _matrix, tto, char_) 249 DEFCONVFNX(name, char_matrix_str, CONCAT2(tto, _matrix), tto, char_)
243 250
244 #define DEFSTRDBLCONVFN(name, tfrom) \ 251 #define DEFSTRDBLCONVFN(name, tfrom) \
245 DEFCONVFNX(name, tfrom, matrix, , char_) 252 DEFCONVFNX(name, tfrom, matrix, , char_)
246 253
247 #define DEFCONVFN(name, tfrom, tto) \ 254 #define DEFCONVFN(name, tfrom, tto) \
248 DEFCONVFNX2 (name, tfrom, tto ## _matrix, tto ## _) 255 DEFCONVFNX2 (name, tfrom, CONCAT2(tto, _matrix), CONCAT2(tto, _))
249 256
250 #define DEFCONVFN2(name, tfrom, sm, tto) \ 257 #define DEFCONVFN2(name, tfrom, sm, tto) \
251 DEFCONVFNX2 (name, tfrom ## _ ## sm, tto ## _matrix, tto ## _) 258 DEFCONVFNX2 (name, CONCAT3(tfrom, _, sm), CONCAT2(tto, _matrix), CONCAT2(tto, _))
252 259
253 #define UNOPDECL(name, a) \ 260 #define UNOPDECL(name, a) \
254 static octave_value \ 261 static octave_value \
255 oct_unop_ ## name (const octave_base_value& a) 262 CONCAT2(oct_unop_, name) (const octave_base_value& a)
256 263
257 #define DEFUNOPX(name, t) \ 264 #define DEFUNOPX(name, t) \
258 UNOPDECL (name, , ) 265 UNOPDECL (name, , )
259 266
260 #define DEFUNOP(name, t) \ 267 #define DEFUNOP(name, t) \
261 UNOPDECL (name, a) 268 UNOPDECL (name, a)
262 269
263 #define DEFUNOP_OP(name, t, op) \ 270 #define DEFUNOP_OP(name, t, op) \
264 UNOPDECL (name, a) \ 271 UNOPDECL (name, a) \
265 { \ 272 { \
266 CAST_UNOP_ARG (const octave_ ## t&); \ 273 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
267 return octave_value (op v.t ## _value ()); \ 274 return octave_value (op v.CONCAT2(t, _value) ()); \
268 } 275 }
269 276
270 #define DEFNDUNOP_OP(name, t, e, op) \ 277 #define DEFNDUNOP_OP(name, t, e, op) \
271 UNOPDECL (name, a) \ 278 UNOPDECL (name, a) \
272 { \ 279 { \
273 CAST_UNOP_ARG (const octave_ ## t&); \ 280 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
274 return octave_value (op v.e ## _value ()); \ 281 return octave_value (op v.CONCAT2(e, _value) ()); \
275 } 282 }
276 283
277 // FIXME -- in some cases, the constructor isn't necessary. 284 // FIXME -- in some cases, the constructor isn't necessary.
278 285
279 #define DEFUNOP_FN(name, t, f) \ 286 #define DEFUNOP_FN(name, t, f) \
280 UNOPDECL (name, a) \ 287 UNOPDECL (name, a) \
281 { \ 288 { \
282 CAST_UNOP_ARG (const octave_ ## t&); \ 289 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
283 return octave_value (f (v.t ## _value ())); \ 290 return octave_value (f (v.CONCAT2(t, _value) ())); \
284 } 291 }
285 292
286 #define DEFNDUNOP_FN(name, t, e, f) \ 293 #define DEFNDUNOP_FN(name, t, e, f) \
287 UNOPDECL (name, a) \ 294 UNOPDECL (name, a) \
288 { \ 295 { \
289 CAST_UNOP_ARG (const octave_ ## t&); \ 296 CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
290 return octave_value (f (v.e ## _value ())); \ 297 return octave_value (f (v.CONCAT2(e, _value) ())); \
291 } 298 }
292 299
293 #define DEFNCUNOP_METHOD(name, t, method) \ 300 #define DEFNCUNOP_METHOD(name, t, method) \
294 static void \ 301 static void \
295 oct_unop_ ## name (octave_base_value& a) \ 302 CONCAT2(oct_unop_, name) (octave_base_value& a) \
296 { \ 303 { \
297 CAST_UNOP_ARG (octave_ ## t&); \ 304 CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
298 v.method (); \ 305 v.method (); \
299 } 306 }
300 307
301 #define BINOPDECL(name, a1, a2) \ 308 #define BINOPDECL(name, a1, a2) \
302 static octave_value \ 309 static octave_value \
303 oct_binop_ ## name (const octave_base_value& a1, const octave_base_value& a2) 310 CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2)
304 311
305 #define DEFBINOPX(name, t1, t2) \ 312 #define DEFBINOPX(name, t1, t2) \
306 BINOPDECL (name, , ) 313 BINOPDECL (name, , )
307 314
308 #define DEFBINOP(name, t1, t2) \ 315 #define DEFBINOP(name, t1, t2) \
309 BINOPDECL (name, a1, a2) 316 BINOPDECL (name, a1, a2)
310 317
311 #define DEFBINOP_OP(name, t1, t2, op) \ 318 #define DEFBINOP_OP(name, t1, t2, op) \
312 BINOPDECL (name, a1, a2) \ 319 BINOPDECL (name, a1, a2) \
313 { \ 320 { \
314 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ 321 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
315 return octave_value \ 322 return octave_value \
316 (v1.t1 ## _value () op v2.t2 ## _value ()); \ 323 (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
317 } 324 }
318 325
319 #define DEFSCALARBOOLOP_OP(name, t1, t2, op) \ 326 #define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
320 BINOPDECL (name, a1, a2) \ 327 BINOPDECL (name, a1, a2) \
321 { \ 328 { \
322 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ 329 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
323 if (xisnan (v1.t1 ## _value ()) || xisnan (v2.t2 ## _value ())) \ 330 if (xisnan (v1.CONCAT2(t1, _value) ()) || xisnan (v2.CONCAT2(t2, _value) ())) \
324 { \ 331 { \
325 error ("invalid conversion from NaN to logical"); \ 332 error ("invalid conversion from NaN to logical"); \
326 return octave_value (); \ 333 return octave_value (); \
327 } \ 334 } \
328 else \ 335 else \
329 return octave_value \ 336 return octave_value \
330 (v1.t1 ## _value () op v2.t2 ## _value ()); \ 337 (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
331 } 338 }
332 339
333 #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \ 340 #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
334 BINOPDECL (name, a1, a2) \ 341 BINOPDECL (name, a1, a2) \
335 { \ 342 { \
336 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ 343 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
337 return octave_value \ 344 return octave_value \
338 (v1.e1 ## _value () op v2.e2 ## _value ()); \ 345 (v1.CONCAT2(e1, _value) () op v2.CONCAT2(e2, _value) ()); \
339 } 346 }
340 347
341 // FIXME -- in some cases, the constructor isn't necessary. 348 // FIXME -- in some cases, the constructor isn't necessary.
342 349
343 #define DEFBINOP_FN(name, t1, t2, f) \ 350 #define DEFBINOP_FN(name, t1, t2, f) \
344 BINOPDECL (name, a1, a2) \ 351 BINOPDECL (name, a1, a2) \
345 { \ 352 { \
346 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ 353 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
347 return octave_value (f (v1.t1 ## _value (), v2.t2 ## _value ())); \ 354 return octave_value (f (v1.CONCAT2(t1, _value) (), v2.CONCAT2(t2, _value) ())); \
348 } 355 }
349 356
350 #define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \ 357 #define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
351 BINOPDECL (name, a1, a2) \ 358 BINOPDECL (name, a1, a2) \
352 { \ 359 { \
353 CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ 360 CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
354 return octave_value (f (v1.e1 ## _value (), v2.e2 ## _value ())); \ 361 return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
355 } 362 }
356 363
357 #define BINOP_NONCONFORMANT(msg) \ 364 #define BINOP_NONCONFORMANT(msg) \
358 gripe_nonconformant (msg, \ 365 gripe_nonconformant (msg, \
359 a1.rows (), a1.columns (), \ 366 a1.rows (), a1.columns (), \
360 a2.rows (), a2.columns ()); \ 367 a2.rows (), a2.columns ()); \
361 return octave_value () 368 return octave_value ()
362 369
363 #define CATOPDECL(name, a1, a2) \ 370 #define CATOPDECL(name, a1, a2) \
364 static octave_value \ 371 static octave_value \
365 oct_catop_ ## name (octave_base_value& a1, const octave_base_value& a2, \ 372 CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
366 const Array<octave_idx_type>& ra_idx) 373 const Array<octave_idx_type>& ra_idx)
367 374
368 #define DEFCATOPX(name, t1, t2) \ 375 #define DEFCATOPX(name, t1, t2) \
369 CATOPDECL (name, , ) 376 CATOPDECL (name, , )
370 377
374 // FIXME -- in some cases, the constructor isn't necessary. 381 // FIXME -- in some cases, the constructor isn't necessary.
375 382
376 #define DEFCATOP_FN(name, t1, t2, f) \ 383 #define DEFCATOP_FN(name, t1, t2, f) \
377 CATOPDECL (name, a1, a2) \ 384 CATOPDECL (name, a1, a2) \
378 { \ 385 { \
379 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ 386 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
380 return octave_value (v1.t1 ## _value () . f (v2.t2 ## _value (), ra_idx)); \ 387 return octave_value (v1.CONCAT2(t1, _value) () . f (v2.CONCAT2(t2, _value) (), ra_idx)); \
381 } 388 }
382 389
383 #define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \ 390 #define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
384 CATOPDECL (name, a1, a2) \ 391 CATOPDECL (name, a1, a2) \
385 { \ 392 { \
386 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ 393 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
387 return octave_value (v1.e1 ## _value () . f (v2.e2 ## _value (), ra_idx)); \ 394 return octave_value (v1.CONCAT2(e1, _value) () . f (v2.CONCAT2(e2, _value) (), ra_idx)); \
388 } 395 }
389 396
390 #define DEFNDCHARCATOP_FN(name, t1, t2, f) \ 397 #define DEFNDCHARCATOP_FN(name, t1, t2, f) \
391 CATOPDECL (name, a1, a2) \ 398 CATOPDECL (name, a1, a2) \
392 { \ 399 { \
393 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ 400 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
394 \ 401 \
395 return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \ 402 return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
396 true, ((a1.is_sq_string () || a2.is_sq_string ()) \ 403 true, ((a1.is_sq_string () || a2.is_sq_string ()) \
397 ? '\'' : '"')); \ 404 ? '\'' : '"')); \
398 } 405 }
401 // of the first. Hmm. 408 // of the first. Hmm.
402 409
403 #define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \ 410 #define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
404 CATOPDECL (name, a1, a2) \ 411 CATOPDECL (name, a1, a2) \
405 { \ 412 { \
406 CAST_BINOP_ARGS (octave_ ## t1&, const octave_ ## t2&); \ 413 CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
407 return octave_value (tc1 (v1.e1 ## _value ()) . f (tc2 (v2.e2 ## _value ()), ra_idx)); \ 414 return octave_value (tc1 (v1.CONCAT2(e1, _value) ()) . f (tc2 (v2.CONCAT2(e2, _value) ()), ra_idx)); \
408 } 415 }
409 416
410 #define CATOP_NONCONFORMANT(msg) \ 417 #define CATOP_NONCONFORMANT(msg) \
411 gripe_nonconformant (msg, \ 418 gripe_nonconformant (msg, \
412 a1.rows (), a1.columns (), \ 419 a1.rows (), a1.columns (), \