File indexing completed on 2025-01-18 09:50:39
0001
0002
0003
0004
0005 #ifndef PY_FUNCTION_DWA200286_HPP
0006 # define PY_FUNCTION_DWA200286_HPP
0007
0008 # include <boost/python/detail/signature.hpp>
0009 # include <boost/detail/workaround.hpp>
0010 # include <boost/mpl/size.hpp>
0011 # include <memory>
0012
0013 namespace boost { namespace python { namespace objects {
0014
0015
0016
0017
0018
0019
0020 struct BOOST_PYTHON_DECL py_function_impl_base
0021 {
0022 virtual ~py_function_impl_base();
0023 virtual PyObject* operator()(PyObject*, PyObject*) = 0;
0024 virtual unsigned min_arity() const = 0;
0025 virtual unsigned max_arity() const;
0026 virtual python::detail::py_func_sig_info signature() const = 0;
0027 };
0028
0029 template <class Caller>
0030 struct caller_py_function_impl : py_function_impl_base
0031 {
0032 caller_py_function_impl(Caller const& caller)
0033 : m_caller(caller)
0034 {}
0035
0036 PyObject* operator()(PyObject* args, PyObject* kw)
0037 {
0038 return m_caller(args, kw);
0039 }
0040
0041 virtual unsigned min_arity() const
0042 {
0043 return m_caller.min_arity();
0044 }
0045
0046 virtual python::detail::py_func_sig_info signature() const
0047 {
0048 return m_caller.signature();
0049 }
0050
0051 private:
0052 Caller m_caller;
0053 };
0054
0055 template <class Caller, class Sig>
0056 struct signature_py_function_impl : py_function_impl_base
0057 {
0058 signature_py_function_impl(Caller const& caller)
0059 : m_caller(caller)
0060 {}
0061
0062 PyObject* operator()(PyObject* args, PyObject* kw)
0063 {
0064 return m_caller(args, kw);
0065 }
0066
0067 virtual unsigned min_arity() const
0068 {
0069 return mpl::size<Sig>::value - 1;
0070 }
0071
0072 virtual python::detail::py_func_sig_info signature() const
0073 {
0074 python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
0075 python::detail::py_func_sig_info res = {sig, sig};
0076 return res;
0077 }
0078
0079 private:
0080 Caller m_caller;
0081 };
0082
0083 template <class Caller, class Sig>
0084 struct full_py_function_impl : py_function_impl_base
0085 {
0086 full_py_function_impl(Caller const& caller, unsigned min_arity, unsigned max_arity)
0087 : m_caller(caller)
0088 , m_min_arity(min_arity)
0089 , m_max_arity(max_arity > min_arity ? max_arity : min_arity)
0090 {}
0091
0092 PyObject* operator()(PyObject* args, PyObject* kw)
0093 {
0094 return m_caller(args, kw);
0095 }
0096
0097 virtual unsigned min_arity() const
0098 {
0099 return m_min_arity;
0100 }
0101
0102 virtual unsigned max_arity() const
0103 {
0104 return m_max_arity;
0105 }
0106
0107 virtual python::detail::py_func_sig_info signature() const
0108 {
0109 python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
0110 python::detail::py_func_sig_info res = {sig, sig};
0111 return res;
0112 }
0113
0114 private:
0115 Caller m_caller;
0116 unsigned m_min_arity;
0117 unsigned m_max_arity;
0118 };
0119
0120 struct py_function
0121 {
0122 template <class Caller>
0123 py_function(Caller const& caller)
0124 : m_impl(new caller_py_function_impl<Caller>(caller))
0125 {}
0126
0127 template <class Caller, class Sig>
0128 py_function(Caller const& caller, Sig)
0129 : m_impl(new signature_py_function_impl<Caller, Sig>(caller))
0130 {}
0131
0132 template <class Caller, class Sig>
0133 py_function(Caller const& caller, Sig, int min_arity, int max_arity = 0)
0134 : m_impl(new full_py_function_impl<Caller, Sig>(caller, min_arity, max_arity))
0135 {}
0136
0137 py_function(py_function const& rhs)
0138 #if defined(BOOST_NO_CXX11_SMART_PTR)
0139 : m_impl(rhs.m_impl)
0140 #else
0141 : m_impl(std::move(rhs.m_impl))
0142 #endif
0143 {}
0144
0145 PyObject* operator()(PyObject* args, PyObject* kw) const
0146 {
0147 return (*m_impl)(args, kw);
0148 }
0149
0150 unsigned min_arity() const
0151 {
0152 return m_impl->min_arity();
0153 }
0154
0155 unsigned max_arity() const
0156 {
0157 return m_impl->max_arity();
0158 }
0159
0160 python::detail::signature_element const* signature() const
0161 {
0162 return m_impl->signature().signature;
0163 }
0164
0165 python::detail::signature_element const& get_return_type() const
0166 {
0167 return *m_impl->signature().ret;
0168 }
0169
0170 private:
0171 #if defined(BOOST_NO_CXX11_SMART_PTR)
0172 mutable std::auto_ptr<py_function_impl_base> m_impl;
0173 #else
0174 mutable std::unique_ptr<py_function_impl_base> m_impl;
0175 #endif
0176 };
0177
0178 }}}
0179
0180 #endif