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 
11 #ifndef DEFAULTS_DEF_JDG20020811_HPP
12 #define DEFAULTS_DEF_JDG20020811_HPP
13 
14 #include <boost/python/detail/defaults_gen.hpp>
15 #include <boost/python/detail/type_traits.hpp>
16 #include <boost/mpl/front.hpp>
17 #include <boost/mpl/size.hpp>
18 #include <boost/static_assert.hpp>
19 #include <boost/preprocessor/iterate.hpp>
20 #include <boost/python/class_fwd.hpp>
21 #include <boost/python/scope.hpp>
22 #include <boost/preprocessor/debug/line.hpp>
23 #include <boost/python/detail/scope.hpp>
24 #include <boost/python/detail/make_keyword_range_fn.hpp>
25 #include <boost/python/object/add_to_namespace.hpp>
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 namespace boost { namespace python {
29 
30 struct module;
31 
32 namespace objects
33 {
34   struct class_base;
35 }
36 
37 namespace detail
38 {
39   // Called as::
40   //
41   //    name_space_def(ns, "func", func, kw, policies, docstring, &ns)
42   //
43   // Dispatch to properly add f to namespace ns.
44   //
45   // @group define_stub_function helpers {
46   template <class Func, class CallPolicies, class NameSpaceT>
name_space_def(NameSpaceT & name_space,char const * name,Func f,keyword_range const & kw,CallPolicies const & policies,char const * doc,objects::class_base *)47   static void name_space_def(
48       NameSpaceT& name_space
49       , char const* name
50       , Func f
51       , keyword_range const& kw
52       , CallPolicies const& policies
53       , char const* doc
54       , objects::class_base*
55       )
56   {
57       typedef typename NameSpaceT::wrapped_type wrapped_type;
58 
59       objects::add_to_namespace(
60           name_space, name,
61           detail::make_keyword_range_function(
62               f, policies, kw, get_signature(f, (wrapped_type*)0))
63         , doc
64       );
65   }
66 
67   template <class Func, class CallPolicies>
name_space_def(object & name_space,char const * name,Func f,keyword_range const & kw,CallPolicies const & policies,char const * doc,...)68   static void name_space_def(
69       object& name_space
70       , char const* name
71       , Func f
72       , keyword_range const& kw
73       , CallPolicies const& policies
74       , char const* doc
75       , ...
76       )
77   {
78       scope within(name_space);
79 
80       detail::scope_setattr_doc(
81           name
82           , detail::make_keyword_range_function(f, policies, kw)
83           , doc);
84   }
85 
86   // For backward compatibility -- is this obsolete?
87   template <class Func, class CallPolicies, class NameSpaceT>
name_space_def(NameSpaceT & name_space,char const * name,Func f,keyword_range const & kw,CallPolicies const & policies,char const * doc,module *)88   static void name_space_def(
89       NameSpaceT& name_space
90       , char const* name
91       , Func f
92       , keyword_range const& kw // ignored
93       , CallPolicies const& policies
94       , char const* doc
95       , module*
96       )
97   {
98       name_space.def(name, f, policies, doc);
99   }
100   // }
101 
102 
103   //  Expansions of ::
104   //
105   //      template <typename OverloadsT, typename NameSpaceT>
106   //      inline void
107   //      define_stub_function(
108   //          char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_<N>)
109   //      {
110   //          name_space.def(name, &OverloadsT::func_N);
111   //      }
112   //
113   //  where N runs from 0 to BOOST_PYTHON_MAX_ARITY.
114   //
115   //  The set of overloaded functions (define_stub_function) expects:
116   //
117   //      1. char const* name:        function name that will be visible to python
118   //      2. OverloadsT:              a function overloads struct (see defaults_gen.hpp)
119   //      3. NameSpaceT& name_space:  a python::class_ or python::module instance
120   //      4. int_t<N>:                the Nth overloaded function (OverloadsT::func_N)
121   //                                  (see defaults_gen.hpp)
122   //      5. char const* name:        doc string
123   //
124   // @group define_stub_function<N> {
125   template <int N>
126   struct define_stub_function {};
127 
128 #define BOOST_PP_ITERATION_PARAMS_1                                             \
129     (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>))
130 
131 #include BOOST_PP_ITERATE()
132 
133   // }
134 
135   //  This helper template struct does the actual recursive
136   //  definition.  There's a generic version
137   //  define_with_defaults_helper<N> and a terminal case
138   //  define_with_defaults_helper<0>. The struct and its
139   //  specialization has a sole static member function def that
140   //  expects:
141   //
142   //    1. char const* name:        function name that will be
143   //                                visible to python
144   //
145   //    2. OverloadsT:              a function overloads struct
146   //                                (see defaults_gen.hpp)
147   //
148   //    3. NameSpaceT& name_space:  a python::class_ or
149   //                                python::module instance
150   //
151   //    4. char const* name:        doc string
152   //
153   //  The def static member function calls a corresponding
154   //  define_stub_function<N>. The general case recursively calls
155   //  define_with_defaults_helper<N-1>::def until it reaches the
156   //  terminal case case define_with_defaults_helper<0>.
157   template <int N>
158   struct define_with_defaults_helper {
159 
160       template <class StubsT, class CallPolicies, class NameSpaceT>
161       static void
defboost::python::detail::define_with_defaults_helper162       def(
163           char const* name,
164           StubsT stubs,
165           keyword_range kw,
166           CallPolicies const& policies,
167           NameSpaceT& name_space,
168           char const* doc)
169       {
170           //  define the NTH stub function of stubs
171           define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
172 
173           if (kw.second > kw.first)
174               --kw.second;
175 
176           //  call the next define_with_defaults_helper
177           define_with_defaults_helper<N-1>::def(name, stubs, kw, policies, name_space, doc);
178       }
179   };
180 
181   template <>
182   struct define_with_defaults_helper<0> {
183 
184       template <class StubsT, class CallPolicies, class NameSpaceT>
185       static void
defboost::python::detail::define_with_defaults_helper186       def(
187           char const* name,
188           StubsT stubs,
189           keyword_range const& kw,
190           CallPolicies const& policies,
191           NameSpaceT& name_space,
192           char const* doc)
193       {
194           //  define the Oth stub function of stubs
195           define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc);
196           //  return
197       }
198   };
199 
200   //  define_with_defaults
201   //
202   //      1. char const* name:        function name that will be
203   //                                  visible to python
204   //
205   //      2. OverloadsT:              a function overloads struct
206   //                                  (see defaults_gen.hpp)
207   //
208   //      3. CallPolicies& policies:  Call policies
209   //      4. NameSpaceT& name_space:  a python::class_ or
210   //                                  python::module instance
211   //
212   //      5. SigT sig:                Function signature typelist
213   //                                  (see defaults_gen.hpp)
214   //
215   //      6. char const* name:        doc string
216   //
217   //  This is the main entry point. This function recursively
218   //  defines all stub functions of StubT (see defaults_gen.hpp) in
219   //  NameSpaceT name_space which can be either a python::class_ or
220   //  a python::module. The sig argument is a typelist that
221   //  specifies the return type, the class (for member functions,
222   //  and the arguments. Here are some SigT examples:
223   //
224   //      int foo(int)        mpl::vector<int, int>
225   //      void bar(int, int)  mpl::vector<void, int, int>
226   //      void C::foo(int)    mpl::vector<void, C, int>
227   //
228   template <class OverloadsT, class NameSpaceT, class SigT>
229   inline void
define_with_defaults(char const * name,OverloadsT const & overloads,NameSpaceT & name_space,SigT const &)230   define_with_defaults(
231       char const* name,
232       OverloadsT const& overloads,
233       NameSpaceT& name_space,
234       SigT const&)
235   {
236       typedef typename mpl::front<SigT>::type return_type;
237       typedef typename OverloadsT::void_return_type void_return_type;
238       typedef typename OverloadsT::non_void_return_type non_void_return_type;
239 
240       typedef typename mpl::if_c<
241           is_same<void, return_type>::value
242           , void_return_type
243           , non_void_return_type
244       >::type stubs_type;
245 
246       BOOST_STATIC_ASSERT(
247           (stubs_type::max_args) <= mpl::size<SigT>::value);
248 
249       typedef typename stubs_type::template gen<SigT> gen_type;
250       define_with_defaults_helper<stubs_type::n_funcs-1>::def(
251           name
252           , gen_type()
253           , overloads.keywords()
254           , overloads.call_policies()
255           , name_space
256           , overloads.doc_string());
257   }
258 
259 } // namespace detail
260 
261 }} // namespace boost::python
262 
263 #endif // DEFAULTS_DEF_JDG20020811_HPP
264 
265 #else // defined(BOOST_PP_IS_ITERATING)
266 // PP vertical iteration code
267 
268 
269 template <>
270 struct define_stub_function<BOOST_PP_ITERATION()> {
271     template <class StubsT, class CallPolicies, class NameSpaceT>
definedefine_stub_function272     static void define(
273         char const* name
274         , StubsT const&
275         , keyword_range const& kw
276         , CallPolicies const& policies
277         , NameSpaceT& name_space
278         , char const* doc)
279     {
280         detail::name_space_def(
281             name_space
282             , name
283             , &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION())
284             , kw
285             , policies
286             , doc
287             , &name_space);
288     }
289 };
290 
291 #endif // !defined(BOOST_PP_IS_ITERATING)
292