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

vigra/functortraits.hxx |

    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)