signature.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright David Abrahams 2002, Joel de Guzman, 2002.
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #if !defined(BOOST_PP_IS_ITERATING)
  10. # ifndef SIGNATURE_JDG20020813_HPP
  11. # define SIGNATURE_JDG20020813_HPP
  12. # include <boost/python/detail/prefix.hpp>
  13. # include <boost/mpl/if.hpp>
  14. # include <boost/python/detail/preprocessor.hpp>
  15. # include <boost/python/detail/type_traits.hpp>
  16. # include <boost/preprocessor/repeat.hpp>
  17. # include <boost/preprocessor/enum.hpp>
  18. # include <boost/preprocessor/enum_params.hpp>
  19. # include <boost/preprocessor/empty.hpp>
  20. # include <boost/preprocessor/arithmetic/sub.hpp>
  21. # include <boost/preprocessor/iterate.hpp>
  22. # include <boost/python/detail/type_list.hpp>
  23. # include <boost/preprocessor/debug/line.hpp>
  24. # include <boost/preprocessor/arithmetic/sub.hpp>
  25. # include <boost/preprocessor/arithmetic/inc.hpp>
  26. # include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  27. # define BOOST_PYTHON_LIST_INC(n) \
  28. BOOST_PP_CAT(mpl::vector, BOOST_PP_INC(n))
  29. ///////////////////////////////////////////////////////////////////////////////
  30. namespace boost { namespace python { namespace detail {
  31. // A metafunction returning C1 if C1 is derived from C2, and C2
  32. // otherwise
  33. template <class C1, class C2>
  34. struct most_derived
  35. {
  36. typedef typename mpl::if_<
  37. detail::is_convertible<C1*,C2*>
  38. , C1
  39. , C2
  40. >::type type;
  41. };
  42. // The following macros generate expansions for::
  43. //
  44. // template <class RT, class T0... class TN>
  45. // inline mpl::vector<RT, T0...TN>
  46. // get_signature(RT(BOOST_PYTHON_FN_CC *)(T0...TN), void* = 0)
  47. // {
  48. // return mpl::list<RT, T0...TN>();
  49. // }
  50. //
  51. // where BOOST_PYTHON_FN_CC is a calling convention keyword, can be
  52. //
  53. // empty, for default calling convention
  54. // __cdecl (if BOOST_PYTHON_ENABLE_CDECL is defined)
  55. // __stdcall (if BOOST_PYTHON_ENABLE_STDCALL is defined)
  56. // __fastcall (if BOOST_PYTHON_ENABLE_FASTCALL is defined)
  57. //
  58. // And, for an appropriate assortment of cv-qualifications::
  59. //
  60. // template <class RT, class ClassT, class T0... class TN>
  61. // inline mpl::vector<RT, ClassT&, T0...TN>
  62. // get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv))
  63. // {
  64. // return mpl::list<RT, ClassT&, T0...TN>();
  65. // }
  66. //
  67. // template <class Target, class RT, class ClassT, class T0... class TN>
  68. // inline mpl::vector<
  69. // RT
  70. // , typename most_derived<Target, ClassT>::type&
  71. // , T0...TN
  72. // >
  73. // get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv), Target*)
  74. // {
  75. // return mpl::list<RT, ClassT&, T0...TN>();
  76. // }
  77. //
  78. // There are two forms for invoking get_signature::
  79. //
  80. // get_signature(f)
  81. //
  82. // and ::
  83. //
  84. // get_signature(f,(Target*)0)
  85. //
  86. // These functions extract the return type, class (for member
  87. // functions) and arguments of the input signature and stuff them in
  88. // an mpl type sequence (the calling convention is dropped).
  89. // Note that cv-qualification is dropped from
  90. // the "hidden this" argument of member functions; that is a
  91. // necessary sacrifice to ensure that an lvalue from_python converter
  92. // is used. A pointer is not used so that None will be rejected for
  93. // overload resolution.
  94. //
  95. // The second form of get_signature essentially downcasts the "hidden
  96. // this" argument of member functions to Target, because the function
  97. // may actually be a member of a base class which is not wrapped, and
  98. // in that case conversion from python would fail.
  99. //
  100. // @group {
  101. // 'default' calling convention
  102. # define BOOST_PYTHON_FN_CC
  103. # define BOOST_PP_ITERATION_PARAMS_1 \
  104. (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
  105. # include BOOST_PP_ITERATE()
  106. # undef BOOST_PYTHON_FN_CC
  107. // __cdecl calling convention
  108. # if defined(BOOST_PYTHON_ENABLE_CDECL)
  109. # define BOOST_PYTHON_FN_CC __cdecl
  110. # define BOOST_PYTHON_FN_CC_IS_CDECL
  111. # define BOOST_PP_ITERATION_PARAMS_1 \
  112. (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
  113. # include BOOST_PP_ITERATE()
  114. # undef BOOST_PYTHON_FN_CC
  115. # undef BOOST_PYTHON_FN_CC_IS_CDECL
  116. # endif // defined(BOOST_PYTHON_ENABLE_CDECL)
  117. // __stdcall calling convention
  118. # if defined(BOOST_PYTHON_ENABLE_STDCALL)
  119. # define BOOST_PYTHON_FN_CC __stdcall
  120. # define BOOST_PP_ITERATION_PARAMS_1 \
  121. (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
  122. # include BOOST_PP_ITERATE()
  123. # undef BOOST_PYTHON_FN_CC
  124. # endif // defined(BOOST_PYTHON_ENABLE_STDCALL)
  125. // __fastcall calling convention
  126. # if defined(BOOST_PYTHON_ENABLE_FASTCALL)
  127. # define BOOST_PYTHON_FN_CC __fastcall
  128. # define BOOST_PP_ITERATION_PARAMS_1 \
  129. (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
  130. # include BOOST_PP_ITERATE()
  131. # undef BOOST_PYTHON_FN_CC
  132. # endif // defined(BOOST_PYTHON_ENABLE_FASTCALL)
  133. # undef BOOST_PYTHON_LIST_INC
  134. // }
  135. }}} // namespace boost::python::detail
  136. # endif // SIGNATURE_JDG20020813_HPP
  137. // For gcc 4.4 compatability, we must include the
  138. // BOOST_PP_ITERATION_DEPTH test inside an #else clause.
  139. #else // BOOST_PP_IS_ITERATING
  140. #if BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
  141. # define N BOOST_PP_ITERATION()
  142. // as 'get_signature(RT(*)(T0...TN), void* = 0)' is the same
  143. // function as 'get_signature(RT(__cdecl *)(T0...TN), void* = 0)',
  144. // we don't define it twice
  145. # if !defined(BOOST_PYTHON_FN_CC_IS_CDECL)
  146. template <
  147. class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
  148. inline BOOST_PYTHON_LIST_INC(N)<
  149. RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
  150. get_signature(RT(BOOST_PYTHON_FN_CC *)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0)
  151. {
  152. return BOOST_PYTHON_LIST_INC(N)<
  153. RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
  154. >();
  155. }
  156. # endif // !defined(BOOST_PYTHON_FN_CC_IS_CDECL)
  157. # undef N
  158. # define BOOST_PP_ITERATION_PARAMS_2 \
  159. (3, (0, 3, <boost/python/signature.hpp>))
  160. # include BOOST_PP_ITERATE()
  161. #else
  162. # define N BOOST_PP_RELATIVE_ITERATION(1)
  163. # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_ITERATION())
  164. template <
  165. class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
  166. inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
  167. RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
  168. get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q)
  169. {
  170. return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
  171. RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
  172. >();
  173. }
  174. template <
  175. class Target
  176. , class RT
  177. , class ClassT
  178. BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)
  179. >
  180. inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
  181. RT
  182. , typename most_derived<Target, ClassT>::type&
  183. BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
  184. >
  185. get_signature(
  186. RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q
  187. , Target*
  188. )
  189. {
  190. return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
  191. RT
  192. , BOOST_DEDUCED_TYPENAME most_derived<Target, ClassT>::type&
  193. BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
  194. >();
  195. }
  196. # undef Q
  197. # undef N
  198. #endif // BOOST_PP_ITERATION_DEPTH()
  199. #endif // !defined(BOOST_PP_IS_ITERATING)