py_function.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright David Abrahams 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef PY_FUNCTION_DWA200286_HPP
  6. # define PY_FUNCTION_DWA200286_HPP
  7. # include <boost/python/detail/signature.hpp>
  8. # include <boost/detail/workaround.hpp>
  9. # include <boost/mpl/size.hpp>
  10. # include <memory>
  11. namespace boost { namespace python { namespace objects {
  12. // This type is used as a "generalized Python callback", wrapping the
  13. // function signature:
  14. //
  15. // PyObject* (PyObject* args, PyObject* keywords)
  16. struct BOOST_PYTHON_DECL py_function_impl_base
  17. {
  18. virtual ~py_function_impl_base();
  19. virtual PyObject* operator()(PyObject*, PyObject*) = 0;
  20. virtual unsigned min_arity() const = 0;
  21. virtual unsigned max_arity() const;
  22. virtual python::detail::py_func_sig_info signature() const = 0;
  23. };
  24. template <class Caller>
  25. struct caller_py_function_impl : py_function_impl_base
  26. {
  27. caller_py_function_impl(Caller const& caller)
  28. : m_caller(caller)
  29. {}
  30. PyObject* operator()(PyObject* args, PyObject* kw)
  31. {
  32. return m_caller(args, kw);
  33. }
  34. virtual unsigned min_arity() const
  35. {
  36. return m_caller.min_arity();
  37. }
  38. virtual python::detail::py_func_sig_info signature() const
  39. {
  40. return m_caller.signature();
  41. }
  42. private:
  43. Caller m_caller;
  44. };
  45. template <class Caller, class Sig>
  46. struct signature_py_function_impl : py_function_impl_base
  47. {
  48. signature_py_function_impl(Caller const& caller)
  49. : m_caller(caller)
  50. {}
  51. PyObject* operator()(PyObject* args, PyObject* kw)
  52. {
  53. return m_caller(args, kw);
  54. }
  55. virtual unsigned min_arity() const
  56. {
  57. return mpl::size<Sig>::value - 1;
  58. }
  59. virtual python::detail::py_func_sig_info signature() const
  60. {
  61. python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
  62. python::detail::py_func_sig_info res = {sig, sig};
  63. return res;
  64. }
  65. private:
  66. Caller m_caller;
  67. };
  68. template <class Caller, class Sig>
  69. struct full_py_function_impl : py_function_impl_base
  70. {
  71. full_py_function_impl(Caller const& caller, unsigned min_arity, unsigned max_arity)
  72. : m_caller(caller)
  73. , m_min_arity(min_arity)
  74. , m_max_arity(max_arity > min_arity ? max_arity : min_arity)
  75. {}
  76. PyObject* operator()(PyObject* args, PyObject* kw)
  77. {
  78. return m_caller(args, kw);
  79. }
  80. virtual unsigned min_arity() const
  81. {
  82. return m_min_arity;
  83. }
  84. virtual unsigned max_arity() const
  85. {
  86. return m_max_arity;
  87. }
  88. virtual python::detail::py_func_sig_info signature() const
  89. {
  90. python::detail::signature_element const* sig = python::detail::signature<Sig>::elements();
  91. python::detail::py_func_sig_info res = {sig, sig};
  92. return res;
  93. }
  94. private:
  95. Caller m_caller;
  96. unsigned m_min_arity;
  97. unsigned m_max_arity;
  98. };
  99. struct py_function
  100. {
  101. template <class Caller>
  102. py_function(Caller const& caller)
  103. : m_impl(new caller_py_function_impl<Caller>(caller))
  104. {}
  105. template <class Caller, class Sig>
  106. py_function(Caller const& caller, Sig)
  107. : m_impl(new signature_py_function_impl<Caller, Sig>(caller))
  108. {}
  109. template <class Caller, class Sig>
  110. py_function(Caller const& caller, Sig, int min_arity, int max_arity = 0)
  111. : m_impl(new full_py_function_impl<Caller, Sig>(caller, min_arity, max_arity))
  112. {}
  113. py_function(py_function const& rhs)
  114. #if defined(BOOST_NO_CXX11_SMART_PTR)
  115. : m_impl(rhs.m_impl)
  116. #else
  117. : m_impl(std::move(rhs.m_impl))
  118. #endif
  119. {}
  120. PyObject* operator()(PyObject* args, PyObject* kw) const
  121. {
  122. return (*m_impl)(args, kw);
  123. }
  124. unsigned min_arity() const
  125. {
  126. return m_impl->min_arity();
  127. }
  128. unsigned max_arity() const
  129. {
  130. return m_impl->max_arity();
  131. }
  132. python::detail::signature_element const* signature() const
  133. {
  134. return m_impl->signature().signature;
  135. }
  136. python::detail::signature_element const& get_return_type() const
  137. {
  138. return *m_impl->signature().ret;
  139. }
  140. private:
  141. #if defined(BOOST_NO_CXX11_SMART_PTR)
  142. mutable std::auto_ptr<py_function_impl_base> m_impl;
  143. #else
  144. mutable std::unique_ptr<py_function_impl_base> m_impl;
  145. #endif
  146. };
  147. }}} // namespace boost::python::objects
  148. #endif // PY_FUNCTION_DWA200286_HPP