Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:26:14

0001 // Copyright Jim Bosch 2010-2012.
0002 // Copyright Stefan Seefeld 2016.
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef boost_python_numpy_invoke_matching_hpp_
0008 #define boost_python_numpy_invoke_matching_hpp_
0009 
0010 /**
0011  *  @brief Template invocation based on dtype matching.
0012  */
0013 
0014 #include <boost/python/numpy/dtype.hpp>
0015 #include <boost/python/numpy/ndarray.hpp>
0016 #include <boost/mpl/integral_c.hpp>
0017 
0018 namespace boost { namespace python { namespace numpy {
0019 namespace detail 
0020 {
0021 
0022 struct BOOST_NUMPY_DECL add_pointer_meta
0023 {
0024   template <typename T>
0025   struct apply 
0026   {
0027     typedef typename boost::add_pointer<T>::type type;
0028   };
0029 
0030 };
0031 
0032 struct BOOST_NUMPY_DECL dtype_template_match_found {};
0033 struct BOOST_NUMPY_DECL nd_template_match_found {};
0034 
0035 template <typename Function>
0036 struct dtype_template_invoker 
0037 {
0038     
0039   template <typename T>
0040   void operator()(T *) const 
0041   {
0042     if (dtype::get_builtin<T>() == m_dtype) 
0043     {
0044       m_func.Function::template apply<T>();
0045       throw dtype_template_match_found();
0046     }
0047   }
0048 
0049   dtype_template_invoker(dtype const & dtype_, Function func) 
0050     : m_dtype(dtype_), m_func(func) {}
0051 
0052 private:
0053   dtype const & m_dtype;
0054   Function m_func;
0055 };
0056 
0057 template <typename Function>
0058 struct dtype_template_invoker< boost::reference_wrapper<Function> > 
0059 {
0060     
0061   template <typename T>
0062   void operator()(T *) const 
0063   {
0064     if (dtype::get_builtin<T>() == m_dtype) 
0065     {
0066       m_func.Function::template apply<T>();
0067       throw dtype_template_match_found();
0068     }
0069   }
0070 
0071   dtype_template_invoker(dtype const & dtype_, Function & func)
0072     : m_dtype(dtype_), m_func(func) {}
0073 
0074 private:
0075   dtype const & m_dtype;
0076   Function & m_func;
0077 };
0078 
0079 template <typename Function>
0080 struct nd_template_invoker 
0081 {    
0082   template <int N>
0083   void operator()(boost::mpl::integral_c<int,N> *) const 
0084   {
0085     if (m_nd == N) 
0086     {
0087       m_func.Function::template apply<N>();
0088       throw nd_template_match_found();
0089     }
0090   }
0091 
0092   nd_template_invoker(int nd, Function func) : m_nd(nd), m_func(func) {}
0093 
0094 private:
0095   int m_nd;
0096   Function m_func;
0097 };
0098 
0099 template <typename Function>
0100 struct nd_template_invoker< boost::reference_wrapper<Function> > 
0101 {    
0102   template <int N>
0103   void operator()(boost::mpl::integral_c<int,N> *) const 
0104   {
0105     if (m_nd == N) 
0106     {
0107       m_func.Function::template apply<N>();
0108       throw nd_template_match_found();
0109     }
0110   }
0111 
0112   nd_template_invoker(int nd, Function & func) : m_nd(nd), m_func(func) {}
0113 
0114 private:
0115   int m_nd;
0116   Function & m_func;
0117 };
0118 
0119 } // namespace boost::python::numpy::detail
0120 
0121 template <typename Sequence, typename Function>
0122 void invoke_matching_nd(int nd, Function f) 
0123 {
0124   detail::nd_template_invoker<Function> invoker(nd, f);
0125   try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
0126   catch (detail::nd_template_match_found &) { return;}
0127   PyErr_SetString(PyExc_TypeError, "number of dimensions not found in template list.");
0128   python::throw_error_already_set();
0129 }
0130 
0131 template <typename Sequence, typename Function>
0132 void invoke_matching_dtype(dtype const & dtype_, Function f) 
0133 {
0134   detail::dtype_template_invoker<Function> invoker(dtype_, f);
0135   try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
0136   catch (detail::dtype_template_match_found &) { return;}
0137   PyErr_SetString(PyExc_TypeError, "dtype not found in template list.");
0138   python::throw_error_already_set();
0139 }
0140 
0141 namespace detail 
0142 {
0143 
0144 template <typename T, typename Function>
0145 struct array_template_invoker_wrapper_2 
0146 {
0147   template <int N>
0148   void apply() const { m_func.Function::template apply<T,N>();}
0149   array_template_invoker_wrapper_2(Function & func) : m_func(func) {}
0150 
0151 private:
0152   Function & m_func;
0153 };
0154 
0155 template <typename DimSequence, typename Function>
0156 struct array_template_invoker_wrapper_1 
0157 {
0158   template <typename T>
0159   void apply() const { invoke_matching_nd<DimSequence>(m_nd, array_template_invoker_wrapper_2<T,Function>(m_func));}
0160   array_template_invoker_wrapper_1(int nd, Function & func) : m_nd(nd), m_func(func) {}
0161 
0162 private:
0163   int m_nd;
0164   Function & m_func;
0165 };
0166 
0167 template <typename DimSequence, typename Function>
0168 struct array_template_invoker_wrapper_1< DimSequence, boost::reference_wrapper<Function> >
0169   : public array_template_invoker_wrapper_1< DimSequence, Function >
0170 {
0171   array_template_invoker_wrapper_1(int nd, Function & func)
0172     : array_template_invoker_wrapper_1< DimSequence, Function >(nd, func) {}
0173 };
0174 
0175 } // namespace boost::python::numpy::detail
0176 
0177 template <typename TypeSequence, typename DimSequence, typename Function>
0178 void invoke_matching_array(ndarray const & array_, Function f) 
0179 {
0180   detail::array_template_invoker_wrapper_1<DimSequence,Function> wrapper(array_.get_nd(), f);
0181   invoke_matching_dtype<TypeSequence>(array_.get_dtype(), wrapper);
0182 }
0183 
0184 }}} // namespace boost::python::numpy
0185 
0186 #endif