invoke_matching.hpp
Go to the documentation of this file.
00001 // Copyright Jim Bosch 2010-2012.
00002 // Distributed under the Boost Software License, Version 1.0.
00003 //    (See accompanying file LICENSE_1_0.txt or copy at
00004 //          http://www.boost.org/LICENSE_1_0.txt)
00005 #ifndef BOOST_NUMPY_INVOKE_MATCHING_HPP_INCLUDED
00006 #define BOOST_NUMPY_INVOKE_MATCHING_HPP_INCLUDED
00007 
00013 #include <boost/numpy/dtype.hpp>
00014 #include <boost/numpy/ndarray.hpp>
00015 
00016 #include <boost/mpl/integral_c.hpp>
00017 
00018 namespace boost 
00019 {
00020 namespace numpy 
00021 {
00022 namespace detail 
00023 {
00024 
00025 struct add_pointer_meta 
00026 {
00027   template <typename T>
00028   struct apply 
00029   {
00030     typedef typename boost::add_pointer<T>::type type;
00031   };
00032 
00033 };
00034 
00035 struct dtype_template_match_found {};
00036 struct nd_template_match_found {};
00037 
00038 template <typename Function>
00039 struct dtype_template_invoker 
00040 {
00041     
00042   template <typename T>
00043   void operator()(T *) const 
00044   {
00045     if (dtype::get_builtin<T>() == m_dtype) 
00046     {
00047       m_func.Function::template apply<T>();
00048       throw dtype_template_match_found();
00049     }
00050   }
00051 
00052   dtype_template_invoker(dtype const & dtype_, Function func) 
00053     : m_dtype(dtype_), m_func(func) {}
00054 
00055 private:
00056   dtype const & m_dtype;
00057   Function m_func;
00058 };
00059 
00060 template <typename Function>
00061 struct dtype_template_invoker< boost::reference_wrapper<Function> > 
00062 {
00063     
00064   template <typename T>
00065   void operator()(T *) const 
00066   {
00067     if (dtype::get_builtin<T>() == m_dtype) 
00068     {
00069       m_func.Function::template apply<T>();
00070       throw dtype_template_match_found();
00071     }
00072   }
00073 
00074   dtype_template_invoker(dtype const & dtype_, Function & func)
00075     : m_dtype(dtype_), m_func(func) {}
00076 
00077 private:
00078   dtype const & m_dtype;
00079   Function & m_func;
00080 };
00081 
00082 template <typename Function>
00083 struct nd_template_invoker 
00084 {    
00085   template <int N>
00086   void operator()(boost::mpl::integral_c<int,N> *) const 
00087   {
00088     if (m_nd == N) 
00089     {
00090       m_func.Function::template apply<N>();
00091       throw nd_template_match_found();
00092     }
00093   }
00094 
00095   nd_template_invoker(int nd, Function func) : m_nd(nd), m_func(func) {}
00096 
00097 private:
00098   int m_nd;
00099   Function m_func;
00100 };
00101 
00102 template <typename Function>
00103 struct nd_template_invoker< boost::reference_wrapper<Function> > 
00104 {    
00105   template <int N>
00106   void operator()(boost::mpl::integral_c<int,N> *) const 
00107   {
00108     if (m_nd == N) 
00109     {
00110       m_func.Function::template apply<N>();
00111       throw nd_template_match_found();
00112     }
00113   }
00114 
00115   nd_template_invoker(int nd, Function & func) : m_nd(nd), m_func(func) {}
00116 
00117 private:
00118   int m_nd;
00119   Function & m_func;
00120 };
00121 
00122 } // namespace boost::numpy::detail
00123 
00124 template <typename Sequence, typename Function>
00125 void invoke_matching_nd(int nd, Function f) 
00126 {
00127   detail::nd_template_invoker<Function> invoker(nd, f);
00128   try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
00129   catch (detail::nd_template_match_found &) { return;}
00130   PyErr_SetString(PyExc_TypeError, "number of dimensions not found in template list.");
00131   python::throw_error_already_set();
00132 }
00133 
00134 template <typename Sequence, typename Function>
00135 void invoke_matching_dtype(dtype const & dtype_, Function f) 
00136 {
00137   detail::dtype_template_invoker<Function> invoker(dtype_, f);
00138   try { boost::mpl::for_each< Sequence, detail::add_pointer_meta >(invoker);}
00139   catch (detail::dtype_template_match_found &) { return;}
00140   PyErr_SetString(PyExc_TypeError, "dtype not found in template list.");
00141   python::throw_error_already_set();
00142 }
00143 
00144 namespace detail 
00145 {
00146 
00147 template <typename T, typename Function>
00148 struct array_template_invoker_wrapper_2 
00149 {
00150   template <int N>
00151   void apply() const { m_func.Function::template apply<T,N>();}
00152   array_template_invoker_wrapper_2(Function & func) : m_func(func) {}
00153 
00154 private:
00155   Function & m_func;
00156 };
00157 
00158 template <typename DimSequence, typename Function>
00159 struct array_template_invoker_wrapper_1 
00160 {
00161   template <typename T>
00162   void apply() const { invoke_matching_nd<DimSequence>(m_nd, array_template_invoker_wrapper_2<T,Function>(m_func));}
00163   array_template_invoker_wrapper_1(int nd, Function & func) : m_nd(nd), m_func(func) {}
00164 
00165 private:
00166   int m_nd;
00167   Function & m_func;
00168 };
00169 
00170 template <typename DimSequence, typename Function>
00171 struct array_template_invoker_wrapper_1< DimSequence, boost::reference_wrapper<Function> >
00172   : public array_template_invoker_wrapper_1< DimSequence, Function >
00173 {
00174   array_template_invoker_wrapper_1(int nd, Function & func)
00175     : array_template_invoker_wrapper_1< DimSequence, Function >(nd, func) {}
00176 };
00177 
00178 } // namespace boost::numpy::detail
00179 
00180 template <typename TypeSequence, typename DimSequence, typename Function>
00181 void invoke_matching_array(ndarray const & array_, Function f) 
00182 {
00183   detail::array_template_invoker_wrapper_1<DimSequence,Function> wrapper(array_.get_nd(), f);
00184   invoke_matching_dtype<TypeSequence>(array_.get_dtype(), wrapper);
00185 }
00186 
00187 } // namespace boost::numpy
00188 } // namespace boost
00189 
00190 #endif // !BOOST_NUMPY_INVOKE_MATCHING_HPP_INCLUDED


boost_numpy
Author(s): Jim Bosch, Ankit Daftery
autogenerated on Fri Aug 28 2015 10:10:40