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

vigra/inspector_passes.hxx VIGRA

00001 #ifndef VIGRA_INSPECTOR_PASSES_HXX
00002 #define VIGRA_INSPECTOR_PASSES_HXX
00003 
00004 #include "metaprogramming.hxx"
00005 
00006 namespace vigra {
00007 
00008 // test and accomodate for functors that require extra passes over arrays / etc.
00009 
00010 namespace detail {
00011 
00012 template <bool>
00013 struct extra_passes_selector
00014 {
00015     template <class Inspector, class Functor>
00016     static void
00017     call(Inspector, Functor &) {}
00018 };
00019 template <>
00020 struct extra_passes_selector<true>
00021 {
00022     template <class Inspector, class Functor_n>
00023     static void
00024     call_n(Inspector g, Functor_n f_n)
00025     {
00026         g(f_n);
00027     }
00028     template <class Inspector, class Functor>
00029     static void
00030     call(Inspector g, Functor & f)
00031     {
00032         for (unsigned n = 2; n <= Functor::max_passes; ++n)
00033         {
00034             f.calc_sync();
00035             call_n(g, f.pass_n(n));
00036         }
00037     }
00038 };
00039 
00040 template <class T>
00041 struct has_extra_passes : public sfinae_test<T, has_extra_passes>
00042 {
00043     template <class U> has_extra_passes(U*, typename U::extra_passes* = 0);
00044 };
00045 
00046 template <class Functor, bool extra = has_extra_passes<Functor>::value>
00047 struct get_extra_passes
00048     : public VigraFalseType
00049 {
00050     void sync(Functor &) {}
00051 };
00052 
00053 template <class Functor>
00054 struct get_extra_passes<Functor, true>
00055 {
00056     typedef get_extra_passes extra_passes;
00057     static const unsigned max_passes = Functor::max_passes;
00058     static const bool value = Functor::max_passes >= 2;
00059 
00060     void sync(Functor & f)
00061     {
00062         f.calc_sync();
00063     }
00064 };
00065 
00066 template <class Inspector, class Functor>
00067 inline
00068 void
00069 extra_passes_select(Inspector g, Functor & f)
00070 {
00071     g(f);
00072     extra_passes_selector<get_extra_passes<Functor>::value>::call(g, f);
00073 }
00074 
00075 } // namespace detail
00076 
00077 } // namespace vigra
00078 
00079 #endif // VIGRA_INSPECTOR_PASSES_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)