source: XMLIO_V2/external/include/blitz/array/functorExpr.h @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 41.7 KB
Line 
1// -*- C++ -*-
2/***************************************************************************
3 * blitz/array/functorExpr.h   User-defined functors for arrays
4 *
5 * $Id: functorExpr.h,v 1.8 2005/05/07 04:17:57 julianc Exp $
6 *
7 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * Suggestions:          blitz-dev@oonumerics.org
20 * Bugs:                 blitz-bugs@oonumerics.org
21 *
22 * For more information, please see the Blitz++ Home Page:
23 *    http://oonumerics.org/blitz/
24 *
25 ****************************************************************************/
26/* This header file is designed to allow the use of Blitz++ with
27   functors (classes defining an operator()) and more general member
28   functions. It works best if you have access to the class source code;
29   there is limited support for classes that cannot be modified. The best
30   approach in that case is usually to write an adapter class.
31
32   This works with class methods that take one, two or three arguments.
33
34   If you have a functor, add the following to your (public) class declaration:
35
36   BZ_DECLARE_FUNCTOR(classname)   // for one argument functors
37   BZ_DECLARE_FUNCTOR2(classname)  // for two argument functors
38   BZ_DECLARE_FUNCTOR3(classname)  // for three argument functors
39   
40   or
41
42   BZ_DECLARE_FUNCTOR_RET(classname, returnType)
43   BZ_DECLARE_FUNCTOR2_RET(classname, returnType)
44   BZ_DECLARE_FUNCTOR3_RET(classname, returnType)
45
46   for classes whose operator() has a return type that is not what you would
47   deduce from the usual C++ promotion rules (e.g., takes two doubles and
48   returns a bool).
49
50   You can then use your class in Blitz++ expressions and no temporaries will
51   be generated. For example, assuming that your class is named T, and that
52   A, B and C are Arrays, you can write
53
54   T classInstance( ... );
55   A = C + classInstance(B * tensor::i);
56   A = C + classInstance(tensor::i, tensor::j)
57
58   It also works for member functions:
59   
60   BZ_DECLARE_MEMBER_FUNCTION(classname, funcname)
61   BZ_DECLARE_MEMBER_FUNCTION2(classname, funcname)
62   BZ_DECLARE_MEMBER_FUNCTION3(classname, funcname)
63   
64   or
65   
66   BZ_DECLARE_MEMBER_FUNCTION_RET(classname, funcname, returnType)
67   BZ_DECLARE_MEMBER_FUNCTION2_RET(classname, funcname, returnType)
68   BZ_DECLARE_MEMBER_FUNCTION3_RET(classname, funcname, returnType)
69
70   allows you to write stuff like
71   
72   A = C + classInstance.funcname(B * tensor::i);
73   A = C + classInstance.funcname(tensor::i, tensor::j)
74   
75   All the member functions to be applied must be declared const.
76     
77   There is also some support for classes where the source code is not
78   available or not to be tampered with.  For example,
79     
80   A = C + applyFunctor(classInstance, B * tensor::i);
81   A = C + applyFunctor(classInstance, tensor::i, tensor::j);
82   
83   This approach does not work for arbitrary member functions.  The
84   class must be a proper functor with an operator(). 
85
86*/
87
88#ifndef BZ_ARRAY_FUNCTOREXPR_H
89#define BZ_ARRAY_FUNCTOREXPR_H
90
91#ifndef BZ_ARRAY_H
92 #error <blitz/array/functorExpr.h> must be included via <blitz/array.h>
93#endif
94
95#include <blitz/prettyprint.h>
96#include <blitz/shapecheck.h>
97#include <blitz/tinyvec.h>
98
99BZ_NAMESPACE(blitz)
100
101template<typename P_functor, typename P_expr, typename P_result>
102class _bz_FunctorExpr {
103public:
104    typedef P_functor T_functor;
105    typedef P_expr T_expr;
106    typedef _bz_typename T_expr::T_numtype T_numtype1;
107    typedef P_result T_numtype;
108    typedef T_expr    T_ctorArg1;
109    typedef int       T_ctorArg2;    // dummy
110    typedef int       T_ctorArg3;    // dummy
111
112    static const int 
113        numArrayOperands = T_expr::numArrayOperands,
114        numIndexPlaceholders = T_expr::numIndexPlaceholders,
115        rank = T_expr::rank;
116   
117    _bz_FunctorExpr(const _bz_FunctorExpr<P_functor,P_expr,P_result>& a)
118        : f_(a.f_), iter_(a.iter_)
119    { }
120   
121    _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr) a)
122        : f_(f), iter_(a)
123    { }
124
125    _bz_FunctorExpr(BZ_ETPARM(T_functor) f, _bz_typename T_expr::T_ctorArg1 a)
126        : f_(f), iter_(a)
127    { }
128
129#if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC
130    template<typename T1>
131    explicit _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a)
132        : f_(f), iter_(a)
133    { }
134#endif
135
136    T_numtype operator*()
137    { return f_(*iter_); }
138
139#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
140    template<int N_rank>
141    T_numtype operator()(TinyVector<int,N_rank> i)
142    { return f_(iter_(i)); }
143#else
144    template<int N_rank>
145    T_numtype operator()(const TinyVector<int,N_rank>& i)
146    { return f_(iter_(i)); }
147#endif
148
149    int ascending(int rank)
150    { return iter_.ascending(rank); }
151
152    int ordering(int rank)
153    { return iter_.ordering(rank); }
154
155    int lbound(int rank)
156    { return iter_.lbound(rank); }
157
158    int ubound(int rank)
159    { return iter_.ubound(rank); }
160 
161    void push(int position)
162    { iter_.push(position); }
163
164    void pop(int position)
165    { iter_.pop(position); }
166
167    void advance()
168    { iter_.advance(); }
169
170    void advance(int n)
171    { iter_.advance(n); }
172
173    void loadStride(int rank)
174    { iter_.loadStride(rank); }
175
176    bool isUnitStride(int rank) const
177    { return iter_.isUnitStride(rank); }
178
179    void advanceUnitStride()
180    { iter_.advanceUnitStride(); }
181 
182    bool canCollapse(int outerLoopRank, int innerLoopRank) const
183    { 
184        return iter_.canCollapse(outerLoopRank, innerLoopRank); 
185    }
186
187    T_numtype operator[](int i)
188    { return f_(iter_[i]); }
189
190    T_numtype fastRead(int i)
191    { return f_(iter_.fastRead(i)); }
192
193    int suggestStride(int rank) const
194    { return iter_.suggestStride(rank); }
195
196    bool isStride(int rank, int stride) const
197    { return iter_.isStride(rank,stride); }
198
199    void prettyPrint(BZ_STD_SCOPE(string) &str, 
200        prettyPrintFormat& format) const
201    {
202        str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor);
203        str += "(";
204        iter_.prettyPrint(str, format);
205        str += ")";
206    }
207
208    template<typename T_shape>
209    bool shapeCheck(const T_shape& shape)
210    { return iter_.shapeCheck(shape); }
211
212    template<int N_rank>
213    void moveTo(const TinyVector<int,N_rank>& i)
214    {
215        iter_.moveTo(i);
216    }
217
218protected:
219    _bz_FunctorExpr() { }
220
221    T_functor f_;
222    T_expr iter_;
223};
224
225template<typename P_functor, typename P_expr1, typename P_expr2, typename P_result>
226class _bz_FunctorExpr2
227{
228public:
229    typedef P_functor T_functor;
230    typedef P_expr1 T_expr1;
231    typedef P_expr2 T_expr2;
232    typedef _bz_typename T_expr1::T_numtype T_numtype1;
233    typedef _bz_typename T_expr2::T_numtype T_numtype2;
234    typedef P_result T_numtype;
235    typedef T_expr1 T_ctorArg1;
236    typedef T_expr1 T_ctorArg2;
237    typedef int T_ctorArg3;  // dummy
238
239    static const int 
240        numArrayOperands = T_expr1::numArrayOperands
241                         + T_expr2::numArrayOperands,
242        numIndexPlaceholders = T_expr1::numIndexPlaceholders
243                             + T_expr2::numIndexPlaceholders,
244        rank = T_expr1::rank > T_expr2::rank
245             ? T_expr1::rank : T_expr2::rank;
246 
247    _bz_FunctorExpr2(const _bz_FunctorExpr2<P_functor, P_expr1, P_expr2,
248        P_result>& a) 
249        : f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_)
250    { }
251
252    _bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a,
253        BZ_ETPARM(T_expr2) b)
254        : f_(f), iter1_(a), iter2_(b)
255    { }
256
257    template<typename T1, typename T2>
258    _bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b) 
259        : f_(f), iter1_(a), iter2_(b)
260    { }
261 
262    T_numtype operator*()
263    { return f_(*iter1_, *iter2_); }
264
265#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
266    template<int N_rank>
267    T_numtype operator()(TinyVector<int, N_rank> i)
268    { return f_(iter1_(i), iter2_(i)); }
269#else
270    template<int N_rank>
271    T_numtype operator()(const TinyVector<int, N_rank>& i)
272    { return f_(iter1_(i), iter2_(i)); }
273#endif
274
275    int ascending(int rank)
276    {
277        return bounds::compute_ascending(rank, iter1_.ascending(rank),
278            iter2_.ascending(rank));
279    }
280
281    int ordering(int rank)
282    {
283        return bounds::compute_ordering(rank, iter1_.ordering(rank),
284            iter2_.ordering(rank));
285    }
286 
287    int lbound(int rank)
288    { 
289        return bounds::compute_lbound(rank, iter1_.lbound(rank),
290            iter2_.lbound(rank));
291    }
292 
293    int ubound(int rank)
294    {
295        return bounds::compute_ubound(rank, iter1_.ubound(rank),
296            iter2_.ubound(rank));
297    }
298 
299    void push(int position)
300    { 
301        iter1_.push(position); 
302        iter2_.push(position);
303    }
304 
305    void pop(int position)
306    { 
307        iter1_.pop(position); 
308        iter2_.pop(position);
309    }
310 
311    void advance()
312    { 
313        iter1_.advance(); 
314        iter2_.advance();
315    }
316 
317    void advance(int n)
318    {
319        iter1_.advance(n);
320        iter2_.advance(n);
321    }
322 
323    void loadStride(int rank)
324    {
325        iter1_.loadStride(rank); 
326        iter2_.loadStride(rank);
327    }
328 
329    bool isUnitStride(int rank) const
330    { return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); }
331 
332    void advanceUnitStride()
333    { 
334        iter1_.advanceUnitStride(); 
335        iter2_.advanceUnitStride();
336    }
337 
338    bool canCollapse(int outerLoopRank, int innerLoopRank) const
339    { 
340        return iter1_.canCollapse(outerLoopRank, innerLoopRank)
341            && iter2_.canCollapse(outerLoopRank, innerLoopRank);
342    } 
343
344    T_numtype operator[](int i)
345    { return f_(iter1_[i], iter2_[i]); }
346
347    T_numtype fastRead(int i)
348    { return f_(iter1_.fastRead(i), iter2_.fastRead(i)); }
349
350    int suggestStride(int rank) const
351    {
352        int stride1 = iter1_.suggestStride(rank);
353        int stride2 = iter2_.suggestStride(rank);
354        return ( stride1>stride2 ? stride1 : stride2 );
355    }
356 
357    bool isStride(int rank, int stride) const
358    {
359        return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride);
360    }
361 
362    void prettyPrint(BZ_STD_SCOPE(string) &str, 
363        prettyPrintFormat& format) const
364    {
365        str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor);
366        str += "(";
367        iter1_.prettyPrint(str, format);
368        str += ",";
369        iter2_.prettyPrint(str, format);
370        str += ")";
371    }
372
373    template<int N_rank>
374    void moveTo(const TinyVector<int,N_rank>& i)
375    {
376        iter1_.moveTo(i);
377        iter2_.moveTo(i);
378    }
379 
380    template<typename T_shape>
381    bool shapeCheck(const T_shape& shape)
382    { return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); }
383 
384protected:
385    _bz_FunctorExpr2() { }
386
387    T_functor f_;
388    T_expr1 iter1_;
389    T_expr2 iter2_;
390};
391
392template<typename P_functor, typename P_expr1, typename P_expr2, typename P_expr3,
393    class P_result>
394class _bz_FunctorExpr3
395{
396public:
397    typedef P_functor T_functor;
398    typedef P_expr1 T_expr1;
399    typedef P_expr2 T_expr2;
400    typedef P_expr3 T_expr3;
401    typedef _bz_typename T_expr1::T_numtype T_numtype1;
402    typedef _bz_typename T_expr2::T_numtype T_numtype2;
403    typedef _bz_typename T_expr3::T_numtype T_numtype3;
404    typedef P_result T_numtype;
405    typedef T_expr1 T_ctorArg1;
406    typedef T_expr2 T_ctorArg2;
407    typedef T_expr3 T_ctorArg3;
408
409    static const int 
410        numArrayOperands = T_expr1::numArrayOperands
411                         + T_expr2::numArrayOperands
412                         + T_expr3::numArrayOperands,
413        numIndexPlaceholders = T_expr1::numIndexPlaceholders
414                             + T_expr2::numIndexPlaceholders
415                             + T_expr3::numIndexPlaceholders,
416        rank12 = T_expr1::rank > T_expr2::rank
417               ? T_expr1::rank : T_expr2::rank,
418        rank = rank12 > T_expr3::rank ? rank12 : T_expr3::rank;
419 
420    _bz_FunctorExpr3(const _bz_FunctorExpr3<P_functor, P_expr1, P_expr2,
421        P_expr3, P_result>& a) 
422        : f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_)
423    { }
424
425    _bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a,
426        BZ_ETPARM(T_expr2) b, BZ_ETPARM(T_expr3) c)
427        : f_(f), iter1_(a), iter2_(b), iter3_(c)
428    { }
429
430    template<typename T1, typename T2, typename T3>
431    _bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b,
432        BZ_ETPARM(T3) c) 
433        : f_(f), iter1_(a), iter2_(b), iter3_(c)
434    { }
435 
436    T_numtype operator*()
437    { return f_(*iter1_, *iter2_, *iter3_); }
438
439#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
440    template<int N_rank>
441    T_numtype operator()(TinyVector<int, N_rank> i)
442    { return f_(iter1_(i), iter2_(i), iter3_(i)); }
443#else
444    template<int N_rank>
445    T_numtype operator()(const TinyVector<int, N_rank>& i)
446    { return f_(iter1_(i), iter2_(i), iter3_(i)); }
447#endif
448
449    int ascending(int rank)
450    {
451        return bounds::compute_ascending(rank, iter1_.ascending(rank),
452            bounds::compute_ascending(rank, iter2_.ascending(rank),
453            iter3_.ascending(rank)));
454    }
455
456    int ordering(int rank)
457    {
458        return bounds::compute_ordering(rank, iter1_.ordering(rank),
459            bounds::compute_ordering(rank, iter2_.ordering(rank),
460            iter3_.ordering(rank)));
461    }
462 
463    int lbound(int rank)
464    { 
465        return bounds::compute_lbound(rank, iter1_.lbound(rank),
466            bounds::compute_lbound(rank, iter2_.lbound(rank),
467            iter3_.lbound(rank)));
468    }
469 
470    int ubound(int rank)
471    {
472        return bounds::compute_ubound(rank, iter1_.ubound(rank),
473            bounds::compute_ubound(rank, iter2_.ubound(rank),
474            iter3_.ubound(rank)));
475    }
476 
477    void push(int position)
478    { 
479        iter1_.push(position); 
480        iter2_.push(position);
481        iter3_.push(position);
482    }
483 
484    void pop(int position)
485    { 
486        iter1_.pop(position); 
487        iter2_.pop(position);
488        iter3_.pop(position);
489    }
490 
491    void advance()
492    { 
493        iter1_.advance(); 
494        iter2_.advance();
495        iter3_.advance();
496    }
497 
498    void advance(int n)
499    {
500        iter1_.advance(n);
501        iter2_.advance(n);
502        iter3_.advance(n);
503    }
504 
505    void loadStride(int rank)
506    { 
507        iter1_.loadStride(rank); 
508        iter2_.loadStride(rank);
509        iter3_.loadStride(rank);
510    }
511 
512    bool isUnitStride(int rank) const
513    {
514        return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank)
515            && iter3_.isUnitStride(rank);
516    }
517 
518    void advanceUnitStride()
519    { 
520        iter1_.advanceUnitStride(); 
521        iter2_.advanceUnitStride();
522        iter3_.advanceUnitStride();
523    }
524 
525    bool canCollapse(int outerLoopRank, int innerLoopRank) const
526    { 
527        return iter1_.canCollapse(outerLoopRank, innerLoopRank)
528            && iter2_.canCollapse(outerLoopRank, innerLoopRank)
529            && iter3_.canCollapse(outerLoopRank, innerLoopRank);
530    } 
531
532    T_numtype operator[](int i)
533    { return f_(iter1_[i], iter2_[i], iter3_[i]); }
534
535    T_numtype fastRead(int i)
536    { return f_(iter1_.fastRead(i), iter2_.fastRead(i), iter3_.fastRead(i)); }
537
538    int suggestStride(int rank) const
539    {
540        int stride1 = iter1_.suggestStride(rank);
541        int stride2 = iter2_.suggestStride(rank);
542        int stride3 = iter3_.suggestStride(rank);
543        return ( stride1 > (stride2 = (stride2>stride3 ? stride2 : stride3)) ?
544            stride1 : stride2 );
545    }
546 
547    bool isStride(int rank, int stride) const
548    {
549        return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride)
550            && iter3_.isStride(rank,stride);
551    }
552 
553    void prettyPrint(BZ_STD_SCOPE(string) &str, 
554        prettyPrintFormat& format) const
555    {
556        str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor);
557        str += "(";
558        iter1_.prettyPrint(str, format);
559        str += ",";
560        iter2_.prettyPrint(str, format);
561        str += ",";
562        iter3_.prettyPrint(str, format);
563        str += ")";
564    }
565
566    template<int N_rank>
567    void moveTo(const TinyVector<int,N_rank>& i)
568    {
569        iter1_.moveTo(i);
570        iter2_.moveTo(i);
571        iter3_.moveTo(i);
572    }
573 
574    template<typename T_shape>
575    bool shapeCheck(const T_shape& shape)
576    {
577        return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape)
578            && iter3_.shapeCheck(shape);
579    }
580 
581protected:
582    _bz_FunctorExpr3() { }
583
584    T_functor f_;
585    T_expr1 iter1_;
586    T_expr2 iter2_;
587    T_expr3 iter3_;
588};
589
590template<typename P_functor, typename P_expr>
591_bz_inline_et
592_bz_ArrayExpr<_bz_FunctorExpr<P_functor, _bz_typename asExpr<P_expr>::T_expr,
593    _bz_typename asExpr<P_expr>::T_expr::T_numtype> >
594applyFunctor(const P_functor& f, const ETBase<P_expr>& a)
595{
596    typedef _bz_FunctorExpr<P_functor,
597        _bz_typename asExpr<P_expr>::T_expr,
598        _bz_typename asExpr<P_expr>::T_expr::T_numtype> f1;
599    return _bz_ArrayExpr<f1>(f, a.unwrap());
600}
601
602template<typename P_functor, typename P_expr1, typename P_expr2>
603_bz_inline_et
604_bz_ArrayExpr<_bz_FunctorExpr2<P_functor,
605    _bz_typename asExpr<P_expr1>::T_expr,
606    _bz_typename asExpr<P_expr2>::T_expr,
607    BZ_PROMOTE(_bz_typename asExpr<P_expr1>::T_expr::T_numtype,
608               _bz_typename asExpr<P_expr2>::T_expr::T_numtype)> >
609applyFunctor(const P_functor& f,
610    const ETBase<P_expr1>& a, const ETBase<P_expr2>& b)
611{
612    typedef _bz_FunctorExpr2<P_functor,
613        _bz_typename asExpr<P_expr1>::T_expr,
614        _bz_typename asExpr<P_expr2>::T_expr,
615        BZ_PROMOTE(_bz_typename asExpr<P_expr1>::T_expr::T_numtype,
616                   _bz_typename asExpr<P_expr2>::T_expr::T_numtype)> f2;
617    return _bz_ArrayExpr<f2>(f, a.unwrap(), b.unwrap());
618}
619
620template<typename P_functor, typename P_expr1, typename P_expr2, typename P_expr3>
621_bz_inline_et
622_bz_ArrayExpr<_bz_FunctorExpr3<P_functor,
623    _bz_typename asExpr<P_expr1>::T_expr,
624    _bz_typename asExpr<P_expr2>::T_expr, 
625    _bz_typename asExpr<P_expr3>::T_expr,
626    BZ_PROMOTE(_bz_typename asExpr<P_expr1>::T_expr::T_numtype,
627               BZ_PROMOTE(_bz_typename asExpr<P_expr2>::T_expr::T_numtype,
628                          _bz_typename asExpr<P_expr3>::T_expr::T_numtype))> >
629applyFunctor(const P_functor& f, const ETBase<P_expr1>& a,
630    const ETBase<P_expr2>& b, const ETBase<P_expr3>& c)
631{
632    typedef _bz_FunctorExpr3<P_functor,
633        _bz_typename asExpr<P_expr1>::T_expr,
634        _bz_typename asExpr<P_expr2>::T_expr,
635        _bz_typename asExpr<P_expr3>::T_expr,
636        BZ_PROMOTE(_bz_typename asExpr<P_expr1>::T_expr::T_numtype,
637            BZ_PROMOTE(_bz_typename asExpr<P_expr2>::T_expr::T_numtype,
638                       _bz_typename asExpr<P_expr3>::T_expr::T_numtype))> f3;
639    return _bz_ArrayExpr<f3>(f, a.unwrap(), b.unwrap(), c.unwrap());
640}
641
642BZ_NAMESPACE_END // End of stuff in namespace
643
644
645#define _BZ_MAKE_FUNCTOR(classname, funcname)                             \
646class _bz_Functor ## classname ## funcname                                \
647{                                                                         \
648public:                                                                   \
649    _bz_Functor ## classname ## funcname (const classname& c)             \
650        : c_(c)                                                           \
651    { }                                                                   \
652    template<typename T_numtype1>                                            \
653    inline T_numtype1 operator()(T_numtype1 x) const                      \
654    { return c_.funcname(x); }                                            \
655private:                                                                  \
656    const classname& c_;                                                  \
657};
658
659#define _BZ_MAKE_FUNCTOR2(classname, funcname)                            \
660class _bz_Functor ## classname ## funcname                                \
661{                                                                         \
662public:                                                                   \
663    _bz_Functor ## classname ## funcname (const classname& c)             \
664        : c_(c)                                                           \
665    { }                                                                   \
666    template<typename T_numtype1, typename T_numtype2>                          \
667    inline BZ_PROMOTE(T_numtype1, T_numtype2)                             \
668    operator()(T_numtype1 x, T_numtype2 y) const                          \
669    { return c_.funcname(x,y); }                                          \
670private:                                                                  \
671    const classname& c_;                                                  \
672};
673
674#define _BZ_MAKE_FUNCTOR3(classname, funcname)                            \
675class _bz_Functor ## classname ## funcname                                \
676{                                                                         \
677public:                                                                   \
678    _bz_Functor ## classname ## funcname (const classname& c)             \
679        : c_(c)                                                           \
680    { }                                                                   \
681    template<typename T_numtype1, typename T_numtype2, typename T_numtype3>        \
682    inline BZ_PROMOTE(BZ_PROMOTE(T_numtype1, T_numtype2), T_numtype3)     \
683    operator()(T_numtype1 x, T_numtype2 y, T_numtype3 z) const            \
684    { return c_.funcname(x,y,z); }                                        \
685private:                                                                  \
686    const classname& c_;                                                  \
687};
688
689
690#define _BZ_MAKE_FUNCTOR_RET(classname, funcname, ret)                    \
691class _bz_Functor ## classname ## funcname                                \
692{                                                                         \
693public:                                                                   \
694    _bz_Functor ## classname ## funcname (const classname& c)             \
695        : c_(c)                                                           \
696    { }                                                                   \
697    template<typename T_numtype1>                                            \
698    inline ret operator()(T_numtype1 x) const                             \
699    { return c_.funcname(x); }                                            \
700private:                                                                  \
701    const classname& c_;                                                  \
702};
703
704#define _BZ_MAKE_FUNCTOR2_RET(classname, funcname, ret)                   \
705class _bz_Functor ## classname ## funcname                                \
706{                                                                         \
707public:                                                                   \
708    _bz_Functor ## classname ## funcname (const classname& c)             \
709        : c_(c)                                                           \
710    { }                                                                   \
711    template<typename T_numtype1, typename T_numtype2>                          \
712    inline ret operator()(T_numtype1 x, T_numtype2 y) const               \
713    { return c_.funcname(x,y); }                                          \
714private:                                                                  \
715    const classname& c_;                                                  \
716};
717
718#define _BZ_MAKE_FUNCTOR3_RET(classname, funcname, ret)                   \
719class _bz_Functor ## classname ## funcname                                \
720{                                                                         \
721public:                                                                   \
722    _bz_Functor ## classname ## funcname (const classname& c)             \
723        : c_(c)                                                           \
724    { }                                                                   \
725    template<typename T_numtype1, typename T_numtype2, typename T_numtype3>        \
726    inline ret operator()(T_numtype1 x, T_numtype2 y, T_numtype3 z) const \
727    { return c_.funcname(x,y,z); }                                        \
728private:                                                                  \
729    const classname& c_;                                                  \
730};
731
732
733#define BZ_DECLARE_FUNCTOR(classname)                                     \
734template<typename P_expr>                                                 \
735BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)<            \
736    classname,                                                            \
737    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,                  \
738    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> >     \
739operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const                 \
740{                                                                         \
741    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
742        BZ_BLITZ_SCOPE(_bz_FunctorExpr)<classname,                        \
743        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,              \
744        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \
745        (*this, a.unwrap());                                              \
746}
747
748#define BZ_DECLARE_FUNCTOR2(classname)                                    \
749template<typename P_expr1, typename P_expr2>                              \
750BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<           \
751    classname,                                                            \
752    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
753    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
754    BZ_PROMOTE(_bz_typename                                               \
755               BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,        \
756               _bz_typename                                               \
757               BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> >     \
758operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                      \
759           const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const                \
760{                                                                         \
761    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
762        BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<classname,                       \
763        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
764        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
765        BZ_PROMOTE(_bz_typename                                           \
766                   BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,    \
767                   _bz_typename                                           \
768                   BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \
769        (*this, a.unwrap(), b.unwrap());                                  \
770}
771
772#define BZ_DECLARE_FUNCTOR3(classname)                                    \
773template<typename P_expr1, typename P_expr2, typename P_expr3>            \
774BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<           \
775    classname,                                                            \
776    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
777    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
778    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,                 \
779    BZ_PROMOTE(_bz_typename                                               \
780               BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,        \
781    BZ_PROMOTE(_bz_typename                                               \
782               BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype,        \
783               _bz_typename                                               \
784               BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >    \
785operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                      \
786           const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b,                      \
787           const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const                \
788{                                                                         \
789    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
790        BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<classname,                       \
791        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
792        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
793        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,             \
794        BZ_PROMOTE(_bz_typename                                           \
795                   BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,    \
796        BZ_PROMOTE(_bz_typename                                           \
797                   BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype,    \
798                   _bz_typename                                           \
799                   BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >\
800        (*this, a.unwrap(), b.unwrap(), c.unwrap());                      \
801}
802
803
804#define BZ_DECLARE_FUNCTOR_RET(classname, ret)                            \
805template<typename P_expr>                                                 \
806BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)<            \
807    classname,                                                            \
808    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,                  \
809    ret> >                                                                \
810operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const                 \
811{                                                                         \
812    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
813        BZ_BLITZ_SCOPE(_bz_FunctorExpr)<classname,                        \
814        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,              \
815        ret> >                                                            \
816        (*this, a.unwrap());                                              \
817}
818
819#define BZ_DECLARE_FUNCTOR2_RET(classname, ret)                           \
820template<typename P_expr1, typename P_expr2>                              \
821BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<           \
822    classname,                                                            \
823    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
824    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
825    ret> >                                                                \
826operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                      \
827           const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const                \
828{                                                                         \
829    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
830        BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<classname,                       \
831        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
832        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
833        ret> >                                                            \
834        (*this, a.unwrap(), b.unwrap());                                  \
835}
836
837#define BZ_DECLARE_FUNCTOR3_RET(classname, ret)                           \
838template<typename P_expr1, typename P_expr2, typename P_expr3>            \
839BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<           \
840    classname,                                                            \
841    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
842    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
843    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,                 \
844    ret> >                                                                \
845operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                      \
846           const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b,                      \
847           const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const                \
848{                                                                         \
849    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
850        BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<classname,                       \
851        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
852        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
853        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,             \
854        ret> >                                                            \
855        (*this, a.unwrap(), b.unwrap(), c.unwrap());                      \
856}
857
858
859#define BZ_DECLARE_MEMBER_FUNCTION(classname, funcname)                   \
860_BZ_MAKE_FUNCTOR(classname, funcname)                                     \
861template<typename P_expr>                                                 \
862BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)<            \
863    _bz_Functor ## classname ## funcname,                                 \
864    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,                  \
865    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> >     \
866funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const                   \
867{                                                                         \
868    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
869        BZ_BLITZ_SCOPE(_bz_FunctorExpr)<                                  \
870        _bz_Functor ## classname ## funcname,                             \
871        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,              \
872        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \
873        (*this, a.unwrap());                                              \
874}
875
876#define BZ_DECLARE_MEMBER_FUNCTION2(classname, funcname)                  \
877_BZ_MAKE_FUNCTOR2(classname, funcname)                                    \
878template<typename P_expr1, typename P_expr2>                              \
879BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<           \
880    _bz_Functor ## classname ## funcname,                                 \
881    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
882    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
883    BZ_PROMOTE(_bz_typename                                               \
884               BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,        \
885               _bz_typename                                               \
886               BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> >     \
887funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                        \
888         const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const                  \
889{                                                                         \
890    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
891        BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<                                 \
892        _bz_Functor ## classname ## funcname,                             \
893        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
894        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
895        BZ_PROMOTE(_bz_typename                                           \
896                   BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,    \
897                   _bz_typename                                           \
898                   BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \
899        (*this, a.unwrap(), b.unwrap());                                  \
900}
901
902#define BZ_DECLARE_MEMBER_FUNCTION3(classname, funcname)                  \
903_BZ_MAKE_FUNCTOR3(classname, funcname)                                    \
904template<typename P_expr1, typename P_expr2, typename P_expr3>            \
905BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<           \
906    _bz_Functor ## classname ## funcname,                                 \
907    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
908    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
909    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,                 \
910    BZ_PROMOTE(_bz_typename                                               \
911               BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,        \
912    BZ_PROMOTE(_bz_typename                                               \
913               BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype,        \
914               _bz_typename                                               \
915               BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >    \
916funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                        \
917         const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b,                        \
918         const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const                  \
919{                                                                         \
920    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
921        BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<                                 \
922        _bz_Functor ## classname ## funcname,                             \
923        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
924        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
925        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,             \
926        BZ_PROMOTE(_bz_typename                                           \
927                   BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype,    \
928        BZ_PROMOTE(_bz_typename                                           \
929                   BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype,    \
930                   _bz_typename                                           \
931                   BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >\
932        (*this, a.unwrap(), b.unwrap(), c.unwrap());                      \
933}
934
935
936#define BZ_DECLARE_MEMBER_FUNCTION_RET(classname, funcname, ret)          \
937_BZ_MAKE_FUNCTOR_RET(classname, funcname, ret)                            \
938template<typename P_expr>                                                 \
939BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)<            \
940    _bz_Functor ## classname ## funcname,                                 \
941    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,                  \
942    ret> >                                                                \
943funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const                   \
944{                                                                         \
945    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
946        BZ_BLITZ_SCOPE(_bz_FunctorExpr)<                                  \
947        _bz_Functor ## classname ## funcname,                             \
948        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr,              \
949        ret> >                                                            \
950        (*this, a.unwrap());                                              \
951}
952
953#define BZ_DECLARE_MEMBER_FUNCTION2_RET(classname, funcname, ret)         \
954_BZ_MAKE_FUNCTOR2_RET(classname, funcname, ret)                           \
955template<typename P_expr1, typename P_expr2>                              \
956BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<           \
957    _bz_Functor ## classname ## funcname,                                 \
958    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
959    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
960    ret> >                                                                \
961funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                        \
962         const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const                  \
963{                                                                         \
964    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
965        BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<                                 \
966        _bz_Functor ## classname ## funcname,                             \
967        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
968        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
969        ret> >                                                            \
970        (*this, a.unwrap(), b.unwrap());                                  \
971}
972
973#define BZ_DECLARE_MEMBER_FUNCTION3_RET(classname, funcname, ret)         \
974_BZ_MAKE_FUNCTOR3_RET(classname, funcname, ret)                           \
975template<typename P_expr1, typename P_expr2, typename P_expr3>            \
976BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<           \
977    _bz_Functor ## classname ## funcname,                                 \
978    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,                 \
979    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,                 \
980    _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,                 \
981    ret> >                                                                \
982funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a,                        \
983         const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b,                        \
984         const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const                  \
985{                                                                         \
986    return BZ_BLITZ_SCOPE(_bz_ArrayExpr)<                                 \
987        BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<                                 \
988        _bz_Functor ## classname ## funcname,                             \
989        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr,             \
990        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr,             \
991        _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr,             \
992        ret> >                                                            \
993        (*this, a.unwrap(), b.unwrap(), c.unwrap());                      \
994}
995
996
997
998#endif // BZ_ARRAY_FUNCTOREXPR_H
999
Note: See TracBrowser for help on using the repository browser.