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

vigra/functortraits.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2005 by Ullrich Koethe                  */
00004 /*                                                                      */
00005 /*    This file is part of the VIGRA computer vision library.           */
00006 /*    The VIGRA Website is                                              */
00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
00008 /*    Please direct questions, bug reports, and contributions to        */
00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
00010 /*        vigra@informatik.uni-hamburg.de                               */
00011 /*                                                                      */
00012 /*    Permission is hereby granted, free of charge, to any person       */
00013 /*    obtaining a copy of this software and associated documentation    */
00014 /*    files (the "Software"), to deal in the Software without           */
00015 /*    restriction, including without limitation the rights to use,      */
00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00017 /*    sell copies of the Software, and to permit persons to whom the    */
00018 /*    Software is furnished to do so, subject to the following          */
00019 /*    conditions:                                                       */
00020 /*                                                                      */
00021 /*    The above copyright notice and this permission notice shall be    */
00022 /*    included in all copies or substantial portions of the             */
00023 /*    Software.                                                         */
00024 /*                                                                      */
00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
00033 /*                                                                      */
00034 /************************************************************************/
00035 
00036 
00037 #ifndef VIGRA_FUNCTORTRAITS_HXX
00038 #define VIGRA_FUNCTORTRAITS_HXX
00039 
00040 #include <functional>
00041 #include "metaprogramming.hxx"
00042 
00043 namespace vigra {
00044 
00045 struct InitializerTag {};
00046 struct UnaryFunctorTag {};
00047 struct BinaryFunctorTag {};
00048 struct TernaryFunctorTag {};
00049 struct UnaryAnalyserTag {};
00050 struct BinaryAnalyserTag {};
00051 struct TernaryAnalyserTag {};
00052 
00053 struct UnaryReduceFunctorTag
00054 : public InitializerTag, public UnaryAnalyserTag
00055 {};
00056 
00057 struct BinaryReduceFunctorTag
00058 : public InitializerTag, public BinaryAnalyserTag
00059 {};
00060 
00061 typedef UnaryFunctorTag UnaryExpandFunctorTag;
00062 typedef BinaryFunctorTag BinaryExpandFunctorTag;
00063 
00064 template <class T>
00065 class FunctorTraitsBase
00066 {
00067   public:
00068     typedef T type;
00069     
00070     typedef typename IsDerivedFrom<T, InitializerTag>::result isInitializer;
00071 
00072     typedef typename IsDerivedFrom<T, UnaryFunctorTag>::result isUnaryFunctor;
00073     typedef typename IsDerivedFrom<T, BinaryFunctorTag>::result isBinaryFunctor;
00074     typedef typename IsDerivedFrom<T, TernaryFunctorTag>::result isTernaryFunctor;
00075 
00076     typedef typename IsDerivedFrom<T, UnaryAnalyserTag>::result isUnaryAnalyser;
00077     typedef typename IsDerivedFrom<T, BinaryAnalyserTag>::result isBinaryAnalyser;
00078     typedef typename IsDerivedFrom<T, TernaryAnalyserTag>::result isTernaryAnalyser;
00079 };
00080 
00081 
00082 
00083 /** \addtogroup Functors
00084 */
00085 //@{
00086 /** \brief Export associated information for a functor.
00087 
00088     The FunctorTraits class contains the following fields:
00089 
00090     \code
00091     template <class T>
00092     struct FunctorTraits
00093     {
00094         typedef T type;
00095         
00096         typedef ... isInitializer;
00097 
00098         typedef ... isUnaryFunctor;
00099         typedef ... isBinaryFunctor;
00100         typedef ... isTernaryFunctor;
00101         
00102         typedef ... isUnaryAnalyser;
00103         typedef ... isBinaryAnalyser;
00104         typedef ... isTernaryAnalyser;
00105     };
00106     \endcode
00107 
00108     where the dots are either <tt>VigraTrueType</tt> or <tt>VigraFalseType</tt>
00109     depending on whether the functor supports the respective functionality or not.
00110     Note that these traits are automatically defined correctly when your functor is derived 
00111     from the appropriate functor tag classes: 
00112     
00113     \code
00114     struct InitializerTag {};
00115     struct UnaryFunctorTag {};
00116     struct BinaryFunctorTag {};
00117     struct TernaryFunctorTag {};
00118     struct UnaryAnalyserTag {};
00119     struct BinaryAnalyserTag {};
00120     struct TernaryAnalyserTag {};
00121     struct UnaryReduceFunctorTag : public InitializerTag, public UnaryAnalyserTag {};
00122     struct BinaryReduceFunctorTag : public InitializerTag, public BinaryAnalyserTag {};
00123     \endcode
00124     
00125     If a functor <tt>f</tt> is a model of these categories, it supports the following
00126     calls (<tt>v</tt> is a variable such that the result type of the functor
00127     calls can be converted into <tt>v</tt>'s type, and <tt>a1, a2, a3</tt> are
00128     variables convertible into the functor's argument types):
00129     
00130     <DL>
00131     <DT><b>Initializer</b>
00132         <DD> <tt>v = f()</tt> (used with initImageWithFunctor())
00133     <DT><b>UnaryFunctor</b>
00134         <DD> <tt>v = f(a1)</tt> (used with transformImage())
00135     <DT><b>BinaryFunctor</b>
00136         <DD> <tt>v = f(a1, a2)</tt> (used with combineTwoImages())
00137     <DT><b>TernaryFunctor</b>
00138         <DD> <tt>v = f(a1, a2, a3)</tt> (used with combineThreeImages())
00139     <DT><b>UnaryAnalyser</b>
00140         <DD> <tt>f(a1)</tt> (return type <tt>void</tt>, used with inspectImage())
00141     <DT><b>BinaryAnalyser</b>
00142         <DD> <tt>f(a1, a2)</tt> (return type <tt>void</tt>, used with inspectTwoImages())
00143     <DT><b>TernaryAnalyser</b>
00144         <DD> <tt>f(a1, a2, a3)</tt> (return type <tt>void</tt>)
00145     </DL>
00146     
00147     It should be noted that the functor's argument and result types are not contained
00148     in the traits class: Since the function calls are often member template functions in 
00149     VIGRA, many functors do not have fixed argument types. Neither are the result
00150     types fixed in this case because they are computed (via a template meta-program)
00151     from the argument types.
00152 
00153     <b>\#include</b> <vigra/functortraits.hxx>
00154     Namespace: vigra
00155 */
00156 template <class T>
00157 class FunctorTraits
00158 : public FunctorTraitsBase<T>
00159 {};
00160 
00161 #define VIGRA_DEFINE_STL_FUNCTOR(name, unary, binary) \
00162 template <class T> \
00163 class FunctorTraits<name<T> > \
00164 { \
00165   public: \
00166     typedef T type; \
00167      \
00168     typedef VigraFalseType isInitializer; \
00169      \
00170     typedef unary          isUnaryFunctor; \
00171     typedef binary         isBinaryFunctor; \
00172     typedef VigraFalseType isTernaryFunctor; \
00173      \
00174     typedef VigraFalseType isUnaryAnalyser; \
00175     typedef VigraFalseType isBinaryAnalyser; \
00176     typedef VigraFalseType isTernaryAnalyser; \
00177 };
00178 
00179 // ???TODO: these should also be specialized for the ptr_fun and mem_fun_ptr wrappers
00180 VIGRA_DEFINE_STL_FUNCTOR(std::plus, VigraFalseType, VigraTrueType)
00181 VIGRA_DEFINE_STL_FUNCTOR(std::minus, VigraFalseType, VigraTrueType)
00182 VIGRA_DEFINE_STL_FUNCTOR(std::multiplies, VigraFalseType, VigraTrueType)
00183 VIGRA_DEFINE_STL_FUNCTOR(std::divides, VigraFalseType, VigraTrueType)
00184 VIGRA_DEFINE_STL_FUNCTOR(std::modulus, VigraFalseType, VigraTrueType)
00185 VIGRA_DEFINE_STL_FUNCTOR(std::equal_to, VigraFalseType, VigraTrueType)
00186 VIGRA_DEFINE_STL_FUNCTOR(std::not_equal_to, VigraFalseType, VigraTrueType)
00187 VIGRA_DEFINE_STL_FUNCTOR(std::greater, VigraFalseType, VigraTrueType)
00188 VIGRA_DEFINE_STL_FUNCTOR(std::less, VigraFalseType, VigraTrueType)
00189 VIGRA_DEFINE_STL_FUNCTOR(std::greater_equal, VigraFalseType, VigraTrueType)
00190 VIGRA_DEFINE_STL_FUNCTOR(std::less_equal, VigraFalseType, VigraTrueType)
00191 VIGRA_DEFINE_STL_FUNCTOR(std::logical_and, VigraFalseType, VigraTrueType)
00192 VIGRA_DEFINE_STL_FUNCTOR(std::logical_or, VigraFalseType, VigraTrueType)
00193 VIGRA_DEFINE_STL_FUNCTOR(std::binary_negate, VigraFalseType, VigraTrueType)
00194 
00195 VIGRA_DEFINE_STL_FUNCTOR(std::negate, VigraTrueType, VigraFalseType)
00196 VIGRA_DEFINE_STL_FUNCTOR(std::logical_not, VigraTrueType, VigraFalseType)
00197 VIGRA_DEFINE_STL_FUNCTOR(std::unary_negate, VigraTrueType, VigraFalseType)
00198 VIGRA_DEFINE_STL_FUNCTOR(std::binder1st, VigraTrueType, VigraFalseType)
00199 VIGRA_DEFINE_STL_FUNCTOR(std::binder2nd, VigraTrueType, VigraFalseType)
00200 #undef VIGRA_DEFINE_STL_FUNCTOR
00201 
00202 template <class R>
00203 class FunctorTraits<R (*)()>
00204 {
00205   public:
00206     typedef R (*type)();
00207     
00208     typedef VigraTrueType  isInitializer;
00209     typedef VigraFalseType isUnaryFunctor;
00210     typedef VigraFalseType isBinaryFunctor;
00211     typedef VigraFalseType isTernaryFunctor;
00212     typedef VigraFalseType isUnaryAnalyser;
00213     typedef VigraFalseType isBinaryAnalyser;
00214     typedef VigraFalseType isTernaryAnalyser;
00215 };
00216 
00217 template <class R, class T>
00218 class FunctorTraits<R (*)(T)>
00219 {
00220   public:
00221     typedef R (*type)(T);
00222     
00223     typedef VigraFalseType isInitializer;
00224     typedef VigraTrueType  isUnaryFunctor;
00225     typedef VigraFalseType isBinaryFunctor;
00226     typedef VigraFalseType isTernaryFunctor;
00227     typedef VigraFalseType isUnaryAnalyser;
00228     typedef VigraFalseType isBinaryAnalyser;
00229     typedef VigraFalseType isTernaryAnalyser;
00230 };
00231 
00232 template <class R, class T1, class T2>
00233 class FunctorTraits<R (*)(T1, T2)>
00234 {
00235   public:
00236     typedef R (*type)(T1, T2);
00237     
00238     typedef VigraFalseType isInitializer;
00239     typedef VigraFalseType isUnaryFunctor;
00240     typedef VigraTrueType  isBinaryFunctor;
00241     typedef VigraFalseType isTernaryFunctor;
00242     typedef VigraFalseType isUnaryAnalyser;
00243     typedef VigraFalseType isBinaryAnalyser;
00244     typedef VigraFalseType isTernaryAnalyser;
00245 };
00246 
00247 template <class R, class T1, class T2, class T3>
00248 class FunctorTraits<R (*)(T1, T2, T3)>
00249 {
00250   public:
00251     typedef R (*type)(T1, T2, T3);
00252     
00253     typedef VigraFalseType isInitializer;
00254     typedef VigraFalseType isUnaryFunctor;
00255     typedef VigraFalseType isBinaryFunctor;
00256     typedef VigraTrueType  isTernaryFunctor;
00257     typedef VigraFalseType isUnaryAnalyser;
00258     typedef VigraFalseType isBinaryAnalyser;
00259     typedef VigraFalseType isTernaryAnalyser;
00260 };
00261 
00262 //@}
00263 
00264 } // namespace vigra
00265 
00266 #endif // VIGRA_FUNCTORTRAITS_HXX

© 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.9.0 (Tue Nov 6 2012)