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