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

functorexpression.hxx VIGRA

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 
linalg::TemporaryMatrix< T > acos(MultiArrayView< 2, T, C > const &v)
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
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
linalg::TemporaryMatrix< T > exp(MultiArrayView< 2, T, C > const &v)
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition: fftw3.hxx:1044
linalg::TemporaryMatrix< T > asin(MultiArrayView< 2, T, C > const &v)
void add(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
addition with enforced result type.
Definition: fixedpoint.hxx:561
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition: fftw3.hxx:1037
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:382
linalg::TemporaryMatrix< T > log10(MultiArrayView< 2, T, C > const &v)
FFTWComplex< R > & operator*=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
multiply-assignment
Definition: fftw3.hxx:875
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
linalg::TemporaryMatrix< T > atan(MultiArrayView< 2, T, C > const &v)
linalg::TemporaryMatrix< T > tan(MultiArrayView< 2, T, C > const &v)
FFTWComplex< R > & operator/=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
divide-assignment
Definition: fftw3.hxx:884
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition: fixedpoint.hxx:675
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition: fixedpoint.hxx:667
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.1 (Fri May 19 2017)