vigra - vigra/functorexpression.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

functorexpression.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36 #ifndef VIGRA_FUNCTOREXPRESSION_HXX
37 #define VIGRA_FUNCTOREXPRESSION_HXX
38
39
40 /** \page FunctorExpressions Functor Expressions
41
42 Simple automatic functor creation by means of expression templates
43 (also known as a "lambda library"). Note, however, that the \ref
44 MultiMathModule module offers similar functionality with an easier
45 syntax.
46
47 <b>\#include</b> <vigra/functorexpression.hxx><br>
48 Namespace: vigra::functor
49
50 <b> Motivation</b>
51
52 Many generic algorithms are made more flexible by means of functors
53 which define part of the algorithms' behavior according to the
54 needs of a specific situation. For example, we can apply an exponential
55 to each pixel by passing a pointer to the <TT>exp</TT> function
56 to <TT>transformImage()</TT>:
57
58 \code
59 vigra::FImage src(w,h), dest(w,h);
60 ... // fill src
61
62 vigra::transformImage(srcImageRange(src), destImage(dest), &exp);
63 \endcode
64
65 However, this only works for simple operations. If we wanted to
66 apply the exponential to a scaled pixel value (i.e. we want to execute
67 <TT>exp(-beta*v)</TT>), we first need to implement a new functor:
68
69 \code
70 struct Exponential
71 {
72 Exponential(double b)
73 : beta(b)
74 {}
75
76 template <class PixelType>
77 PixelType operator()(PixelType const& v) const
78 {
79 return exp(-beta*v);
80 }
81
82 double beta;
83 };
84 \endcode
85
86 This functor would be used like this:
87
88 \code
89 double beta = ...;
90 vigra::transformImage(srcImageRange(src), destImage(dest),
91 Exponential(beta));
92 \endcode
93
94 However, this approach has some disadvantages:
95
96 <UL>
97
98 <li> Writing a functor is more work then simply program the loop
99 directly, i.e. non-generically. Programmers will tend to
100 avoid generic constructs, if they require so much writing.
101 <li> Often, functors are only needed for a single expression.
102 It is not desirable to get into the trouble of introducing
103 and documenting a new class if that class is used only once.
104 <li> Functors cannot be implemented directly at the point of use.
105 Thus, to find out exactly what a functor is doing, one needs
106 to look somewhere else. This complicates use and maintenance
107 ot generic code.
108
109 </UL>
110
111 Therefore, it is necessary to provide a means to generate functors on
112 the fly where they are needed. The C++ standard library contains so called
113 "functor combinators" that allow to construct complicated functors from
114 simpler ones. The above problem "apply exp(-beta*v) to every pixel"
115 would be solved like this:
116
117 \code
118 float beta = ...;
119
120 vigra::transformImage(srcImageRange(src), destImage(dest),
121 std::compose1(std::ptr_fun(exp),
122 std::bind1st(std::multiplies<float>(), -beta)));
123 \endcode
124
125 I won't go into details on how this works. Suffice it to say that
126 this technique requires a functional programming style that is unfamiliar
127 to many programmers, and thus leads to code that is difficult to
128 understand. Moreover, this technique has some limitations that prevent
129 certain expressions from being implementable this way. Therefore, VIGRA
130 provides a better and simpler means to create functors on the fly.
131
132 <b> Automatic Functor Creation</b>
133
134 Automatic functor creation in VIGRA is based on a technique called
135 <a href="http://extreme.indiana.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">Expression Templates</a>.
136 This means that C++ operators are
137 overloaded so that they don't execute the specified operation directly,
138 but instead produce a functor which will later calculate the result.
139 This technique has the big advantage that the familiar operator notation
140 can be used, while all the flexibility of generic programming is preserved.
141
142 The above problem "apply <TT>exp(-beta*v)</TT> to every pixel" will be solved
143 like this:
144
145 \code
146 using namespace vigra::functor;
147
148 float beta = ...;
149
150 transformImage(srcImageRange(src), destImage(dest),
151 exp(Param(-beta)*Arg1()));
152 \endcode
153
154 Here, four expression templates have been used to create the desired
155 functor:
156
157 <DL>
158
159 <DT><b><TT>Param(-beta):</TT></b><DD> creates a functor that represents a
160 constant (<TT>-beta</TT> in this case)
161
162 <DT><b><TT>Arg1():</TT></b><DD> represents the first argument of the expression (i.e.
163 the pixels of image <TT>src</TT> in the example). Likewise, <TT>Arg2()</TT> and
164 <TT>Arg3()</TT> are defined to represent more arguments. These are needed
165 for algorithms that have multiple input images, such as
166 \ref combineTwoImages() and \ref combineThreeImages().
167
168 <DT><b>* (multiplication):</b><DD> creates a functor that returns the product of
169 its arguments. Likewise, the other C++ operators (i.e.
170 <TT>+, -, *, /, %, ==, !=, <, <=, >, >=, &&, ||, &, |, ^, !, ~</TT>)
171 are overloaded.
172
173 <DT><b><TT>exp():</TT></b><DD> creates a functor that takes the exponential of its
174 argument. Likewise, the other algebraic functions
175 (i.e. <TT>sq, sqrt, exp, log, log10, sin, asin, cos, acos, tan,
176 atan, abs, floor, ceil, pow, atan2, fmod, min, max</TT>)
177 are overloaded.
178
179 </DL>
180
181 We will explain additional capabilities of the functor creation mechanism
182 by means of examples.
183
184 The same argument can be used several times in the expression.
185 For example, to calculate the gradient magnitude from the components
186 of the gradient vector, you may write:
187
188 \code
189 using namespace vigra::functor;
190
191 vigra::FImage gradient_x(w,h), gradient_y(w,h), magnitude(w,h);
192 ... // calculate gradient_x and gradient_y
193
194 combineTwoImages(srcImageRange(gradient_x), srcImage(gradient_y),
195 destImage(magnitude),
196 sqrt(Arg1()*Arg1() + Arg2()*Arg2()));
197 \endcode
198
199 It is also possible to build other functions into functor expressions. Suppose
200 you want to apply <TT>my_complicated_function()</TT> to the sum of two images:
201
202 \code
203 using namespace vigra::functor;
204
205 vigra::FImage src1(w,h), src2(w,h), dest(w,h);
206
207 double my_complicated_function(double);
208
209 combineTwoImages(srcImageRange(src1), srcImage(src2), destImage(dest),
210 applyFct(&my_complicated_function, Arg1()+Arg2()));
211 \endcode
212
213 [Note that the arguments of the wrapped function are passed as additional
214 arguments to <TT>applyFct()</TT>]
215
216 You can implement conditional expression by means of the <TT>ifThenElse()</TT>
217 functor. It corresponds to the "? :" operator that cannot be overloaded.
218 <TT>ifThenElse()</TT> can be used, for example, to threshold an image:
219
220 \code
221 using namespace vigra::functor;
222
223 vigra::FImage src(w,h), thresholded(w,h);
224 ...// fill src
225
226 float threshold = ...;
227
228 transformImage(srcImageRange(src), destImage(thresholded),
229 ifThenElse(Arg1() < Param(threshold),
230 Param(0.0), // yes branch
231 Param(1.0)) // no branch
232 );
233 \endcode
234
235 You can use the <TT>Var()</TT> functor to assign values to a variable
236 (<TT>=, +=, -=, *=, /=</TT>&nbsp; are supported). For example, the average gray
237 value of the image is calculated like this:
238
239 \code
240 using namespace vigra::functor;
241
242 vigra::FImage src(w,h);
243 ...// fill src
244
245 double sum = 0.0;
246
247 inspectImage(srcImageRange(src), Var(sum) += Arg1());
248
249 std::cout << "Average: " << (sum / (w*h)) << std::endl;
250 \endcode
251
252 For use in \ref inspectImage() and its relatives, there is a second
253 conditional functor <TT>ifThen()</TT> that emulates the <TT>if()</TT> statement
254 and does not return a value. Using <TT>ifThen()</TT>, we can calculate the size
255 of an image region:
256
257 \code
258 using namespace vigra::functor;
259
260 vigra::IImage label_image(w,h);
261 ...// mark regions by labels in label_image
262
263 int region_label = ...; // the region we want to inspect
264 int size = 0;
265
266 inspectImage(srcImageRange(label_image),
267 ifThen(Arg1() == Param(region_label),
268 Var(size) += Param(1)));
269
270 std::cout << "Size of region " << region_label << ": " << size << std::endl;
271 \endcode
272
273 Often, we want to execute several commands in one functor. This can be done
274 by means of the overloaded <TT>operator,()</TT> ("operator comma"). Expressions
275 separated by a comma will be executed in succession. We can thus
276 simultaneously find the size and the average gray value of a region:
277
278 \code
279 using namespace vigra::functor;
280
281 vigra::FImage src(w,h);
282 vigra::IImage label_image(w,h);
283 ...// segment src and mark regions in label_image
284
285 int region_label = ...; // the region we want to inspect
286 int size = 0;
287 double sum = 0.0;
288
289 inspectTwoImages(srcImageRange(src), srcImage(label_image),
290 ifThen(Arg2() == Param(region_label),
291 (
292 Var(size) += Param(1), // the comma operator is invoked
293 Var(sum) += Arg1()
294 )));
295
296 std::cout << "Region " << region_label << ": size = " << size <<
297 ", average = " << sum / size << std::endl;
298 \endcode
299
300 [Note that the list of comma-separated expressions must be enclosed in parentheses.]
301
302 A comma separated list of expressions can also be applied in the context of
303 \ref transformImage() and its cousins. Here, a general rule of C++ applies: The
304 return value of a comma expression is the value of its last subexpression.
305 For example, we can initialize an image so that each pixel contains its
306 address in scan order:
307
308 \code
309 using namespace vigra::functor;
310
311 vigra::IImage img(w,h);
312
313 int count = -1;
314
315 initImageWithFunctor(destImageRange(img),
316 (
317 Var(count) += Param(1),
318 Var(count) // this is the result of the comma expression
319 ));
320 \endcode
321
322 Further information about how this mechanism works can be found in
323 <a href="http://hci.iwr.uni-heidelberg.de/vigra/documents/FunctorFactory.ps">this paper</a> (sorry, slightly out of date).
324 */
325
326 #ifndef DOXYGEN
327
328 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
329
330 #include <cmath>
331 #include "numerictraits.hxx"
332 #include "mathutil.hxx"
333 #include "functortraits.hxx"
334
335
336 namespace vigra {
337
338 namespace functor {
339
340 /************************************************************/
341 /* */
342 /* unary functor base template */
343 /* */
344 /************************************************************/
345
346
347 struct ErrorType;
348
349 template <class Operation>
350 struct ResultTraits0;
351
352 template <class Operation, class T1>
353 struct ResultTraits1
354 {
355 typedef T1 Res;
356 };
357
358 template <class Operation, class T1, class T2>
359 struct ResultTraits2
360 {
361 typedef typename PromoteTraits<T1, T2>::Promote Res;
362 };
363
364 template <class Operation, class T1, class T2, class T3>
365 struct ResultTraits3
366 {
367 typedef typename PromoteTraits<T1, T2>::Promote P1;
368 typedef typename PromoteTraits<P1, T3>::Promote Res;
369 };
370
371 template <class EXPR>
372 struct UnaryFunctor
373 {
374 UnaryFunctor(EXPR const & e)
375 : expr_(e)
376 {}
377
378 // typename ResultTraits0<EXPR>::Res
379 typename ResultTraits0<EXPR>::Res
380 operator()() const
381 {
382 return expr_();
383 }
384
385 template <class T1>
386 typename ResultTraits1<EXPR, T1>::Res
387 operator()(T1 const & v) const
388 {
389 return expr_(v);
390 }
391
392 template <class T1, class T2>
393 typename ResultTraits2<EXPR, T1, T2>::Res
394 operator()(T1 const & v1, T2 const & v2) const
395 {
396 return expr_(v1, v2);
397 }
398
399 template <class T1, class T2, class T3>
400 typename ResultTraits3<EXPR, T1, T2, T3>::Res
401 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
402 {
403 return expr_(v1, v2, v3);
404 }
405
406 protected:
407 EXPR expr_;
408
409 private:
410 UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
411 };
412
413 template <class Expr>
414 struct ResultTraits0<UnaryFunctor<Expr> >
415 {
416 typedef typename ResultTraits0<Expr>::Res Res;
417 };
418
419 template <class Expr, class T1>
420 struct ResultTraits1<UnaryFunctor<Expr>, T1>
421 {
422 typedef typename ResultTraits1<Expr, T1>::Res Res;
423 };
424
425 template <class Expr, class T1, class T2>
426 struct ResultTraits2<UnaryFunctor<Expr>, T1, T2>
427 {
428 typedef typename ResultTraits2<Expr, T1, T2>::Res Res;
429 };
430
431 template <class Expr, class T1, class T2, class T3>
432 struct ResultTraits3<UnaryFunctor<Expr>, T1, T2, T3>
433 {
434 typedef typename ResultTraits3<Expr, T1, T2, T3>::Res Res;
435 };
436
437 /************************************************************/
438 /* */
439 /* unary functors for arguments */
440 /* */
441 /************************************************************/
442
443 struct ArgumentFunctor1;
444 struct ArgumentFunctor2;
445 struct ArgumentFunctor3;
446
447 template <>
448 struct UnaryFunctor<ArgumentFunctor1>
449 {
450 UnaryFunctor()
451 {}
452
453 template <class T1>
454 T1 const & operator()(T1 const & v1) const
455 {
456 return v1;
457 }
458
459 template <class T1, class T2>
460 T1 const & operator()(T1 const & v1, T2 const &) const
461 {
462 return v1;
463 }
464
465 template <class T1, class T2, class T3>
466 T1 const & operator()(T1 const & v1, T2 const &, T3 const &) const
467 {
468 return v1;
469 }
470
471 private:
472 UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
473 };
474
475 typedef UnaryFunctor<ArgumentFunctor1> Identity;
476
477 template <>
478 struct ResultTraits0<UnaryFunctor<ArgumentFunctor1> >
479 {
480 typedef ErrorType Res;
481 };
482
483 template <class T1>
484 struct ResultTraits1<UnaryFunctor<ArgumentFunctor1>, T1>
485 {
486 typedef T1 Res;
487 };
488
489 template <class T1, class T2>
490 struct ResultTraits2<UnaryFunctor<ArgumentFunctor1>, T1, T2>
491 {
492 typedef T1 Res;
493 };
494
495 template <class T1, class T2, class T3>
496 struct ResultTraits3<UnaryFunctor<ArgumentFunctor1>, T1, T2, T3>
497 {
498 typedef T1 Res;
499 };
500
501 /************************************************************/
502
503 inline
504 UnaryFunctor<ArgumentFunctor1>
505 Arg1()
506 {
507 return UnaryFunctor<ArgumentFunctor1>();
508 }
509
510 /************************************************************/
511
512 template <>
513 struct UnaryFunctor<ArgumentFunctor2>
514 {
515 UnaryFunctor()
516 {}
517
518 template <class T1, class T2>
519 T2 const & operator()(T1 const &, T2 const & v2) const
520 {
521 return v2;
522 }
523
524 template <class T1, class T2, class T3>
525 T2 const & operator()(T1 const &, T2 const & v2, T3 const &) const
526 {
527 return v2;
528 }
529
530 private:
531 UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
532 };
533
534 template <>
535 struct ResultTraits0<UnaryFunctor<ArgumentFunctor2> >
536 {
537 typedef ErrorType Res;
538 };
539
540 template <class T1>
541 struct ResultTraits1<UnaryFunctor<ArgumentFunctor2>, T1>
542 {
543 typedef ErrorType Res;
544 };
545
546 template <class T1, class T2>
547 struct ResultTraits2<UnaryFunctor<ArgumentFunctor2>, T1, T2>
548 {
549 typedef T2 Res;
550 };
551
552 template <class T1, class T2, class T3>
553 struct ResultTraits3<UnaryFunctor<ArgumentFunctor2>, T1, T2, T3>
554 {
555 typedef T2 Res;
556 };
557
558 /************************************************************/
559
560 inline
561 UnaryFunctor<ArgumentFunctor2>
562 Arg2()
563 {
564 return UnaryFunctor<ArgumentFunctor2>();
565 }
566
567 /************************************************************/
568
569 template <>
570 struct UnaryFunctor<ArgumentFunctor3>
571 {
572 UnaryFunctor()
573 {}
574
575 template <class T1, class T2, class T3>
576 T3 const & operator()(T1 const &, T2 const &, T3 const & v3) const
577 {
578 return v3;
579 }
580
581 private:
582 UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
583 };
584
585 template <>
586 struct ResultTraits0<UnaryFunctor<ArgumentFunctor3> >
587 {
588 typedef ErrorType Res;
589 };
590
591 template <class T1>
592 struct ResultTraits1<UnaryFunctor<ArgumentFunctor3>, T1>
593 {
594 typedef ErrorType Res;
595 };
596
597 template <class T1, class T2>
598 struct ResultTraits2<UnaryFunctor<ArgumentFunctor3>, T1, T2>
599 {
600 typedef ErrorType Res;
601 };
602
603 template <class T1, class T2, class T3>
604 struct ResultTraits3<UnaryFunctor<ArgumentFunctor3>, T1, T2, T3>
605 {
606 typedef T3 Res;
607 };
608
609 /************************************************************/
610
611 inline
612 UnaryFunctor<ArgumentFunctor3>
613 Arg3()
614 {
615 return UnaryFunctor<ArgumentFunctor3>();
616 }
617
618 /************************************************************/
619 /* */
620 /* constant parameters */
621 /* */
622 /************************************************************/
623
624 template <class T>
625 struct ParameterFunctor
626 {
627 ParameterFunctor(T v)
628 : value_(v)
629 {}
630
631 T const & operator()() const
632 {
633 return value_;
634 }
635
636 template <class U1>
637 T const & operator()(U1 const &) const
638 {
639 return value_;
640 }
641
642 template <class U1, class U2>
643 T const & operator()(U1 const &, U2 const &) const
644 {
645 return value_;
646 }
647
648 template <class U1, class U2, class U3>
649 T const & operator()(U1 const &, U2 const &, U3 const &) const
650 {
651 return value_;
652 }
653
654 protected:
655 T value_;
656
657 private:
658 ParameterFunctor & operator=(ParameterFunctor const &); // not implemented
659 };
660
661 template <class T>
662 struct ResultTraits0<ParameterFunctor<T> >
663 {
664 typedef T Res;
665 };
666
667 template <class T, class T1>
668 struct ResultTraits1<ParameterFunctor<T>, T1>
669 {
670 typedef T Res;
671 };
672
673 template <class T, class T1, class T2>
674 struct ResultTraits2<ParameterFunctor<T>, T1, T2>
675 {
676 typedef T Res;
677 };
678
679 template <class T, class T1, class T2, class T3>
680 struct ResultTraits3<ParameterFunctor<T>, T1, T2, T3>
681 {
682 typedef T Res;
683 };
684
685 template <class T>
686 inline UnaryFunctor<ParameterFunctor<T> >
687 Param(T const & v)
688 {
689 ParameterFunctor<T> fv(v);
690 return UnaryFunctor<ParameterFunctor<T> >(fv);
691 }
692
693 /************************************************************/
694 /* */
695 /* unary analyser base template */
696 /* */
697 /************************************************************/
698
699
700 template <class EXPR>
701 class UnaryAnalyser
702 {
703 public:
704 UnaryAnalyser(EXPR const & e)
705 : expr_(e)
706 {}
707
708 void operator()() const
709 {
710 expr_();
711 }
712
713 template <class T1>
714 void operator()(T1 const & v) const
715 {
716 expr_(v);
717 }
718
719 template <class T1, class T2>
720 void operator()(T1 const & v1, T2 const & v2) const
721 {
722 expr_(v1, v2);
723 }
724
725 template <class T1, class T2, class T3>
726 void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
727 {
728 expr_(v1, v2, v3);
729 }
730 protected:
731
732 EXPR expr_;
733
734 private:
735 UnaryAnalyser & operator=(UnaryAnalyser const &); // not implemented
736 };
737
738 /************************************************************/
739 /* */
740 /* variable assignment */
741 /* */
742 /************************************************************/
743
744 template <class T>
745 struct VarFunctor;
746
747 template <class T>
748 struct UnaryFunctor<VarFunctor<T> >;
749
750 /************************************************************/
751
752 #define MAKE_ASSIGNMENT_FUNCTOR(name, op) \
753 template <class V, class EXPR> \
754 struct AssignmentFunctor_##name \
755 { \
756 AssignmentFunctor_##name(UnaryFunctor<VarFunctor<V> > v, \
757 UnaryFunctor<EXPR> const & e) \
758 : value_(v.value_), expr_(e) \
759 {} \
760 \
761 V & operator()() const \
762 { \
763 const_cast<V &>(value_) op expr_(); \
764 return const_cast<V &>(value_); \
765 } \
766 \
767 template <class T1> \
768 V & operator()(T1 const & v1) const \
769 { \
770 const_cast<V &>(value_) op expr_(v1); \
771 return const_cast<V &>(value_); \
772 } \
773 \
774 template <class T1, class T2> \
775 V & operator()(T1 const & v1, T2 const & v2) const \
776 { \
777 const_cast<V &>(value_) op expr_(v1, v2); \
778 return const_cast<V &>(value_); \
779 } \
780 \
781 template <class T1, class T2, class T3> \
782 V & operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
783 { \
784 const_cast<V &>(value_) op expr_(v1, v2, v3); \
785 return const_cast<V &>(value_); \
786 } \
787 \
788 private: \
789 V & value_; \
790 UnaryFunctor<EXPR> expr_; \
791 \
792 AssignmentFunctor_##name & operator=(AssignmentFunctor_##name const &);\
793 };
794
795 /************************************************************/
796
797 MAKE_ASSIGNMENT_FUNCTOR(assign, =)
798 MAKE_ASSIGNMENT_FUNCTOR(add, +=)
799 MAKE_ASSIGNMENT_FUNCTOR(subtract, -=)
800 MAKE_ASSIGNMENT_FUNCTOR(multiply, *=)
801 MAKE_ASSIGNMENT_FUNCTOR(divide, /=)
802
803 #undef MAKE_ASSIGNMENT_FUNCTOR
804
805 /************************************************************/
806 /* */
807 /* variables */
808 /* */
809 /************************************************************/
810
811 template <class T>
812 struct UnaryFunctor<VarFunctor<T> >
813 {
814 typedef T Res;
815
816 UnaryFunctor(T & v)
817 : value_(v)
818 {}
819
820 template <class EXPR>
821 UnaryAnalyser< AssignmentFunctor_assign<T, UnaryFunctor<EXPR> > >
822 operator=(UnaryFunctor<EXPR> const & e)
823 {
824 AssignmentFunctor_assign<T, UnaryFunctor<EXPR> > va(*this, e);
825 return UnaryAnalyser< AssignmentFunctor_assign<T, UnaryFunctor<EXPR> > >(va);
826 }
827
828 template <class EXPR>
829 UnaryAnalyser< AssignmentFunctor_add<T, UnaryFunctor<EXPR> > >
830 operator+=(UnaryFunctor<EXPR> const & e)
831 {
832 AssignmentFunctor_add<T, UnaryFunctor<EXPR> > va(*this, e);
833 return UnaryAnalyser< AssignmentFunctor_add<T, UnaryFunctor<EXPR> > >(va);
834 }
835
836 template <class EXPR>
837 UnaryAnalyser< AssignmentFunctor_subtract<T, UnaryFunctor<EXPR> > >
838 operator-=(UnaryFunctor<EXPR> const & e)
839 {
840 AssignmentFunctor_subtract<T, UnaryFunctor<EXPR> > va(*this, e);
841 return UnaryAnalyser< AssignmentFunctor_subtract<T, UnaryFunctor<EXPR> > >(va);
842 }
843
844 template <class EXPR>
845 UnaryAnalyser< AssignmentFunctor_multiply<T, UnaryFunctor<EXPR> > >
846 operator*=(UnaryFunctor<EXPR> const & e)
847 {
848 AssignmentFunctor_multiply<T, UnaryFunctor<EXPR> > va(*this, e);
849 return UnaryAnalyser< AssignmentFunctor_multiply<T, UnaryFunctor<EXPR> > >(va);
850 }
851
852 template <class EXPR>
853 UnaryAnalyser< AssignmentFunctor_divide<T, UnaryFunctor<EXPR> > >
854 operator/=(UnaryFunctor<EXPR> const & e)
855 {
856 AssignmentFunctor_divide<T, UnaryFunctor<EXPR> > va(*this, e);
857 return UnaryAnalyser< AssignmentFunctor_divide<T, UnaryFunctor<EXPR> > >(va);
858 }
859
860 T const & operator()() const
861 {
862 return value_;
863 }
864
865 template <class U1>
866 T const & operator()(U1 const &) const
867 {
868 return value_;
869 }
870
871 template <class U1, class U2>
872 T const & operator()(U1 const &, U2 const &) const
873 {
874 return value_;
875 }
876
877 template <class U1, class U2, class U3>
878 T const & operator()(U1 const &, U2 const &, U3 const &) const
879 {
880 return value_;
881 }
882
883 T & value_;
884
885 private:
886 UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
887 };
888
889 template <class T>
890 struct ResultTraits0<UnaryFunctor<VarFunctor<T> > >
891 {
892 typedef T Res;
893 };
894
895 template <class T, class T1>
896 struct ResultTraits1<UnaryFunctor<VarFunctor<T> >, T1>
897 {
898 typedef T Res;
899 };
900
901 template <class T, class T1, class T2>
902 struct ResultTraits2<UnaryFunctor<VarFunctor<T> >, T1, T2>
903 {
904 typedef T Res;
905 };
906
907 template <class T, class T1, class T2, class T3>
908 struct ResultTraits3<UnaryFunctor<VarFunctor<T> >, T1, T2, T3>
909 {
910 typedef T Res;
911 };
912
913 template <class T>
914 inline UnaryFunctor<VarFunctor<T> >
915 Var(T & v)
916 {
917 return UnaryFunctor<VarFunctor<T> >(v);
918 }
919
920 /************************************************************/
921 /* */
922 /* if then */
923 /* */
924 /************************************************************/
925
926 template <class EXPR1, class EXPR2>
927 struct IfThenFunctor
928 {
929 typedef void Res;
930
931 IfThenFunctor(EXPR1 const & e1, EXPR2 const & e2)
932 : expr1_(e1), expr2_(e2)
933 {}
934
935 void operator()() const
936 {
937 if( expr1_() ) expr2_();
938 }
939
940 template <class T>
941 void operator()(T const & v1) const
942 {
943 if( expr1_(v1) ) expr2_(v1);
944 }
945
946 template <class T1, class T2>
947 void operator()(T1 const & v1, T2 const & v2) const
948 {
949 if( expr1_(v1, v2) ) expr2_(v1, v2);
950 }
951
952 template <class T1, class T2, class T3>
953 void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
954 {
955 if( expr1_(v1, v2, v3) ) expr2_(v1, v2, v3);
956 }
957
958 private:
959
960 EXPR1 expr1_;
961 EXPR2 expr2_;
962
963 private:
964 IfThenFunctor & operator=(IfThenFunctor const &); // not implemented
965 };
966
967 template <class EXPR1, class EXPR2>
968 UnaryAnalyser<IfThenFunctor<UnaryFunctor<EXPR1>,
969 UnaryAnalyser<EXPR2> > >
970 ifThen(UnaryFunctor<EXPR1> const & e1,
971 UnaryAnalyser<EXPR2> const & e2)
972 {
973 IfThenFunctor<UnaryFunctor<EXPR1>,
974 UnaryAnalyser<EXPR2> > p(e1, e2);
975 return UnaryAnalyser<IfThenFunctor<UnaryFunctor<EXPR1>,
976 UnaryAnalyser<EXPR2> > >(p);
977 }
978
979 /************************************************************/
980 /* */
981 /* if then else */
982 /* */
983 /************************************************************/
984
985 template <class EXPR1, class EXPR2, class EXPR3>
986 struct IfThenElseFunctor;
987
988 template <class EXPR1, class EXPR2, class EXPR3>
989 struct ResultTraits0<IfThenElseFunctor<EXPR1, EXPR2, EXPR3> >
990 {
991 typedef typename ResultTraits0<EXPR2>::Res R2;
992 typedef typename ResultTraits0<EXPR3>::Res R3;
993 typedef typename PromoteTraits<R2, R3>::Promote Res;
994 };
995
996 template <class EXPR1, class EXPR2, class EXPR3, class T1>
997 struct ResultTraits1<IfThenElseFunctor<EXPR1, EXPR2, EXPR3>, T1>
998 {
999 typedef typename ResultTraits1<EXPR2, T1>::Res R2;
1000 typedef typename ResultTraits1<EXPR3, T1>::Res R3;
1001 typedef typename PromoteTraits<R2, R3>::Promote Res;
1002 };
1003
1004 template <class EXPR1, class EXPR2, class EXPR3, class T1, class T2>
1005 struct ResultTraits2<IfThenElseFunctor<EXPR1, EXPR2, EXPR3>, T1, T2>
1006 {
1007 typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2;
1008 typedef typename ResultTraits2<EXPR3, T1, T2>::Res R3;
1009 typedef typename PromoteTraits<R2, R3>::Promote Res;
1010 };
1011
1012 template <class EXPR1, class EXPR2, class EXPR3, class T1, class T2, class T3>
1013 struct ResultTraits3<IfThenElseFunctor<EXPR1, EXPR2, EXPR3>, T1, T2, T3>
1014 {
1015 typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2;
1016 typedef typename ResultTraits3<EXPR3, T1, T2, T3>::Res R3;
1017 typedef typename PromoteTraits<R2, R3>::Promote Res;
1018 };
1019
1020 template <class EXPR1, class EXPR2, class EXPR3>
1021 struct IfThenElseFunctor
1022 {
1023 IfThenElseFunctor(EXPR1 const & e1, EXPR2 const & e2, EXPR3 const & e3)
1024 : expr1_(e1), expr2_(e2), expr3_(e3)
1025 {}
1026
1027 typename ResultTraits0<IfThenElseFunctor>::Res
1028 operator()() const
1029 {
1030 if(expr1_())
1031 {
1032 return typename ResultTraits0<IfThenElseFunctor>::Res(expr2_());
1033 }
1034 else
1035 {
1036 return typename ResultTraits0<IfThenElseFunctor>::Res(expr3_());
1037 }
1038 }
1039
1040 template <class T>
1041 typename ResultTraits1<IfThenElseFunctor, T>::Res
1042 operator()(T const & v1) const
1043 {
1044 if(expr1_(v1))
1045 {
1046 return typename ResultTraits1<IfThenElseFunctor, T>::Res(expr2_(v1));
1047 }
1048 else
1049 {
1050 return typename ResultTraits1<IfThenElseFunctor, T>::Res(expr3_(v1));
1051 }
1052 }
1053
1054 template <class T1, class T2>
1055 typename ResultTraits2<IfThenElseFunctor, T1, T2>::Res
1056 operator()(T1 const & v1, T2 const & v2) const
1057 {
1058 if(expr1_(v1, v2))
1059 {
1060 return typename ResultTraits2<IfThenElseFunctor, T1, T2>::Res(expr2_(v1, v2));
1061 }
1062 else
1063 {
1064 return typename ResultTraits2<IfThenElseFunctor, T1, T2>::Res(expr3_(v1, v2));
1065 }
1066 }
1067
1068 template <class T1, class T2, class T3>
1069 typename ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res
1070 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
1071 {
1072 if(expr1_(v1, v2, v3))
1073 {
1074 return typename ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res(expr2_(v1, v2, v3));
1075 }
1076 else
1077 {
1078 return typename ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res(expr3_(v1, v2, v3));
1079 }
1080 }
1081
1082 private:
1083
1084 EXPR1 expr1_;
1085 EXPR2 expr2_;
1086 EXPR3 expr3_;
1087
1088 IfThenElseFunctor & operator=(IfThenElseFunctor const &); // not implemented
1089 };
1090
1091 template <class EXPR1, class EXPR2, class EXPR3>
1092 UnaryFunctor<IfThenElseFunctor<UnaryFunctor<EXPR1>,
1093 UnaryFunctor<EXPR2>,
1094 UnaryFunctor<EXPR3> > >
1095 ifThenElse(UnaryFunctor<EXPR1> const & e1,
1096 UnaryFunctor<EXPR2> const & e2,
1097 UnaryFunctor<EXPR3> const & e3)
1098 {
1099 IfThenElseFunctor<UnaryFunctor<EXPR1>,
1100 UnaryFunctor<EXPR2>,
1101 UnaryFunctor<EXPR3> > p(e1, e2, e3);
1102 return UnaryFunctor<IfThenElseFunctor<UnaryFunctor<EXPR1>,
1103 UnaryFunctor<EXPR2>,
1104 UnaryFunctor<EXPR3> > >(p);
1105 }
1106
1107 /************************************************************/
1108 /* */
1109 /* functors for unary functions */
1110 /* */
1111 /************************************************************/
1112
1113 #define MAKE_FUNCTOR_UNARY_FUNCTION(function, namespc, traitsClass, traitsValue) \
1114 using ::namespc::function; \
1115 template <class EXPR> \
1116 struct Functor_##function; \
1117 \
1118 template <class EXPR> \
1119 struct ResultTraits0<Functor_##function<EXPR> > \
1120 { \
1121 typedef typename ResultTraits0<EXPR>::Res R1; \
1122 typedef typename traitsClass<R1>::traitsValue Res; \
1123 }; \
1124 \
1125 template <class EXPR, class T1> \
1126 struct ResultTraits1<Functor_##function<EXPR>, T1> \
1127 { \
1128 typedef typename ResultTraits1<EXPR, T1>::Res R1; \
1129 typedef typename traitsClass<R1>::traitsValue Res; \
1130 }; \
1131 \
1132 template <class EXPR, class T1, class T2> \
1133 struct ResultTraits2<Functor_##function<EXPR>, T1, T2> \
1134 { \
1135 typedef typename ResultTraits2<EXPR, T1, T2>::Res R1; \
1136 typedef typename traitsClass<R1>::traitsValue Res; \
1137 }; \
1138 \
1139 template <class EXPR, class T1, class T2, class T3> \
1140 struct ResultTraits3<Functor_##function<EXPR>, T1, T2, T3> \
1141 { \
1142 typedef typename ResultTraits3<EXPR, T1, T2, T3>::Res R1; \
1143 typedef typename traitsClass<R1>::traitsValue Res; \
1144 }; \
1145 \
1146 template <class EXPR> \
1147 struct Functor_##function \
1148 { \
1149 Functor_##function(EXPR const & e) \
1150 : expr_(e) \
1151 {} \
1152 \
1153 typename ResultTraits0<Functor_##function>::Res \
1154 operator()() const \
1155 { \
1156 return function(expr_()); \
1157 } \
1158 \
1159 template <class T> \
1160 typename ResultTraits1<Functor_##function, T>::Res \
1161 operator()(T const & v1) const \
1162 { \
1163 return function(expr_(v1)); \
1164 } \
1165 \
1166 template <class T1, class T2> \
1167 typename ResultTraits2<Functor_##function, T1, T2>::Res \
1168 operator()(T1 const & v1, T2 const & v2) const \
1169 { \
1170 return function(expr_(v1, v2)); \
1171 } \
1172 \
1173 template <class T1, class T2, class T3> \
1174 typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \
1175 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
1176 { \
1177 return function(expr_(v1, v2, v3)); \
1178 } \
1179 \
1180 protected: \
1181 \
1182 EXPR expr_; \
1183 \
1184 private: \
1185 Functor_##function & operator=(Functor_##function const &); \
1186 }; \
1187 \
1188 template <class EXPR> \
1189 inline UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > > \
1190 function(UnaryFunctor<EXPR> const & e) \
1191 { \
1192 Functor_##function<UnaryFunctor<EXPR> > p(e); \
1193 return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > >(p); \
1194 }
1195
1196 /************************************************************/
1197
1198 MAKE_FUNCTOR_UNARY_FUNCTION(sq, vigra, NumericTraits, RealPromote)
1199 MAKE_FUNCTOR_UNARY_FUNCTION(sqrt, std, NumericTraits, RealPromote)
1200 MAKE_FUNCTOR_UNARY_FUNCTION(exp, std, NumericTraits, RealPromote)
1201 MAKE_FUNCTOR_UNARY_FUNCTION(log, std, NumericTraits, RealPromote)
1202 MAKE_FUNCTOR_UNARY_FUNCTION(log10, std, NumericTraits, RealPromote)
1203 MAKE_FUNCTOR_UNARY_FUNCTION(sin, std, NumericTraits, RealPromote)
1204 MAKE_FUNCTOR_UNARY_FUNCTION(asin, std, NumericTraits, RealPromote)
1205 MAKE_FUNCTOR_UNARY_FUNCTION(cos, std, NumericTraits, RealPromote)
1206 MAKE_FUNCTOR_UNARY_FUNCTION(acos, std, NumericTraits, RealPromote)
1207 MAKE_FUNCTOR_UNARY_FUNCTION(tan, std, NumericTraits, RealPromote)
1208 MAKE_FUNCTOR_UNARY_FUNCTION(atan, std, NumericTraits, RealPromote)
1209 MAKE_FUNCTOR_UNARY_FUNCTION(floor, std, NumericTraits, RealPromote)
1210 MAKE_FUNCTOR_UNARY_FUNCTION(ceil, std, NumericTraits, RealPromote)
1211 MAKE_FUNCTOR_UNARY_FUNCTION(abs, vigra, NumericTraits, RealPromote)
1212 MAKE_FUNCTOR_UNARY_FUNCTION(norm, vigra, NormTraits, NormType)
1213 MAKE_FUNCTOR_UNARY_FUNCTION(squaredNorm, vigra, NormTraits, SquaredNormType)
1214
1215 #undef MAKE_FUNCTOR_UNARY_FUNCTION
1216
1217 /************************************************************/
1218 /* */
1219 /* functors for unary operators */
1220 /* */
1221 /************************************************************/
1222
1223 #define MAKE_FUNCTOR_UNARY_OPERATOR(name, op) \
1224 template <class EXPR> \
1225 struct Functor_##name; \
1226 \
1227 template <class EXPR> \
1228 struct ResultTraits0<Functor_##name<EXPR> > \
1229 { \
1230 typedef typename ResultTraits0<EXPR>::Res Res; \
1231 }; \
1232 \
1233 template <class EXPR, class T1> \
1234 struct ResultTraits1<Functor_##name<EXPR>, T1> \
1235 { \
1236 typedef typename ResultTraits1<EXPR, T1>::Res Res; \
1237 }; \
1238 \
1239 template <class EXPR, class T1, class T2> \
1240 struct ResultTraits2<Functor_##name<EXPR>, T1, T2> \
1241 { \
1242 typedef typename ResultTraits2<EXPR, T1, T2>::Res Res; \
1243 }; \
1244 \
1245 template <class EXPR, class T1, class T2, class T3> \
1246 struct ResultTraits3<Functor_##name<EXPR>, T1, T2, T3> \
1247 { \
1248 typedef typename ResultTraits3<EXPR, T1, T2, T3>::Res Res; \
1249 }; \
1250 \
1251 template <class EXPR> \
1252 struct Functor_##name \
1253 { \
1254 Functor_##name(EXPR const & e) \
1255 : expr_(e) \
1256 {} \
1257 \
1258 typename ResultTraits0<Functor_##name>::Res \
1259 operator()() const \
1260 { \
1261 return op expr_(); \
1262 } \
1263 \
1264 template <class T> \
1265 typename ResultTraits1<Functor_##name, T>::Res \
1266 operator()(T const & v1) const \
1267 { \
1268 return op expr_(v1); \
1269 } \
1270 \
1271 template <class T1, class T2> \
1272 typename ResultTraits2<Functor_##name, T1, T2>::Res \
1273 operator()(T1 const & v1, T2 const & v2) const \
1274 { \
1275 return op expr_(v1, v2); \
1276 } \
1277 \
1278 template <class T1, class T2, class T3> \
1279 typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
1280 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
1281 { \
1282 return op expr_(v1, v2, v3); \
1283 } \
1284 protected: \
1285 \
1286 EXPR expr_; \
1287 \
1288 private: \
1289 Functor_##name & operator=(Functor_##name const &);\
1290 }; \
1291 \
1292 template <class EXPR> \
1293 inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > > \
1294 operator op(UnaryFunctor<EXPR> const & e) \
1295 { \
1296 Functor_##name<UnaryFunctor<EXPR> > p(e); \
1297 return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > >(p); \
1298 }
1299
1300
1301 /************************************************************/
1302
1303 MAKE_FUNCTOR_UNARY_OPERATOR(minus, -)
1304 MAKE_FUNCTOR_UNARY_OPERATOR(negate, !)
1305 MAKE_FUNCTOR_UNARY_OPERATOR(bitNegate, ~)
1306
1307 #undef MAKE_FUNCTOR_UNARY_OPERATOR
1308
1309 /************************************************************/
1310 /* */
1311 /* functors for binary functions */
1312 /* */
1313 /************************************************************/
1314
1315 #define MAKE_FUNCTOR_BINARY_FUNCTION(function) \
1316 using std::function; \
1317 template <class EXPR1, class EXPR2> \
1318 struct Functor_##function; \
1319 \
1320 template <class EXPR1, class EXPR2> \
1321 struct ResultTraits0<Functor_##function<EXPR1, EXPR2> > \
1322 { \
1323 typedef typename ResultTraits0<EXPR1>::Res R1; \
1324 typedef typename ResultTraits0<EXPR2>::Res R2; \
1325 typedef typename PromoteTraits<R1, R2>::Promote R3; \
1326 typedef typename NumericTraits<R3>::RealPromote Res; \
1327 }; \
1328 \
1329 template <class EXPR1, class EXPR2, class T1> \
1330 struct ResultTraits1<Functor_##function<EXPR1, EXPR2>, T1> \
1331 { \
1332 typedef typename ResultTraits1<EXPR1, T1>::Res R1; \
1333 typedef typename ResultTraits1<EXPR2, T1>::Res R2; \
1334 typedef typename PromoteTraits<R1, R2>::Promote R3; \
1335 typedef typename NumericTraits<R3>::RealPromote Res; \
1336 }; \
1337 \
1338 template <class EXPR1, class EXPR2, class T1, class T2> \
1339 struct ResultTraits2<Functor_##function<EXPR1, EXPR2>, T1, T2> \
1340 { \
1341 typedef typename ResultTraits2<EXPR1, T1, T2>::Res R1; \
1342 typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2; \
1343 typedef typename PromoteTraits<R1, R2>::Promote R3; \
1344 typedef typename NumericTraits<R3>::RealPromote Res; \
1345 }; \
1346 \
1347 template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
1348 struct ResultTraits3<Functor_##function<EXPR1, EXPR2>, T1, T2, T3> \
1349 { \
1350 typedef typename ResultTraits3<EXPR1, T1, T2, T3>::Res R1; \
1351 typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2; \
1352 typedef typename PromoteTraits<R1, R2>::Promote R3; \
1353 typedef typename NumericTraits<R3>::RealPromote Res; \
1354 }; \
1355 \
1356 template <class EXPR1, class EXPR2> \
1357 struct Functor_##function \
1358 { \
1359 Functor_##function(EXPR1 const & e1, EXPR2 const & e2) \
1360 : expr1_(e1), expr2_(e2) \
1361 {} \
1362 \
1363 typename ResultTraits0<Functor_##function>::Res \
1364 operator()() const \
1365 { \
1366 return function(expr1_(), expr2_()); \
1367 } \
1368 \
1369 template <class T> \
1370 typename ResultTraits1<Functor_##function, T>::Res \
1371 operator()(T const & v1) const \
1372 { \
1373 return function(expr1_(v1), expr2_(v1)); \
1374 } \
1375 \
1376 template <class T1, class T2> \
1377 typename ResultTraits2<Functor_##function, T1, T2>::Res \
1378 operator()(T1 const & v1, T2 const & v2) const \
1379 { \
1380 return function(expr1_(v1, v2), expr2_(v1, v2)); \
1381 } \
1382 \
1383 template <class T1, class T2, class T3> \
1384 typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \
1385 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
1386 { \
1387 return function(expr1_(v1, v2, v3), expr2_(v1, v2, v3)); \
1388 } \
1389 \
1390 private: \
1391 \
1392 EXPR1 expr1_; \
1393 EXPR2 expr2_; \
1394 \
1395 Functor_##function & operator=(Functor_##function const &); \
1396 }; \
1397 \
1398 template <class EXPR1, class EXPR2> \
1399 inline UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
1400 function(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
1401 { \
1402 Functor_##function<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
1403 return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>, \
1404 UnaryFunctor<EXPR2> > >(p); \
1405 }
1406
1407 /************************************************************/
1408
1409 MAKE_FUNCTOR_BINARY_FUNCTION(pow)
1410 MAKE_FUNCTOR_BINARY_FUNCTION(atan2)
1411 MAKE_FUNCTOR_BINARY_FUNCTION(fmod)
1412
1413 #undef MAKE_FUNCTOR_BINARY_FUNCTION
1414
1415 /************************************************************/
1416
1417 #define MAKE_FUNCTOR_MINMAX(name, op) \
1418 template <class EXPR1, class EXPR2> \
1419 struct Functor_##name; \
1420 \
1421 template <class EXPR1, class EXPR2> \
1422 struct ResultTraits0<Functor_##name<EXPR1, EXPR2> > \
1423 { \
1424 typedef typename ResultTraits0<EXPR1>::Res R1; \
1425 typedef typename ResultTraits0<EXPR2>::Res R2; \
1426 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1427 }; \
1428 \
1429 template <class EXPR1, class EXPR2, class T1> \
1430 struct ResultTraits1<Functor_##name<EXPR1, EXPR2>, T1> \
1431 { \
1432 typedef typename ResultTraits1<EXPR1, T1>::Res R1; \
1433 typedef typename ResultTraits1<EXPR2, T1>::Res R2; \
1434 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1435 }; \
1436 \
1437 template <class EXPR1, class EXPR2, class T1, class T2> \
1438 struct ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2> \
1439 { \
1440 typedef typename ResultTraits2<EXPR1, T1, T2>::Res R1; \
1441 typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2; \
1442 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1443 }; \
1444 \
1445 template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
1446 struct ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3> \
1447 { \
1448 typedef typename ResultTraits3<EXPR1, T1, T2, T3>::Res R1; \
1449 typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2; \
1450 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1451 }; \
1452 \
1453 template <class EXPR1, class EXPR2> \
1454 struct Functor_##name \
1455 { \
1456 Functor_##name(EXPR1 const & e1, EXPR2 const & e2) \
1457 : expr1_(e1), expr2_(e2) \
1458 {} \
1459 \
1460 typename ResultTraits0<Functor_##name>::Res \
1461 operator()() const \
1462 { \
1463 typename \
1464 ResultTraits0<Functor_##name<EXPR1, EXPR2> >::R1 r1(expr1_()); \
1465 typename \
1466 ResultTraits0<Functor_##name<EXPR1, EXPR2> >::R2 r2(expr2_()); \
1467 return (r1 op r2) ? r1 : r2; \
1468 } \
1469 \
1470 template <class T> \
1471 typename ResultTraits1<Functor_##name, T>::Res \
1472 operator()(T const & v1) const \
1473 { \
1474 typename \
1475 ResultTraits1<Functor_##name<EXPR1, EXPR2>, T>::R1 r1(expr1_(v1)); \
1476 typename \
1477 ResultTraits1<Functor_##name<EXPR1, EXPR2>, T>::R2 r2(expr2_(v1)); \
1478 return (r1 op r2) ? r1 : r2; \
1479 } \
1480 \
1481 template <class T1, class T2> \
1482 typename ResultTraits2<Functor_##name, T1, T2>::Res \
1483 operator()(T1 const & v1, T2 const & v2) const \
1484 { \
1485 typename \
1486 ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2>::R1 r1(expr1_(v1, v2)); \
1487 typename \
1488 ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2>::R2 r2(expr2_(v1, v2)); \
1489 return (r1 op r2) ? r1 : r2; \
1490 } \
1491 \
1492 template <class T1, class T2, class T3> \
1493 typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
1494 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
1495 { \
1496 typename \
1497 ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R1 r1(expr1_(v1, v2, v3)); \
1498 typename \
1499 ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R2 r2(expr2_(v1, v2, v3)); \
1500 return (r1 op r2) ? r1 : r2; \
1501 } \
1502 \
1503 private: \
1504 \
1505 EXPR1 expr1_; \
1506 EXPR2 expr2_; \
1507 \
1508 Functor_##name & operator=(Functor_##name const &); \
1509 }; \
1510 \
1511 template <class EXPR1, class EXPR2> \
1512 inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
1513 name(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
1514 { \
1515 Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
1516 return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \
1517 UnaryFunctor<EXPR2> > >(p); \
1518 }
1519
1520 MAKE_FUNCTOR_MINMAX(min, <)
1521 MAKE_FUNCTOR_MINMAX(max, >)
1522
1523 #undef MAKE_FUNCTOR_MINMAX
1524
1525 /************************************************************/
1526 /* */
1527 /* functors for binary operators */
1528 /* */
1529 /************************************************************/
1530
1531 #define MAKE_FUNCTOR_BINARY_OPERATOR(name, op) \
1532 template <class EXPR1, class EXPR2> \
1533 struct Functor_##name; \
1534 \
1535 template <class EXPR1, class EXPR2> \
1536 struct ResultTraits0<Functor_##name<EXPR1, EXPR2> > \
1537 { \
1538 typedef typename ResultTraits0<EXPR1>::Res R1; \
1539 typedef typename ResultTraits0<EXPR2>::Res R2; \
1540 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1541 }; \
1542 \
1543 template <class EXPR1, class EXPR2, class T1> \
1544 struct ResultTraits1<Functor_##name<EXPR1, EXPR2>, T1> \
1545 { \
1546 typedef typename ResultTraits1<EXPR1, T1>::Res R1; \
1547 typedef typename ResultTraits1<EXPR2, T1>::Res R2; \
1548 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1549 }; \
1550 \
1551 template <class EXPR1, class EXPR2, class T1, class T2> \
1552 struct ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2> \
1553 { \
1554 typedef typename ResultTraits2<EXPR1, T1, T2>::Res R1; \
1555 typedef typename ResultTraits2<EXPR2, T1, T2>::Res R2; \
1556 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1557 }; \
1558 \
1559 template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
1560 struct ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3> \
1561 { \
1562 typedef typename ResultTraits3<EXPR1, T1, T2, T3>::Res R1; \
1563 typedef typename ResultTraits3<EXPR2, T1, T2, T3>::Res R2; \
1564 typedef typename PromoteTraits<R1, R2>::Promote Res; \
1565 }; \
1566 \
1567 template <class EXPR1, class EXPR2> \
1568 struct Functor_##name \
1569 { \
1570 Functor_##name(EXPR1 const & e1, EXPR2 const & e2) \
1571 : expr1_(e1), expr2_(e2) \
1572 {} \
1573 \
1574 typename ResultTraits0<Functor_##name>::Res \
1575 operator()() const \
1576 { \
1577 return expr1_() op expr2_(); \
1578 } \
1579 \
1580 template <class T> \
1581 typename ResultTraits1<Functor_##name, T>::Res \
1582 operator()(T const & v1) const \
1583 { \
1584 return expr1_(v1) op expr2_(v1); \
1585 } \
1586 \
1587 template <class T1, class T2> \
1588 typename ResultTraits2<Functor_##name, T1, T2>::Res \
1589 operator()(T1 const & v1, T2 const & v2) const \
1590 { \
1591 return expr1_(v1, v2) op expr2_(v1, v2); \
1592 } \
1593 \
1594 template <class T1, class T2, class T3> \
1595 typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
1596 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
1597 { \
1598 return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \
1599 } \
1600 \
1601 private: \
1602 \
1603 EXPR1 expr1_; \
1604 EXPR2 expr2_; \
1605 \
1606 Functor_##name & operator=(Functor_##name const &); \
1607 }; \
1608 \
1609 template <class EXPR1, class EXPR2> \
1610 inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
1611 operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
1612 { \
1613 Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
1614 return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \
1615 UnaryFunctor<EXPR2> > >(p); \
1616 }
1617
1618 /************************************************************/
1619
1620 MAKE_FUNCTOR_BINARY_OPERATOR(add, +)
1621 MAKE_FUNCTOR_BINARY_OPERATOR(subtract, -)
1622 MAKE_FUNCTOR_BINARY_OPERATOR(multiply, *)
1623 MAKE_FUNCTOR_BINARY_OPERATOR(divide, /)
1624 MAKE_FUNCTOR_BINARY_OPERATOR(modulo, %)
1625 MAKE_FUNCTOR_BINARY_OPERATOR(bitAnd, &)
1626 MAKE_FUNCTOR_BINARY_OPERATOR(bitOr, |)
1627 MAKE_FUNCTOR_BINARY_OPERATOR(bitXor, ^)
1628
1629 #undef MAKE_FUNCTOR_BINARY_OPERATOR
1630
1631 /************************************************************/
1632
1633 #define MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(name, op) \
1634 template <class EXPR1, class EXPR2> \
1635 struct Functor_##name; \
1636 \
1637 template <class EXPR1, class EXPR2> \
1638 struct ResultTraits0<Functor_##name<EXPR1, EXPR2> > \
1639 { \
1640 typedef bool Res; \
1641 }; \
1642 \
1643 template <class EXPR1, class EXPR2, class T1> \
1644 struct ResultTraits1<Functor_##name<EXPR1, EXPR2>, T1> \
1645 { \
1646 typedef bool Res; \
1647 }; \
1648 \
1649 template <class EXPR1, class EXPR2, class T1, class T2> \
1650 struct ResultTraits2<Functor_##name<EXPR1, EXPR2>, T1, T2> \
1651 { \
1652 typedef bool Res; \
1653 }; \
1654 \
1655 template <class EXPR1, class EXPR2, class T1, class T2, class T3> \
1656 struct ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3> \
1657 { \
1658 typedef bool Res; \
1659 }; \
1660 \
1661 template <class EXPR1, class EXPR2> \
1662 struct Functor_##name \
1663 { \
1664 Functor_##name(EXPR1 const & e1, EXPR2 const & e2) \
1665 : expr1_(e1), expr2_(e2) \
1666 {} \
1667 \
1668 bool operator()() const \
1669 { \
1670 return expr1_() op expr2_(); \
1671 } \
1672 \
1673 template <class T> \
1674 bool operator()(T const & v1) const \
1675 { \
1676 return expr1_(v1) op expr2_(v1); \
1677 } \
1678 \
1679 template <class T1, class T2> \
1680 bool operator()(T1 const & v1, T2 const & v2) const \
1681 { \
1682 return expr1_(v1, v2) op expr2_(v1, v2); \
1683 } \
1684 \
1685 template <class T1, class T2, class T3> \
1686 bool operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
1687 { \
1688 return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \
1689 } \
1690 \
1691 private: \
1692 \
1693 EXPR1 expr1_; \
1694 EXPR2 expr2_; \
1695 \
1696 Functor_##name & operator=(Functor_##name const &); \
1697 }; \
1698 \
1699 template <class EXPR1, class EXPR2> \
1700 inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \
1701 operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
1702 { \
1703 Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
1704 return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \
1705 UnaryFunctor<EXPR2> > >(p); \
1706 }
1707
1708 /************************************************************/
1709
1710 #ifdef __GNUC__
1711 #pragma GCC diagnostic push
1712 #pragma GCC diagnostic ignored "-Wsign-compare"
1713 #endif
1714
1715 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(equals, ==)
1716 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(differs, !=)
1717 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(less, <)
1718 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(lessEqual, <=)
1719 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(greater, >)
1720 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(greaterEqual, >=)
1721 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(and, &&)
1722 MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(or, ||)
1723
1724 #ifdef __GNUC__
1725 #pragma GCC diagnostic pop
1726 #endif
1727
1728 #undef MAKE_FUNCTOR_BINARY_OPERATOR_BOOL
1729
1730 /************************************************************/
1731 /* */
1732 /* unary apply */
1733 /* */
1734 /************************************************************/
1735
1736 template <class EXPR, class RES, class ARG>
1737 struct UnaryFctPtrFunctor
1738 {
1739 UnaryFctPtrFunctor(EXPR const & e, RES (*fct)(ARG))
1740 : expr_(e), f_(fct)
1741 {}
1742
1743 RES operator()() const
1744 {
1745 return f_(expr_());
1746 }
1747
1748 template <class T>
1749 RES operator()(T const & v1) const
1750 {
1751 return f_(expr_(v1));
1752 }
1753
1754 template <class T1, class T2>
1755 RES operator()(T1 const & v1, T2 const & v2) const
1756 {
1757 return f_(expr_(v1, v2));
1758 }
1759
1760 template <class T1, class T2, class T3>
1761 RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
1762 {
1763 return f_(expr_(v1, v2, v3));
1764 }
1765 protected:
1766
1767 EXPR expr_;
1768 RES (*f_)(ARG);
1769
1770 private:
1771 UnaryFctPtrFunctor & operator=(UnaryFctPtrFunctor const &); // not implemented
1772 };
1773
1774 template <class EXPR, class RES, class ARG>
1775 struct ResultTraits0<UnaryFctPtrFunctor<EXPR, RES, ARG> >
1776 {
1777 typedef RES Res;
1778 };
1779
1780 template <class EXPR, class RES, class ARG, class T1>
1781 struct ResultTraits1<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1>
1782 {
1783 typedef RES Res;
1784 };
1785
1786 template <class EXPR, class RES, class ARG, class T1, class T2>
1787 struct ResultTraits2<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1, T2>
1788 {
1789 typedef RES Res;
1790 };
1791
1792 template <class EXPR, class RES, class ARG, class T1, class T2, class T3>
1793 struct ResultTraits3<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1, T2, T3>
1794 {
1795 typedef RES Res;
1796 };
1797
1798 template <class EXPR, class RES, class ARG>
1799 inline UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> >
1800 applyFct(RES (*f)(ARG), UnaryFunctor<EXPR> const & e)
1801 {
1802 UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> p(e, f);
1803 return UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> >(p);
1804 }
1805
1806 /************************************************************/
1807 /* */
1808 /* binary apply */
1809 /* */
1810 /************************************************************/
1811
1812 template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
1813 struct BinaryFctPtrFunctor
1814 {
1815 BinaryFctPtrFunctor(EXPR1 const & e1, EXPR2 const & e2,
1816 RES (*f)(ARG1, ARG2))
1817 : expr1_(e1), expr2_(e2), f_(f)
1818 {}
1819
1820 RES operator()() const
1821 {
1822 return f_(expr1_(), expr2_());
1823 }
1824
1825 template <class T>
1826 RES operator()(T const & v1) const
1827 {
1828 return f_(expr1_(v1), expr2_(v1));
1829 }
1830
1831 template <class T1, class T2>
1832 RES operator()(T1 const & v1, T2 const & v2) const
1833 {
1834 return f_(expr1_(v1, v2), expr2_(v1, v2));
1835 }
1836
1837 template <class T1, class T2, class T3>
1838 RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
1839 {
1840 return f_(expr1_(v1, v2, v3), expr2_(v1, v2, v3));
1841 }
1842
1843 protected:
1844
1845 EXPR1 expr1_;
1846 EXPR2 expr2_;
1847 RES (*f_)(ARG1, ARG2);
1848
1849 private:
1850 BinaryFctPtrFunctor & operator=(BinaryFctPtrFunctor const &); // not implemented
1851 };
1852
1853 template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
1854 struct ResultTraits0<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2> >
1855 {
1856 typedef RES Res;
1857 };
1858
1859 template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2,
1860 class T1>
1861 struct ResultTraits1<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1>
1862 {
1863 typedef RES Res;
1864 };
1865
1866 template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2,
1867 class T1, class T2>
1868 struct ResultTraits2<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1, T2>
1869 {
1870 typedef RES Res;
1871 };
1872
1873 template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2,
1874 class T1, class T2, class T3>
1875 struct ResultTraits3<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1, T2, T3>
1876 {
1877 typedef RES Res;
1878 };
1879
1880 template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
1881 inline UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>,
1882 UnaryFunctor<EXPR2>,
1883 RES, ARG1, ARG2> >
1884 applyFct(RES (*f)(ARG1, ARG2), UnaryFunctor<EXPR1> const & e1,
1885 UnaryFunctor<EXPR2> const & e2)
1886 {
1887 BinaryFctPtrFunctor<UnaryFunctor<EXPR1>,
1888 UnaryFunctor<EXPR2>,
1889 RES, ARG1, ARG2> p(e1, e2, f);
1890 return UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>,
1891 UnaryFunctor<EXPR2>,
1892 RES, ARG1, ARG2> >(p);
1893 }
1894
1895 /************************************************************/
1896 /* */
1897 /* comma operator */
1898 /* */
1899 /************************************************************/
1900
1901 template <class EXPR1, class EXPR2>
1902 struct CommaFunctor
1903 {
1904 CommaFunctor(EXPR1 const & e1, EXPR2 const & e2)
1905 : expr1_(e1), expr2_(e2)
1906 {}
1907
1908 typename ResultTraits0<EXPR2>::Res
1909 operator()() const
1910 {
1911 expr1_();
1912 return expr2_();
1913 }
1914
1915 template <class T>
1916 typename ResultTraits1<EXPR2, T>::Res
1917 operator()(T const & v1) const
1918 {
1919 expr1_(v1);
1920 return expr2_(v1);
1921 }
1922
1923 template <class T1, class T2>
1924 typename ResultTraits2<EXPR2, T1, T2>::Res
1925 operator()(T1 const & v1, T2 const & v2) const
1926 {
1927 expr1_(v1, v2);
1928 return expr2_(v1, v2);
1929 }
1930
1931 template <class T1, class T2, class T3>
1932 typename ResultTraits3<EXPR2, T1, T2, T3>::Res
1933 operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
1934 {
1935 expr1_(v1, v2, v3);
1936 return expr2_(v1, v2, v3);
1937 }
1938
1939 protected:
1940
1941 EXPR1 expr1_;
1942 EXPR2 expr2_;
1943
1944 private:
1945 CommaFunctor & operator=(CommaFunctor const &); // not implemented
1946 };
1947
1948 template <class Expr1, class Expr2>
1949 struct ResultTraits0<CommaFunctor<Expr1, Expr2> >
1950 {
1951 typedef typename ResultTraits0<Expr2>::Res Res;
1952 };
1953
1954 template <class Expr1, class Expr2, class T1>
1955 struct ResultTraits1<CommaFunctor<Expr1, Expr2>, T1>
1956 {
1957 typedef typename ResultTraits1<Expr2, T1>::Res Res;
1958 };
1959
1960 template <class Expr1, class Expr2, class T1, class T2>
1961 struct ResultTraits2<CommaFunctor<Expr1, Expr2>, T1, T2>
1962 {
1963 typedef typename ResultTraits2<Expr2, T1, T2>::Res Res;
1964 };
1965
1966 template <class Expr1, class Expr2, class T1, class T2, class T3>
1967 struct ResultTraits3<CommaFunctor<Expr1, Expr2>, T1, T2, T3>
1968 {
1969 typedef typename ResultTraits3<Expr2, T1, T2, T3>::Res Res;
1970 };
1971
1972 template <class EXPR1, class EXPR2>
1973 inline UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>,
1974 UnaryFunctor<EXPR2> > >
1975 operator,(UnaryAnalyser<EXPR1> const & e1,
1976 UnaryFunctor<EXPR2> const & e2)
1977 {
1978 CommaFunctor<UnaryAnalyser<EXPR1>,
1979 UnaryFunctor<EXPR2> > p(e1, e2);
1980 return UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>,
1981 UnaryFunctor<EXPR2> > >(p);
1982 }
1983
1984 /************************************************************/
1985
1986 template <class EXPR1, class EXPR2>
1987 struct CommaAnalyser
1988 {
1989 CommaAnalyser(EXPR1 const & e1, EXPR2 const & e2)
1990 : expr1_(e1), expr2_(e2)
1991 {}
1992
1993 void operator()() const
1994 {
1995 expr1_();
1996 expr2_();
1997 }
1998
1999 template <class T>
2000 void operator()(T const & v1) const
2001 {
2002 expr1_(v1);
2003 expr2_(v1);
2004 }
2005
2006 template <class T1, class T2>
2007 void operator()(T1 const & v1, T2 const & v2) const
2008 {
2009 expr1_(v1, v2);
2010 expr2_(v1, v2);
2011 }
2012
2013 template <class T1, class T2, class T3>
2014 void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
2015 {
2016 expr1_(v1, v2, v3);
2017 expr2_(v1, v2, v3);
2018 }
2019
2020 protected:
2021
2022 EXPR1 expr1_;
2023 EXPR2 expr2_;
2024
2025 private:
2026 CommaAnalyser & operator=(CommaAnalyser const &); // not implemented
2027 };
2028
2029 template <class EXPR1, class EXPR2>
2030 inline UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>,
2031 UnaryAnalyser<EXPR2> > >
2032 operator,(UnaryAnalyser<EXPR1> const & e1,
2033 UnaryAnalyser<EXPR2> const & e2)
2034 {
2035 CommaAnalyser<UnaryAnalyser<EXPR1>,
2036 UnaryAnalyser<EXPR2> > p(e1, e2);
2037 return UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>,
2038 UnaryAnalyser<EXPR2> > >(p);
2039 }
2040
2041 } // namespace functor
2042
2043 #if defined(__GNUC__) && __GNUC__ < 3
2044 using functor::Arg1;
2045 using functor::Arg2;
2046 using functor::Arg3;
2047 using functor::Param;
2048 #endif
2049
2050 template <class T>
2051 class FunctorTraits<functor::UnaryFunctor<T> >
2052 : public FunctorTraitsBase<functor::UnaryFunctor<T> >
2053 {
2054 public:
2055 typedef VigraTrueType isInitializer;
2056 typedef VigraTrueType isUnaryFunctor;
2057 typedef VigraTrueType isBinaryFunctor;
2058 typedef VigraTrueType isTernaryFunctor;
2059 };
2060
2061 template <class T>
2062 class FunctorTraits<functor::UnaryAnalyser<T> >
2063 : public FunctorTraitsBase<functor::UnaryAnalyser<T> >
2064 {
2065 public:
2066 typedef VigraTrueType isUnaryAnalyser;
2067 typedef VigraTrueType isBinaryAnalyser;
2068 typedef VigraTrueType isTernaryAnalyser;
2069 };
2070
2071
2072
2073 } // namespace vigra
2074
2075 #endif /* NO_PARTIAL_TEMPLATE_SPECIALIZATION */
2076
2077 #endif // DOXYGEN
2078
2079 #endif /* VIGRA_FUNCTOREXPRESSION_HXX */
2080
2081
vigra::linalg::acos
linalg::TemporaryMatrix< T > acos(MultiArrayView< 2, T, C > const &v)
vigra::atan2
FixedPoint16< 2, OverflowHandling > atan2(FixedPoint16< IntBits, OverflowHandling > y, FixedPoint16< IntBits, OverflowHandling > x)
Arctangent. Accuracy better than 1/3 degree (9 significant bits).
Definition: fixedpoint.hxx:1654
vigra::linalg::sin
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
vigra::linalg::exp
linalg::TemporaryMatrix< T > exp(MultiArrayView< 2, T, C > const &v)
vigra::squaredNorm
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition: fftw3.hxx:1044
vigra::linalg::asin
linalg::TemporaryMatrix< T > asin(MultiArrayView< 2, T, C > const &v)
vigra::add
void add(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
addition with enforced result type.
Definition: fixedpoint.hxx:561
vigra::operator-=
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
vigra::norm
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition: fftw3.hxx:1037
vigra::operator+=
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
vigra::sq
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:382
vigra::linalg::log10
linalg::TemporaryMatrix< T > log10(MultiArrayView< 2, T, C > const &v)
vigra::operator*=
FFTWComplex< R > & operator*=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
multiply-assignment
Definition: fftw3.hxx:875
vigra::linalg::log
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
vigra::abs
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
vigra::linalg::atan
linalg::TemporaryMatrix< T > atan(MultiArrayView< 2, T, C > const &v)
vigra::linalg::tan
linalg::TemporaryMatrix< T > tan(MultiArrayView< 2, T, C > const &v)
vigra::operator/=
FFTWComplex< R > & operator/=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
divide-assignment
Definition: fftw3.hxx:884
vigra::ceil
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition: fixedpoint.hxx:675
vigra::linalg::cos
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
vigra::floor
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition: fixedpoint.hxx:667
vigra::sqrt
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.11.0 (Fri May 19 2017)