TuttleOFX  1
static_channel_recursion.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_ALGORITHM_STATIC_CHANNEL_RECURSION_HPP_
00002 #define _TERRY_ALGORITHM_STATIC_CHANNEL_RECURSION_HPP_
00003 
00004 #include <boost/type_traits.hpp>
00005 #include <boost/utility/enable_if.hpp>
00006 #include <boost/mpl/contains.hpp>
00007 #include <boost/mpl/at.hpp>
00008 
00009 #include <boost/gil/gil_config.hpp>
00010 #include <boost/gil/gil_concept.hpp>
00011 #include <boost/gil/utilities.hpp>
00012 
00013 #include <algorithm>
00014 
00015 namespace terry {
00016 using namespace boost::gil;
00017 namespace algorithm {
00018 
00019 namespace ext_detail {
00020 
00021 // compile-time recursion for per-element operations on color bases
00022 template <int N>
00023 struct element_recursion
00024 {
00025     //static_for_each with four sources
00026     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00027     static Op static_for_each(P1& p1, P2& p2, P3& p3, const P4& p4, Op op) {
00028         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00029         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00030         return op2;
00031     }
00032     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00033     static Op static_for_each(P1& p1, P2& p2, const P3& p3, const P4& p4, Op op) {
00034         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00035         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00036         return op2;
00037     }
00038     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00039     static Op static_for_each(P1& p1, const P2& p2, P3& p3, const P4& p4, Op op) {
00040         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00041         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00042         return op2;
00043     }
00044     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00045     static Op static_for_each(P1& p1, const P2& p2, const P3& p3, const P4& p4, Op op) {
00046         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00047         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00048         return op2;
00049     }
00050     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00051     static Op static_for_each(const P1& p1, P2& p2, P3& p3, const P4& p4, Op op) {
00052         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00053         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00054         return op2;
00055     }
00056     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00057     static Op static_for_each(const P1& p1, P2& p2, const P3& p3, const P4& p4, Op op) {
00058         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00059         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00060         return op2;
00061     }
00062     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00063     static Op static_for_each(const P1& p1, const P2& p2, P3& p3, const P4& p4, Op op) {
00064         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00065         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00066         return op2;
00067     }
00068     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00069     static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, const P4& p4, Op op) {
00070         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00071         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00072         return op2;
00073     }
00074 
00075     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00076     static Op static_for_each(P1& p1, P2& p2, P3& p3, P4& p4, Op op) {
00077         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00078         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00079         return op2;
00080     }
00081     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00082     static Op static_for_each(P1& p1, P2& p2, const P3& p3, P4& p4, Op op) {
00083         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00084         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00085         return op2;
00086     }
00087     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00088     static Op static_for_each(P1& p1, const P2& p2, P3& p3, P4& p4, Op op) {
00089         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00090         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00091         return op2;
00092     }
00093     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00094     static Op static_for_each(P1& p1, const P2& p2, const P3& p3, P4& p4, Op op) {
00095         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00096         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00097         return op2;
00098     }
00099     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00100     static Op static_for_each(const P1& p1, P2& p2, P3& p3, P4& p4, Op op) {
00101         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00102         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00103         return op2;
00104     }
00105     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00106     static Op static_for_each(const P1& p1, P2& p2, const P3& p3, P4& p4, Op op) {
00107         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00108         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00109         return op2;
00110     }
00111     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00112     static Op static_for_each(const P1& p1, const P2& p2, P3& p3, P4& p4, Op op) {
00113         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00114         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00115         return op2;
00116     }
00117     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00118     static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, P4& p4, Op op) {
00119         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op));
00120         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4));
00121         return op2;
00122     }
00123 
00124 //    //static_transform with two sources
00125 //    template <typename P1,typename P2,typename Dst,typename Op>
00126 //    static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
00127 //        Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
00128 //        semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
00129 //        return op2;
00130 //    }
00131 //    template <typename P1,typename P2,typename Dst,typename Op>
00132 //    static Op static_transform(P1& src1, const P2& src2, Dst& dst, Op op) {
00133 //        Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
00134 //        semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
00135 //        return op2;
00136 //    }
00137 //    template <typename P1,typename P2,typename Dst,typename Op>
00138 //    static Op static_transform(const P1& src1, P2& src2, Dst& dst, Op op) {
00139 //        Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
00140 //        semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
00141 //        return op2;
00142 //    }
00143 //    template <typename P1,typename P2,typename Dst,typename Op>
00144 //    static Op static_transform(const P1& src1, const P2& src2, Dst& dst, Op op) {
00145 //        Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
00146 //        semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
00147 //        return op2;
00148 //    }
00149 };
00150 
00151 // Termination condition of the compile-time recursion for element operations on a color base
00152 template<> struct element_recursion<0>
00153 {
00154         //static_for_each with four sources
00155     template <typename P1,typename P2,typename P3,typename P4,typename Op>
00156     static Op static_for_each(const P1&,const P2&,const P3&,const P4&,Op op){return op;}
00157 
00158     //static_transform with three sources
00159     template <typename P1,typename P2,typename P3,typename Dst,typename Op>
00160     static Op static_transform(const P1&,const P2&,const P3&,const Dst&,Op op){return op;}
00161 };
00162 
00163 }
00164 
00165 
00166 /**
00167 \defgroup ColorBaseAlgorithmTransform static_transform
00168 \ingroup ColorBaseAlgorithm
00169 \brief Equivalent to std::transform. Pairs the elements semantically
00170 */
00171 
00172 /// \{
00173 ////static_transform with three sources
00174 //template <typename P2,typename P3,typename Dst,typename Op>
00175 //GIL_FORCEINLINE
00176 //Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
00177 //template <typename P2,typename P3,typename Dst,typename Op>
00178 //GIL_FORCEINLINE
00179 //Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
00180 //template <typename P2,typename P3,typename Dst,typename Op>
00181 //GIL_FORCEINLINE
00182 //Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
00183 //template <typename P2,typename P3,typename Dst,typename Op>
00184 //GIL_FORCEINLINE
00185 //Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
00186 /// \}
00187 
00188 /**
00189 \defgroup ColorBaseAlgorithmForEach static_for_each
00190 \ingroup ColorBaseAlgorithm
00191 \brief Equivalent to std::for_each. Pairs the elements semantically
00192 */
00193 
00194 ///\{
00195 //static_for_each with four sources
00196 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00197 GIL_FORCEINLINE
00198 Op static_for_each(P1& p1,P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00199 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00200 GIL_FORCEINLINE
00201 Op static_for_each(P1& p1,P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00202 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00203 GIL_FORCEINLINE
00204 Op static_for_each(P1& p1,const P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00205 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00206 GIL_FORCEINLINE
00207 Op static_for_each(P1& p1,const P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00208 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00209 GIL_FORCEINLINE
00210 Op static_for_each(const P1& p1,P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00211 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00212 GIL_FORCEINLINE
00213 Op static_for_each(const P1& p1,P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00214 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00215 GIL_FORCEINLINE
00216 Op static_for_each(const P1& p1,const P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00217 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00218 GIL_FORCEINLINE
00219 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00220 
00221 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00222 GIL_FORCEINLINE
00223 Op static_for_each(P1& p1,P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00224 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00225 GIL_FORCEINLINE
00226 Op static_for_each(P1& p1,P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00227 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00228 GIL_FORCEINLINE
00229 Op static_for_each(P1& p1,const P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00230 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00231 GIL_FORCEINLINE
00232 Op static_for_each(P1& p1,const P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00233 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00234 GIL_FORCEINLINE
00235 Op static_for_each(const P1& p1,P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00236 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00237 GIL_FORCEINLINE
00238 Op static_for_each(const P1& p1,P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00239 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00240 GIL_FORCEINLINE
00241 Op static_for_each(const P1& p1,const P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00242 template <typename P1,typename P2,typename P3,typename P4,typename Op>
00243 GIL_FORCEINLINE
00244 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); }
00245 ///\}
00246 
00247 }
00248 }
00249 
00250 
00251 #endif