Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:00

0001 //---------------------------------------------------------------------------//
0002 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // See http://boostorg.github.com/compute for more information.
0009 //---------------------------------------------------------------------------//
0010 
0011 #ifndef BOOST_COMPUTE_FUNCTIONAL_BIND_HPP
0012 #define BOOST_COMPUTE_FUNCTIONAL_BIND_HPP
0013 
0014 #include <boost/mpl/int.hpp>
0015 #include <boost/tuple/tuple.hpp>
0016 #include <boost/type_traits/conditional.hpp>
0017 
0018 #include <boost/compute/config.hpp>
0019 #include <boost/compute/detail/meta_kernel.hpp>
0020 
0021 namespace boost {
0022 namespace compute {
0023 namespace placeholders {
0024 
0025 /// \internal_
0026 template<int I>
0027 struct placeholder : boost::integral_constant<int, I>
0028 {
0029     placeholder() { }
0030 };
0031 
0032 placeholder<0> const _1;
0033 placeholder<1> const _2;
0034 
0035 } // end placeholders namespace
0036 
0037 /// Meta-function returning \c true if \c T is a placeholder type.
0038 template<class T>
0039 struct is_placeholder : boost::false_type
0040 {
0041 };
0042 
0043 /// \internal_
0044 template<int I>
0045 struct is_placeholder<placeholders::placeholder<I> > : boost::true_type
0046 {
0047 };
0048 
0049 namespace detail {
0050 
0051 template<class Function, class BoundArgs, class Args>
0052 struct invoked_bound_function
0053 {
0054     invoked_bound_function(Function f, BoundArgs bound_args, Args args)
0055         : m_function(f),
0056           m_bound_args(bound_args),
0057           m_args(args)
0058     {
0059     }
0060 
0061     // meta-function returning true if the N'th argument is a placeholder
0062     template<int N>
0063     struct is_placeholder_arg
0064     {
0065         typedef typename boost::tuples::element<N, BoundArgs>::type nth_bound_arg;
0066 
0067         typedef typename is_placeholder<nth_bound_arg>::type type;
0068         static const bool value = is_placeholder<nth_bound_arg>::value;
0069     };
0070 
0071     template<class Arg>
0072     struct get_arg_type
0073     {
0074         typedef Arg type;
0075     };
0076 
0077     template<int I>
0078     struct get_arg_type<placeholders::placeholder<I> >
0079     {
0080         typedef typename boost::tuples::element<I, Args>::type type;
0081     };
0082 
0083     // meta-function returning the type of the N'th argument when invoked
0084     template<int N>
0085     struct get_nth_arg_type
0086     {
0087         typedef typename boost::tuples::element<N, BoundArgs>::type nth_bound_arg;
0088 
0089         typedef typename get_arg_type<nth_bound_arg>::type type;
0090     };
0091 
0092     template<int N>
0093     typename get_nth_arg_type<N>::type get_nth_arg(
0094         typename boost::enable_if_c<is_placeholder_arg<N>::value>::type* = 0
0095     ) const
0096     {
0097         typedef typename boost::tuples::element<N, BoundArgs>::type nth_bound_arg;
0098 
0099         return boost::get<nth_bound_arg::value>(m_args);
0100     }
0101 
0102     template<int N>
0103     typename get_nth_arg_type<N>::type get_nth_arg(
0104         typename boost::disable_if_c<is_placeholder_arg<N>::value>::type* = 0
0105     ) const
0106     {
0107         return boost::get<N>(m_bound_args);
0108     }
0109 
0110     Function m_function;
0111     BoundArgs m_bound_args;
0112     Args m_args;
0113 };
0114 
0115 template<class Function, class BoundArgs, class Args>
0116 inline meta_kernel& apply_invoked_bound_function(
0117     meta_kernel &k,
0118     const invoked_bound_function<Function, BoundArgs, Args> &expr,
0119     typename boost::enable_if_c<
0120         boost::tuples::length<BoundArgs>::value == 1
0121     >::type* = 0
0122 )
0123 {
0124     return k << expr.m_function(expr.template get_nth_arg<0>());
0125 }
0126 
0127 template<class Function, class BoundArgs, class Args>
0128 inline meta_kernel& apply_invoked_bound_function(
0129     meta_kernel &k,
0130     const invoked_bound_function<Function, BoundArgs, Args> &expr,
0131     typename boost::enable_if_c<
0132         boost::tuples::length<BoundArgs>::value == 2
0133     >::type* = 0
0134 )
0135 {
0136     return k << expr.m_function(expr.template get_nth_arg<0>(),
0137                                 expr.template get_nth_arg<1>());
0138 }
0139 
0140 template<class Function, class BoundArgs, class Args>
0141 inline meta_kernel& apply_invoked_bound_function(
0142     meta_kernel &k,
0143     const invoked_bound_function<Function, BoundArgs, Args> &expr,
0144     typename boost::enable_if_c<
0145         boost::tuples::length<BoundArgs>::value == 3
0146     >::type* = 0
0147 )
0148 {
0149     return k << expr.m_function(expr.template get_nth_arg<0>(),
0150                                 expr.template get_nth_arg<1>(),
0151                                 expr.template get_nth_arg<2>());
0152 }
0153 
0154 template<class Function, class BoundArgs, class Args>
0155 inline meta_kernel& operator<<(
0156     meta_kernel &k,
0157     const invoked_bound_function<Function, BoundArgs, Args> &expr
0158 )
0159 {
0160     return apply_invoked_bound_function(k, expr);
0161 }
0162 
0163 template<class Function, class BoundArgs>
0164 struct bound_function
0165 {
0166     typedef int result_type;
0167 
0168     bound_function(Function f, BoundArgs args)
0169         : m_function(f),
0170           m_args(args)
0171     {
0172     }
0173 
0174     template<class Arg1>
0175     detail::invoked_bound_function<
0176         Function,
0177         BoundArgs,
0178         boost::tuple<Arg1>
0179     >
0180     operator()(const Arg1 &arg1) const
0181     {
0182         return detail::invoked_bound_function<
0183                    Function,
0184                    BoundArgs,
0185                    boost::tuple<Arg1>
0186                >(m_function, m_args, boost::make_tuple(arg1));
0187     }
0188 
0189     template<class Arg1, class Arg2>
0190     detail::invoked_bound_function<
0191         Function,
0192         BoundArgs,
0193         boost::tuple<Arg1, Arg2>
0194     >
0195     operator()(const Arg1 &arg1, const Arg2 &arg2) const
0196     {
0197         return detail::invoked_bound_function<
0198                    Function,
0199                    BoundArgs,
0200                    boost::tuple<Arg1, Arg2>
0201                >(m_function, m_args, boost::make_tuple(arg1, arg2));
0202     }
0203 
0204     Function m_function;
0205     BoundArgs m_args;
0206 };
0207 
0208 } // end detail namespace
0209 
0210 #if !defined(BOOST_COMPUTE_NO_VARIADIC_TEMPLATES) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
0211 /// Returns a function wrapper which invokes \p f with \p args when called.
0212 ///
0213 /// For example, to generate a unary function object which returns \c true
0214 /// when its argument is less than \c 7:
0215 /// \code
0216 /// using boost::compute::less;
0217 /// using boost::compute::placeholders::_1;
0218 ///
0219 /// auto less_than_seven = boost::compute::bind(less<int>(), _1, 7);
0220 /// \endcode
0221 template<class F, class... Args>
0222 inline detail::bound_function<F, boost::tuple<Args...> >
0223 bind(F f, Args... args)
0224 {
0225     typedef typename boost::tuple<Args...> ArgsTuple;
0226 
0227     return detail::bound_function<F, ArgsTuple>(f, boost::make_tuple(args...));
0228 }
0229 #else
0230 template<class F, class A1>
0231 inline detail::bound_function<F, boost::tuple<A1> >
0232 bind(F f, A1 a1)
0233 {
0234     typedef typename boost::tuple<A1> Args;
0235 
0236     return detail::bound_function<F, Args>(f, boost::make_tuple(a1));
0237 }
0238 
0239 template<class F, class A1, class A2>
0240 inline detail::bound_function<F, boost::tuple<A1, A2> >
0241 bind(F f, A1 a1, A2 a2)
0242 {
0243     typedef typename boost::tuple<A1, A2> Args;
0244 
0245     return detail::bound_function<F, Args>(f, boost::make_tuple(a1, a2));
0246 }
0247 
0248 template<class F, class A1, class A2, class A3>
0249 inline detail::bound_function<F, boost::tuple<A1, A2, A3> >
0250 bind(F f, A1 a1, A2 a2, A3 a3)
0251 {
0252     typedef typename boost::tuple<A1, A2, A3> Args;
0253 
0254     return detail::bound_function<F, Args>(f, boost::make_tuple(a1, a2, a3));
0255 }
0256 #endif // BOOST_COMPUTE_NO_VARIADIC_TEMPLATES
0257 
0258 } // end compute namespace
0259 } // end boost namespace
0260 
0261 #endif // BOOST_COMPUTE_FUNCTIONAL_BIND_HPP