1 // Copyright David Abrahams 2001.
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 MAKE_FUNCTION_DWA20011221_HPP
6 # define MAKE_FUNCTION_DWA20011221_HPP
7 
8 # include <boost/python/detail/prefix.hpp>
9 
10 # include <boost/python/default_call_policies.hpp>
11 # include <boost/python/args.hpp>
12 # include <boost/python/detail/caller.hpp>
13 
14 # include <boost/python/object/function_object.hpp>
15 
16 # include <boost/mpl/size.hpp>
17 # include <boost/mpl/int.hpp>
18 
19 namespace boost { namespace python {
20 
21 namespace detail
22 {
23   // make_function_aux --
24   //
25   // These helper functions for make_function (below) do the raw work
26   // of constructing a Python object from some invokable entity. See
27   // <boost/python/detail/caller.hpp> for more information about how
28   // the Sig arguments is used.
29   template <class F, class CallPolicies, class Sig>
make_function_aux(F f,CallPolicies const & p,Sig const &)30   object make_function_aux(
31       F f                               // An object that can be invoked by detail::invoke()
32       , CallPolicies const& p           // CallPolicies to use in the invocation
33       , Sig const&                      // An MPL sequence of argument types expected by F
34       )
35   {
36       return objects::function_object(
37           detail::caller<F,CallPolicies,Sig>(f, p)
38       );
39   }
40 
41   // As above, except that it accepts argument keywords. NumKeywords
42   // is used only for a compile-time assertion to make sure the user
43   // doesn't pass more keywords than the function can accept. To
44   // disable all checking, pass mpl::int_<0> for NumKeywords.
45   template <class F, class CallPolicies, class Sig, class NumKeywords>
make_function_aux(F f,CallPolicies const & p,Sig const &,detail::keyword_range const & kw,NumKeywords)46   object make_function_aux(
47       F f
48       , CallPolicies const& p
49       , Sig const&
50       , detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names
51       , NumKeywords                     // An MPL integral type wrapper: the size of kw
52       )
53   {
54       enum { arity = mpl::size<Sig>::value - 1 };
55 
56       typedef typename detail::error::more_keywords_than_function_arguments<
57           NumKeywords::value, arity
58           >::too_many_keywords assertion;
59 
60       return objects::function_object(
61           detail::caller<F,CallPolicies,Sig>(f, p)
62         , kw);
63   }
64 
65   //   Helpers for make_function when called with 3 arguments.  These
66   //   dispatch functions are used to discriminate between the cases
67   //   when the 3rd argument is keywords or when it is a signature.
68   //
69   // @group {
70   template <class F, class CallPolicies, class Keywords>
make_function_dispatch(F f,CallPolicies const & policies,Keywords const & kw,mpl::true_)71   object make_function_dispatch(F f, CallPolicies const& policies, Keywords const& kw, mpl::true_)
72   {
73       return detail::make_function_aux(
74           f
75         , policies
76         , detail::get_signature(f)
77         , kw.range()
78         , mpl::int_<Keywords::size>()
79       );
80   }
81 
82   template <class F, class CallPolicies, class Signature>
make_function_dispatch(F f,CallPolicies const & policies,Signature const & sig,mpl::false_)83   object make_function_dispatch(F f, CallPolicies const& policies, Signature const& sig, mpl::false_)
84   {
85       return detail::make_function_aux(
86           f
87         , policies
88         , sig
89       );
90   }
91   // }
92 
93  }
94 
95 //   These overloaded functions wrap a function or member function
96 //   pointer as a Python object, using optional CallPolicies,
97 //   Keywords, and/or Signature.
98 //
99 //   @group {
100 template <class F>
make_function(F f)101 object make_function(F f)
102 {
103     return detail::make_function_aux(
104         f,default_call_policies(), detail::get_signature(f));
105 }
106 
107 template <class F, class CallPolicies>
make_function(F f,CallPolicies const & policies)108 object make_function(F f, CallPolicies const& policies)
109 {
110     return detail::make_function_aux(
111         f, policies, detail::get_signature(f));
112 }
113 
114 template <class F, class CallPolicies, class KeywordsOrSignature>
make_function(F f,CallPolicies const & policies,KeywordsOrSignature const & keywords_or_signature)115 object make_function(
116     F f
117   , CallPolicies const& policies
118   , KeywordsOrSignature const& keywords_or_signature)
119 {
120     typedef typename
121         detail::is_reference_to_keywords<KeywordsOrSignature&>::type
122         is_kw;
123 
124     return detail::make_function_dispatch(
125         f
126       , policies
127       , keywords_or_signature
128       , is_kw()
129     );
130 }
131 
132 template <class F, class CallPolicies, class Keywords, class Signature>
make_function(F f,CallPolicies const & policies,Keywords const & kw,Signature const & sig)133 object make_function(
134     F f
135   , CallPolicies const& policies
136   , Keywords const& kw
137   , Signature const& sig
138  )
139 {
140     return detail::make_function_aux(
141           f
142         , policies
143         , sig
144         , kw.range()
145         , mpl::int_<Keywords::size>()
146       );
147 }
148 // }
149 
150 }}
151 
152 
153 #endif // MAKE_FUNCTION_DWA20011221_HPP
154