apply_operation_base.hpp

Go 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  doxygen 1.5.6