1 /************************************************************************/
2 /*                                                                      */
3 /*               Copyright 1998-2005 by Ullrich Koethe                  */
4 /*       Cognitive Systems Group, University of Hamburg, Germany        */
5 /*                                                                      */
6 /*    This file is part of the VIGRA computer vision library.           */
7 /*    ( Version 1.5.0, Dec 07 2006 )                                    */
8 /*    The VIGRA Website is                                              */
9 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
10 /*    Please direct questions, bug reports, and contributions to        */
11 /*        koethe@informatik.uni-hamburg.de          or                  */
12 /*        vigra@kogs1.informatik.uni-hamburg.de                         */
13 /*                                                                      */
14 /*    Permission is hereby granted, free of charge, to any person       */
15 /*    obtaining a copy of this software and associated documentation    */
16 /*    files (the "Software"), to deal in the Software without           */
17 /*    restriction, including without limitation the rights to use,      */
18 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
19 /*    sell copies of the Software, and to permit persons to whom the    */
20 /*    Software is furnished to do so, subject to the following          */
21 /*    conditions:                                                       */
22 /*                                                                      */
23 /*    The above copyright notice and this permission notice shall be    */
24 /*    included in all copies or substantial portions of the             */
25 /*    Software.                                                         */
26 /*                                                                      */
27 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
28 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
29 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
30 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
31 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
32 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
33 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
34 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
35 /*                                                                      */
36 /************************************************************************/
37 
38 
39 #ifndef VIGRA_FUNCTORTRAITS_HXX
40 #define VIGRA_FUNCTORTRAITS_HXX
41 
42 #include <functional>
43 #include "metaprogramming.hxx"
44 
45 namespace vigra {
46 
47 template <class T>
48 class FunctorTraitsBase
49 {
50   public:
51     typedef T type;
52 
53     typedef VigraFalseType isInitializer;
54 
55     typedef VigraFalseType isUnaryFunctor;
56     typedef VigraFalseType isBinaryFunctor;
57     typedef VigraFalseType isTernaryFunctor;
58 
59     typedef VigraFalseType isUnaryAnalyser;
60     typedef VigraFalseType isBinaryAnalyser;
61     typedef VigraFalseType isTernaryAnalyser;
62 };
63 
64 
65 
66 /** \addtogroup Functors
67 */
68 //@{
69 /** \brief Export associated information for a functor.
70 
71     The FunctorTraits class contains the following fields:
72 
73     \code
74     template <class T>
75     struct FunctorTraits
76     {
77         typedef T type;
78 
79         typedef ... isInitializer;
80 
81         typedef ... isUnaryFunctor;
82         typedef ... isBinaryFunctor;
83         typedef ... isTernaryFunctor;
84 
85         typedef ... isUnaryAnalyser;
86         typedef ... isBinaryAnalyser;
87         typedef ... isTernaryAnalyser;
88     };
89     \endcode
90 
91     Where the dots are either <tt>VigraTrueType</tt> or <tt>VigraFalseType</tt>
92     depending on whether the functor supports the respective functionality or not.
93     If a functor <tt>f<tt> is a model of these categories, it supports the following
94     calls (<tt>v</tt> is a variable such that the result type of the functor
95     calls can be converted into <tt>v</tt>'s type, and <tt>a1, a2, a3</tt> are
96     variables convertible into the functor's argument types):
97 
98     <DL>
99     <DT><b>Initializer</b>
100         <DD> <tt>v = f()</tt> (used with initImageWithFunctor())
101     <DT><b>UnaryFunctor</b>
102         <DD> <tt>v = f(a1)</tt> (used with transformImage())
103     <DT><b>BinaryFunctor</b>
104         <DD> <tt>v = f(a1, a2)</tt> (used with combineTwoImages())
105     <DT><b>TernaryFunctor</b>
106         <DD> <tt>v = f(a1, a2, a3)</tt> (used with combineThreeImages())
107     <DT><b>UnaryAnalyser</b>
108         <DD> <tt>f(a1)</tt> (return type <tt>void>/tt>, used with inspectImage())
109     <DT><b>BinaryAnalyser</b>
110         <DD> <tt>f(a1, a2)</tt> (return type <tt>void>/tt>, used with inspectTwoImages())
111     <DT><b>TernaryAnalyser</b>
112         <DD> <tt>f(a1, a2, a3)</tt> (return type <tt>void>/tt>)
113     </DL>
114 
115     It should be noted that the functor's argument and result types are not contained
116     in the traits class: Since the function calls are often member template functions in
117     VIGRA, many functors do not have fixed argument types. Neither are the result
118     types fixed in this case because they are computed (via a template meta-program)
119     from the argument types.
120 
121     <b>\#include</b> "<a href="functortraits_8hxx-source.html">vigra/functortraits.hxx</a>"
122     Namespace: vigra
123 */
124 template <class T>
125 class FunctorTraits
126 : public FunctorTraitsBase<T>
127 {};
128 
129 #define VIGRA_DEFINE_STL_FUNCTOR(name, unary, binary) \
130 template <class T> \
131 class FunctorTraits<name<T> > \
132 { \
133   public: \
134     typedef T type; \
135      \
136     typedef VigraFalseType isInitializer; \
137      \
138     typedef unary          isUnaryFunctor; \
139     typedef binary         isBinaryFunctor; \
140     typedef VigraFalseType isTernaryFunctor; \
141      \
142     typedef VigraFalseType isUnaryAnalyser; \
143     typedef VigraFalseType isBinaryAnalyser; \
144     typedef VigraFalseType isTernaryAnalyser; \
145 };
146 
147 // ???TODO: these should also be specialized for the ptr_fun and mem_fun_ptr wrappers
148 VIGRA_DEFINE_STL_FUNCTOR(std::plus, VigraFalseType, VigraTrueType)
149 VIGRA_DEFINE_STL_FUNCTOR(std::minus, VigraFalseType, VigraTrueType)
150 VIGRA_DEFINE_STL_FUNCTOR(std::multiplies, VigraFalseType, VigraTrueType)
151 VIGRA_DEFINE_STL_FUNCTOR(std::divides, VigraFalseType, VigraTrueType)
152 VIGRA_DEFINE_STL_FUNCTOR(std::modulus, VigraFalseType, VigraTrueType)
153 VIGRA_DEFINE_STL_FUNCTOR(std::equal_to, VigraFalseType, VigraTrueType)
154 VIGRA_DEFINE_STL_FUNCTOR(std::not_equal_to, VigraFalseType, VigraTrueType)
155 VIGRA_DEFINE_STL_FUNCTOR(std::greater, VigraFalseType, VigraTrueType)
156 VIGRA_DEFINE_STL_FUNCTOR(std::less, VigraFalseType, VigraTrueType)
157 VIGRA_DEFINE_STL_FUNCTOR(std::greater_equal, VigraFalseType, VigraTrueType)
158 VIGRA_DEFINE_STL_FUNCTOR(std::less_equal, VigraFalseType, VigraTrueType)
159 VIGRA_DEFINE_STL_FUNCTOR(std::logical_and, VigraFalseType, VigraTrueType)
160 VIGRA_DEFINE_STL_FUNCTOR(std::logical_or, VigraFalseType, VigraTrueType)
161 VIGRA_DEFINE_STL_FUNCTOR(std::binary_negate, VigraFalseType, VigraTrueType)
162 
163 VIGRA_DEFINE_STL_FUNCTOR(std::negate, VigraTrueType, VigraFalseType)
164 VIGRA_DEFINE_STL_FUNCTOR(std::logical_not, VigraTrueType, VigraFalseType)
165 VIGRA_DEFINE_STL_FUNCTOR(std::unary_negate, VigraTrueType, VigraFalseType)
166 VIGRA_DEFINE_STL_FUNCTOR(std::binder1st, VigraTrueType, VigraFalseType)
167 VIGRA_DEFINE_STL_FUNCTOR(std::binder2nd, VigraTrueType, VigraFalseType)
168 #undef VIGRA_DEFINE_STL_FUNCTOR
169 
170 template <class R>
171 class FunctorTraits<R (*)()>
172 {
173   public:
174     typedef R (*type)();
175 
176     typedef VigraTrueType  isInitializer;
177     typedef VigraFalseType isUnaryFunctor;
178     typedef VigraFalseType isBinaryFunctor;
179     typedef VigraFalseType isTernaryFunctor;
180     typedef VigraFalseType isUnaryAnalyser;
181     typedef VigraFalseType isBinaryAnalyser;
182     typedef VigraFalseType isTernaryAnalyser;
183 };
184 
185 template <class R, class T>
186 class FunctorTraits<R (*)(T)>
187 {
188   public:
189     typedef R (*type)(T);
190 
191     typedef VigraFalseType isInitializer;
192     typedef VigraTrueType  isUnaryFunctor;
193     typedef VigraFalseType isBinaryFunctor;
194     typedef VigraFalseType isTernaryFunctor;
195     typedef VigraFalseType isUnaryAnalyser;
196     typedef VigraFalseType isBinaryAnalyser;
197     typedef VigraFalseType isTernaryAnalyser;
198 };
199 
200 template <class R, class T1, class T2>
201 class FunctorTraits<R (*)(T1, T2)>
202 {
203   public:
204     typedef R (*type)(T1, T2);
205 
206     typedef VigraFalseType isInitializer;
207     typedef VigraFalseType isUnaryFunctor;
208     typedef VigraTrueType  isBinaryFunctor;
209     typedef VigraFalseType isTernaryFunctor;
210     typedef VigraFalseType isUnaryAnalyser;
211     typedef VigraFalseType isBinaryAnalyser;
212     typedef VigraFalseType isTernaryAnalyser;
213 };
214 
215 template <class R, class T1, class T2, class T3>
216 class FunctorTraits<R (*)(T1, T2, T3)>
217 {
218   public:
219     typedef R (*type)(T1, T2, T3);
220 
221     typedef VigraFalseType isInitializer;
222     typedef VigraFalseType isUnaryFunctor;
223     typedef VigraFalseType isBinaryFunctor;
224     typedef VigraTrueType  isTernaryFunctor;
225     typedef VigraFalseType isUnaryAnalyser;
226     typedef VigraFalseType isBinaryAnalyser;
227     typedef VigraFalseType isTernaryAnalyser;
228 };
229 
230 //@}
231 
232 } // namespace vigra
233 
234 #endif // VIGRA_FUNCTORTRAITS_HXX
235