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

functortraits.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2005 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 
37 #ifndef VIGRA_FUNCTORTRAITS_HXX
38 #define VIGRA_FUNCTORTRAITS_HXX
39 
40 #include <functional>
41 #include "metaprogramming.hxx"
42 
43 namespace vigra {
44 
45 struct InitializerTag {};
46 struct UnaryFunctorTag {};
47 struct BinaryFunctorTag {};
48 struct TernaryFunctorTag {};
49 struct UnaryAnalyserTag {};
50 struct BinaryAnalyserTag {};
51 struct TernaryAnalyserTag {};
52 
53 struct UnaryReduceFunctorTag
54 : public InitializerTag, public UnaryAnalyserTag
55 {};
56 
57 struct BinaryReduceFunctorTag
58 : public InitializerTag, public BinaryAnalyserTag
59 {};
60 
61 typedef UnaryFunctorTag UnaryExpandFunctorTag;
62 typedef BinaryFunctorTag BinaryExpandFunctorTag;
63 
64 template <class T>
65 class FunctorTraitsBase
66 {
67  public:
68  typedef T type;
69 
70  typedef typename IsDerivedFrom<T, InitializerTag>::result isInitializer;
71 
72  typedef typename IsDerivedFrom<T, UnaryFunctorTag>::result isUnaryFunctor;
73  typedef typename IsDerivedFrom<T, BinaryFunctorTag>::result isBinaryFunctor;
74  typedef typename IsDerivedFrom<T, TernaryFunctorTag>::result isTernaryFunctor;
75 
76  typedef typename IsDerivedFrom<T, UnaryAnalyserTag>::result isUnaryAnalyser;
77  typedef typename IsDerivedFrom<T, BinaryAnalyserTag>::result isBinaryAnalyser;
78  typedef typename IsDerivedFrom<T, TernaryAnalyserTag>::result isTernaryAnalyser;
79 };
80 
81 
82 
83 /** \addtogroup Functors
84 */
85 //@{
86 /** \brief Export associated information for a functor.
87 
88  The FunctorTraits class contains the following fields:
89 
90  \code
91  template <class T>
92  struct FunctorTraits
93  {
94  typedef T type;
95 
96  typedef ... isInitializer;
97 
98  typedef ... isUnaryFunctor;
99  typedef ... isBinaryFunctor;
100  typedef ... isTernaryFunctor;
101 
102  typedef ... isUnaryAnalyser;
103  typedef ... isBinaryAnalyser;
104  typedef ... isTernaryAnalyser;
105  };
106  \endcode
107 
108  where the dots are either <tt>VigraTrueType</tt> or <tt>VigraFalseType</tt>
109  depending on whether the functor supports the respective functionality or not.
110  Note that these traits are automatically defined correctly when your functor is derived
111  from the appropriate functor tag classes:
112 
113  \code
114  struct InitializerTag {};
115  struct UnaryFunctorTag {};
116  struct BinaryFunctorTag {};
117  struct TernaryFunctorTag {};
118  struct UnaryAnalyserTag {};
119  struct BinaryAnalyserTag {};
120  struct TernaryAnalyserTag {};
121  struct UnaryReduceFunctorTag : public InitializerTag, public UnaryAnalyserTag {};
122  struct BinaryReduceFunctorTag : public InitializerTag, public BinaryAnalyserTag {};
123  \endcode
124 
125  If a functor <tt>f</tt> is a model of these categories, it supports the following
126  calls (<tt>v</tt> is a variable such that the result type of the functor
127  calls can be converted into <tt>v</tt>'s type, and <tt>a1, a2, a3</tt> are
128  variables convertible into the functor's argument types):
129 
130  <DL>
131  <DT><b>Initializer</b>
132  <DD> <tt>v = f()</tt> (used with initImageWithFunctor())
133  <DT><b>UnaryFunctor</b>
134  <DD> <tt>v = f(a1)</tt> (used with transformImage())
135  <DT><b>BinaryFunctor</b>
136  <DD> <tt>v = f(a1, a2)</tt> (used with combineTwoImages())
137  <DT><b>TernaryFunctor</b>
138  <DD> <tt>v = f(a1, a2, a3)</tt> (used with combineThreeImages())
139  <DT><b>UnaryAnalyser</b>
140  <DD> <tt>f(a1)</tt> (return type <tt>void</tt>, used with inspectImage())
141  <DT><b>BinaryAnalyser</b>
142  <DD> <tt>f(a1, a2)</tt> (return type <tt>void</tt>, used with inspectTwoImages())
143  <DT><b>TernaryAnalyser</b>
144  <DD> <tt>f(a1, a2, a3)</tt> (return type <tt>void</tt>)
145  </DL>
146 
147  It should be noted that the functor's argument and result types are not contained
148  in the traits class: Since the function calls are often member template functions in
149  VIGRA, many functors do not have fixed argument types. Neither are the result
150  types fixed in this case because they are computed (via a template meta-program)
151  from the argument types.
152 
153  <b>\#include</b> <vigra/functortraits.hxx> <br/>
154  Namespace: vigra
155 */
156 template <class T>
158 : public FunctorTraitsBase<T>
159 {};
160 
161 #define VIGRA_DEFINE_STL_FUNCTOR(name, unary, binary) \
162 template <class T> \
163 class FunctorTraits<name<T> > \
164 { \
165  public: \
166  typedef T type; \
167  \
168  typedef VigraFalseType isInitializer; \
169  \
170  typedef unary isUnaryFunctor; \
171  typedef binary isBinaryFunctor; \
172  typedef VigraFalseType isTernaryFunctor; \
173  \
174  typedef VigraFalseType isUnaryAnalyser; \
175  typedef VigraFalseType isBinaryAnalyser; \
176  typedef VigraFalseType isTernaryAnalyser; \
177 };
178 
179 // ???TODO: these should also be specialized for the ptr_fun and mem_fun_ptr wrappers
180 VIGRA_DEFINE_STL_FUNCTOR(std::plus, VigraFalseType, VigraTrueType)
181 VIGRA_DEFINE_STL_FUNCTOR(std::minus, VigraFalseType, VigraTrueType)
182 VIGRA_DEFINE_STL_FUNCTOR(std::multiplies, VigraFalseType, VigraTrueType)
183 VIGRA_DEFINE_STL_FUNCTOR(std::divides, VigraFalseType, VigraTrueType)
184 VIGRA_DEFINE_STL_FUNCTOR(std::modulus, VigraFalseType, VigraTrueType)
185 VIGRA_DEFINE_STL_FUNCTOR(std::equal_to, VigraFalseType, VigraTrueType)
186 VIGRA_DEFINE_STL_FUNCTOR(std::not_equal_to, VigraFalseType, VigraTrueType)
187 VIGRA_DEFINE_STL_FUNCTOR(std::greater, VigraFalseType, VigraTrueType)
188 VIGRA_DEFINE_STL_FUNCTOR(std::less, VigraFalseType, VigraTrueType)
189 VIGRA_DEFINE_STL_FUNCTOR(std::greater_equal, VigraFalseType, VigraTrueType)
190 VIGRA_DEFINE_STL_FUNCTOR(std::less_equal, VigraFalseType, VigraTrueType)
191 VIGRA_DEFINE_STL_FUNCTOR(std::logical_and, VigraFalseType, VigraTrueType)
192 VIGRA_DEFINE_STL_FUNCTOR(std::logical_or, VigraFalseType, VigraTrueType)
193 VIGRA_DEFINE_STL_FUNCTOR(std::binary_negate, VigraFalseType, VigraTrueType)
194 
195 VIGRA_DEFINE_STL_FUNCTOR(std::negate, VigraTrueType, VigraFalseType)
196 VIGRA_DEFINE_STL_FUNCTOR(std::logical_not, VigraTrueType, VigraFalseType)
197 VIGRA_DEFINE_STL_FUNCTOR(std::unary_negate, VigraTrueType, VigraFalseType)
198 VIGRA_DEFINE_STL_FUNCTOR(std::binder1st, VigraTrueType, VigraFalseType)
199 VIGRA_DEFINE_STL_FUNCTOR(std::binder2nd, VigraTrueType, VigraFalseType)
200 #undef VIGRA_DEFINE_STL_FUNCTOR
201 
202 template <class R>
203 class FunctorTraits<R (*)()>
204 {
205  public:
206  typedef R (*type)();
207 
208  typedef VigraTrueType isInitializer;
209  typedef VigraFalseType isUnaryFunctor;
210  typedef VigraFalseType isBinaryFunctor;
211  typedef VigraFalseType isTernaryFunctor;
212  typedef VigraFalseType isUnaryAnalyser;
213  typedef VigraFalseType isBinaryAnalyser;
214  typedef VigraFalseType isTernaryAnalyser;
215 };
216 
217 template <class R, class T>
218 class FunctorTraits<R (*)(T)>
219 {
220  public:
221  typedef R (*type)(T);
222 
223  typedef VigraFalseType isInitializer;
224  typedef VigraTrueType isUnaryFunctor;
225  typedef VigraFalseType isBinaryFunctor;
226  typedef VigraFalseType isTernaryFunctor;
227  typedef VigraFalseType isUnaryAnalyser;
228  typedef VigraFalseType isBinaryAnalyser;
229  typedef VigraFalseType isTernaryAnalyser;
230 };
231 
232 template <class R, class T1, class T2>
233 class FunctorTraits<R (*)(T1, T2)>
234 {
235  public:
236  typedef R (*type)(T1, T2);
237 
238  typedef VigraFalseType isInitializer;
239  typedef VigraFalseType isUnaryFunctor;
240  typedef VigraTrueType isBinaryFunctor;
241  typedef VigraFalseType isTernaryFunctor;
242  typedef VigraFalseType isUnaryAnalyser;
243  typedef VigraFalseType isBinaryAnalyser;
244  typedef VigraFalseType isTernaryAnalyser;
245 };
246 
247 template <class R, class T1, class T2, class T3>
248 class FunctorTraits<R (*)(T1, T2, T3)>
249 {
250  public:
251  typedef R (*type)(T1, T2, T3);
252 
253  typedef VigraFalseType isInitializer;
254  typedef VigraFalseType isUnaryFunctor;
255  typedef VigraFalseType isBinaryFunctor;
256  typedef VigraTrueType isTernaryFunctor;
257  typedef VigraFalseType isUnaryAnalyser;
258  typedef VigraFalseType isBinaryAnalyser;
259  typedef VigraFalseType isTernaryAnalyser;
260 };
261 
262 //@}
263 
264 } // namespace vigra
265 
266 #endif // VIGRA_FUNCTORTRAITS_HXX
Export associated information for a functor.
Definition: functortraits.hxx:157

© 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)