apply_operation_base.hppGo to the documentation of this file.00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 00004 Use, modification and distribution are subject to the Boost Software License, 00005 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 00006 http://www.boost.org/LICENSE_1_0.txt). 00007 00008 See http://opensource.adobe.com/gil for most recent version including documentation. 00009 */ 00010 00011 /*************************************************************************************************/ 00012 00013 #ifndef GIL_APPLY_OPERATION_BASE_HPP 00014 #define GIL_APPLY_OPERATION_BASE_HPP 00015 00016 #include "../../gil_config.hpp" 00017 #include "../../utilities.hpp" 00018 #include <boost/mpl/begin.hpp> 00019 #include <boost/mpl/next.hpp> 00020 #include <boost/mpl/deref.hpp> 00021 #include <boost/mpl/size.hpp> 00022 #include <boost/preprocessor/repeat.hpp> 00023 00033 00034 namespace boost { namespace gil { 00035 00036 /* 00037 GENERATE_APPLY_FWD_OPS generates for every N functions that look like this (for N==2): 00038 00039 template <> struct apply_operation_fwd_fn<3> { 00040 template <typename Types, typename Bits, typename UnaryOp> 00041 typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { 00042 typedef typename mpl::begin<Types>::type T0; 00043 typedef typename mpl::next<T0>::type T1; 00044 typedef typename mpl::next<T1>::type T2; 00045 switch (index) { 00046 case 0: return op(reinterpret_cast<typename mpl::deref<T0>::type&>(bits)); 00047 case 1: return op(reinterpret_cast<typename mpl::deref<T1>::type&>(bits)); 00048 case 2: return op(reinterpret_cast<typename mpl::deref<T2>::type&>(bits)); 00049 } 00050 throw; 00051 } 00052 00053 template <typename Types, typename Bits, typename UnaryOp> 00054 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { 00055 typedef typename mpl::begin<Types>::type T0; 00056 typedef typename mpl::next<T0>::type T1; 00057 typedef typename mpl::next<T1>::type T2; 00058 switch (index) { 00059 case 0: return op(reinterpret_cast<const typename mpl::deref<T0>::type&>(bits)); 00060 case 1: return op(reinterpret_cast<const typename mpl::deref<T1>::type&>(bits)); 00061 case 2: return op(reinterpret_cast<const typename mpl::deref<T2>::type&>(bits)); 00062 } 00063 throw; 00064 } 00065 }; 00066 */ 00067 00068 #define GIL_FWD_TYPEDEFS(z, N, text) T##N; typedef typename mpl::next<T##N>::type 00069 #define GIL_FWD_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast<typename mpl::deref<T##N>::type*>(&bits)); 00070 #define GIL_FWD_CONST_CASE(z, N, SUM) case N: return op(*gil_reinterpret_cast_c<const typename mpl::deref<T##N>::type*>(&bits)); 00071 00072 #define GIL_APPLY_FWD_OP(z, N, text) \ 00073 template <> struct apply_operation_fwd_fn<BOOST_PP_ADD(N,1)> { \ 00074 template <typename Types, typename Bits, typename UnaryOp> \ 00075 typename UnaryOp::result_type apply(Bits& bits, std::size_t index, UnaryOp op) const { \ 00076 typedef typename mpl::begin<Types>::type \ 00077 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \ 00078 T##N; \ 00079 switch (index) { \ 00080 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CASE, BOOST_PP_EMPTY) \ 00081 } \ 00082 throw; \ 00083 } \ 00084 template <typename Types, typename Bits, typename UnaryOp> \ 00085 typename UnaryOp::result_type applyc(const Bits& bits, std::size_t index, UnaryOp op) const { \ 00086 typedef typename mpl::begin<Types>::type \ 00087 BOOST_PP_REPEAT(N, GIL_FWD_TYPEDEFS, BOOST_PP_EMPTY) \ 00088 T##N; \ 00089 switch (index) { \ 00090 BOOST_PP_REPEAT(BOOST_PP_ADD(N,1), GIL_FWD_CONST_CASE,BOOST_PP_EMPTY) \ 00091 } \ 00092 throw; \ 00093 } \ 00094 }; 00095 00096 #define GIL_GENERATE_APPLY_FWD_OPS(N) BOOST_PP_REPEAT(N, GIL_APPLY_FWD_OP, BOOST_PP_EMPTY) 00097 00098 namespace detail { 00099 template <std::size_t N> struct apply_operation_fwd_fn {}; 00100 00101 // Create specializations of apply_operation_fn for each N 0..100 00102 GIL_GENERATE_APPLY_FWD_OPS(99) 00103 } // namespace detail 00104 00105 // unary application 00106 template <typename Types, typename Bits, typename Op> 00107 typename Op::result_type GIL_FORCEINLINE apply_operation_basec(const Bits& bits, std::size_t index, Op op) { 00108 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template applyc<Types>(bits,index,op); 00109 } 00110 00111 // unary application 00112 template <typename Types, typename Bits, typename Op> 00113 typename Op::result_type GIL_FORCEINLINE apply_operation_base( Bits& bits, std::size_t index, Op op) { 00114 return detail::apply_operation_fwd_fn<mpl::size<Types>::value>().template apply<Types>(bits,index,op); 00115 } 00116 00117 namespace detail { 00118 template <typename T2, typename Op> 00119 struct reduce_bind1 { 00120 const T2& _t2; 00121 mutable Op& _op; 00122 00123 typedef typename Op::result_type result_type; 00124 00125 reduce_bind1(const T2& t2, Op& op) : _t2(t2), _op(op) {} 00126 00127 template <typename T1> GIL_FORCEINLINE result_type operator()(const T1& t1) { return _op(t1, _t2); } 00128 }; 00129 00130 template <typename Types1, typename Bits1, typename Op> 00131 struct reduce_bind2 { 00132 const Bits1& _bits1; 00133 std::size_t _index1; 00134 mutable Op& _op; 00135 00136 typedef typename Op::result_type result_type; 00137 00138 reduce_bind2(const Bits1& bits1, std::size_t index1, Op& op) : _bits1(bits1), _index1(index1), _op(op) {} 00139 00140 template <typename T2> GIL_FORCEINLINE result_type operator()(const T2& t2) { 00141 return apply_operation_basec<Types1>(_bits1, _index1, reduce_bind1<T2,Op>(t2, _op)); 00142 } 00143 }; 00144 } // namespace detail 00145 00146 // Binary application by applying on each dimension separately 00147 template <typename Types1, typename Types2, typename Bits1, typename Bits2, typename Op> 00148 static typename Op::result_type GIL_FORCEINLINE apply_operation_base(const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) { 00149 return apply_operation_basec<Types2>(bits2,index2,detail::reduce_bind2<Types1,Bits1,Op>(bits1,index1,op)); 00150 } 00151 00152 #undef GIL_FWD_TYPEDEFS 00153 #undef GIL_FWD_CASE 00154 #undef GIL_FWD_CONST_CASE 00155 #undef GIL_APPLY_FWD_OP 00156 #undef GIL_GENERATE_APPLY_FWD_OPS 00157 #undef BHS 00158 00159 } } // namespace boost::gil 00160 00161 00162 #endif Generated on Sat May 2 13:50:13 2009 for Generic Image Library by 1.5.6 |