source: NonGTP/Boost/boost/python/detail/defaults_gen.hpp @ 857

Revision 857, 20.0 KB checked in by igarcia, 19 years ago (diff)
RevLine 
[857]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#ifndef DEFAULTS_GEN_JDG20020807_HPP
10#define DEFAULTS_GEN_JDG20020807_HPP
11
12#include <boost/python/detail/preprocessor.hpp>
13#include <boost/preprocessor/repeat.hpp>
14#include <boost/preprocessor/repeat_from_to.hpp>
15#include <boost/preprocessor/enum.hpp>
16#include <boost/preprocessor/enum_params.hpp>
17#include <boost/preprocessor/repetition/enum_binary_params.hpp>
18#include <boost/preprocessor/tuple.hpp>
19#include <boost/preprocessor/cat.hpp>
20#include <boost/preprocessor/arithmetic/sub.hpp>
21#include <boost/preprocessor/stringize.hpp>
22#include <boost/preprocessor/inc.hpp>
23#include <boost/preprocessor/empty.hpp>
24#include <boost/preprocessor/comma_if.hpp>
25#include <boost/config.hpp>
26#include <boost/mpl/begin_end.hpp>
27#include <boost/mpl/next.hpp>
28#include <boost/mpl/deref.hpp>
29#include <cstddef>
30
31namespace boost { namespace python {
32
33namespace detail
34{
35  // overloads_base is used as a base class for all function
36  // stubs. This class holds the doc_string of the stubs.
37  struct overloads_base
38  {
39      overloads_base(char const* doc_)
40          : m_doc(doc_) {}
41
42      overloads_base(char const* doc_, detail::keyword_range const& kw)
43          : m_doc(doc_), m_keywords(kw) {}
44
45      char const* doc_string() const
46      {
47          return m_doc;
48      }
49
50      detail::keyword_range const& keywords() const
51      {
52          return m_keywords;
53      }
54
55   private:
56      char const* m_doc;
57      detail::keyword_range m_keywords;
58  };
59
60  // overloads_proxy is generated by the overloads_common operator[] (see
61  // below). This class holds a user defined call policies of the stubs.
62  template <class CallPoliciesT, class OverloadsT>
63  struct overloads_proxy
64      : public overloads_base
65  {
66      typedef typename OverloadsT::non_void_return_type   non_void_return_type;
67      typedef typename OverloadsT::void_return_type       void_return_type;
68
69      overloads_proxy(
70          CallPoliciesT const& policies_
71          , char const* doc
72          , keyword_range const& kw
73          )
74          : overloads_base(doc, kw)
75            , policies(policies_)
76      {}
77
78      CallPoliciesT
79      call_policies() const
80      {
81          return policies;
82      }
83
84      CallPoliciesT policies;
85  };
86
87  // overloads_common is our default function stubs base class. This
88  // class returns the default_call_policies in its call_policies()
89  // member function.  It can generate a overloads_proxy however through
90  // its operator[]
91  template <class DerivedT>
92  struct overloads_common
93      : public overloads_base
94  {
95      overloads_common(char const* doc)
96          : overloads_base(doc) {}
97
98      overloads_common(char const* doc, keyword_range const& kw)
99          : overloads_base(doc, kw) {}
100
101      default_call_policies
102      call_policies() const
103      {
104          return default_call_policies();
105      }
106
107      template <class CallPoliciesT>
108      overloads_proxy<CallPoliciesT, DerivedT>
109      operator[](CallPoliciesT const& policies) const
110      {
111          return overloads_proxy<CallPoliciesT, DerivedT>(
112              policies, this->doc_string(), this->keywords());
113      }
114  };
115
116}}} // namespace boost::python::detail
117
118
119#define BOOST_PYTHON_TYPEDEF_GEN(z, index, data)                                \
120    typedef typename ::boost::mpl::next<BOOST_PP_CAT(iter, index)>::type        \
121        BOOST_PP_CAT(iter, BOOST_PP_INC(index));                                \
122    typedef typename ::boost::mpl::deref<BOOST_PP_CAT(iter, index)>::type       \
123        BOOST_PP_CAT(T, index);
124
125#define BOOST_PYTHON_FUNC_WRAPPER_GEN(z, index, data)                   \
126    static RT BOOST_PP_CAT(func_,                                       \
127        BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) (    \
128        BOOST_PP_ENUM_BINARY_PARAMS_Z(                                  \
129            1, index, T, arg))                                          \
130    {                                                                   \
131        BOOST_PP_TUPLE_ELEM(3, 2, data)                                 \
132        BOOST_PP_TUPLE_ELEM(3, 0, data)(                                \
133            BOOST_PP_ENUM_PARAMS(                                       \
134                index,                                                  \
135                arg));                                                  \
136    }
137
138#define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret)     \
139    struct fstubs_name                                                          \
140    {                                                                           \
141        BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts));            \
142        BOOST_STATIC_CONSTANT(int, max_args = n_funcs);                         \
143                                                                                \
144        template <typename SigT>                                                \
145        struct gen                                                              \
146        {                                                                       \
147            typedef typename ::boost::mpl::begin<SigT>::type rt_iter;           \
148            typedef typename ::boost::mpl::deref<rt_iter>::type RT;             \
149            typedef typename ::boost::mpl::next<rt_iter>::type iter0;           \
150                                                                                \
151            BOOST_PP_REPEAT_2ND(                                                \
152                n_args,                                                         \
153                BOOST_PYTHON_TYPEDEF_GEN,                                       \
154                0)                                                              \
155                                                                                \
156            BOOST_PP_REPEAT_FROM_TO_2(                                          \
157                BOOST_PP_SUB_D(1, n_args, n_dflts),                             \
158                BOOST_PP_INC(n_args),                                           \
159                BOOST_PYTHON_FUNC_WRAPPER_GEN,                                  \
160                (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret))               \
161        };                                                                      \
162    };                                                                          \
163
164///////////////////////////////////////////////////////////////////////////////
165#define BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN(z, index, data)                       \
166    static RT BOOST_PP_CAT(func_,                                               \
167        BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) (            \
168            ClassT obj BOOST_PP_COMMA_IF(index)                                 \
169            BOOST_PP_ENUM_BINARY_PARAMS_Z(1, index, T, arg)                     \
170        )                                                                       \
171    {                                                                           \
172        BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)(    \
173            BOOST_PP_ENUM_PARAMS(index, arg)                                    \
174        );                                                                      \
175    }
176
177#define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \
178    struct fstubs_name                                                          \
179    {                                                                           \
180        BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts));            \
181        BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1);                     \
182                                                                                \
183        template <typename SigT>                                                \
184        struct gen                                                              \
185        {                                                                       \
186            typedef typename ::boost::mpl::begin<SigT>::type rt_iter;           \
187            typedef typename ::boost::mpl::deref<rt_iter>::type RT;             \
188                                                                                \
189            typedef typename ::boost::mpl::next<rt_iter>::type class_iter;      \
190            typedef typename ::boost::mpl::deref<class_iter>::type ClassT;      \
191            typedef typename ::boost::mpl::next<class_iter>::type iter0;        \
192                                                                                \
193            BOOST_PP_REPEAT_2ND(                                                \
194                n_args,                                                         \
195                BOOST_PYTHON_TYPEDEF_GEN,                                       \
196                0)                                                              \
197                                                                                \
198            BOOST_PP_REPEAT_FROM_TO_2(                                          \
199                BOOST_PP_SUB_D(1, n_args, n_dflts),                             \
200                BOOST_PP_INC(n_args),                                           \
201                BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN,                              \
202                (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret))               \
203        };                                                                      \
204    };
205
206#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)                    \
207    fstubs_name(char const* doc = 0)                                                        \
208        : ::boost::python::detail::overloads_common<fstubs_name>(doc) {}                    \
209    template <std::size_t N>                                                                \
210    fstubs_name(char const* doc, ::boost::python::detail::keywords<N> const& keywords)      \
211        : ::boost::python::detail::overloads_common<fstubs_name>(                           \
212            doc, keywords.range())                                                          \
213    {                                                                                       \
214        typedef typename ::boost::python::detail::                                          \
215            error::more_keywords_than_function_arguments<                                   \
216                N,n_args>::too_many_keywords assertion;                                     \
217    }                                                                                       \
218    template <std::size_t N>                                                                \
219    fstubs_name(::boost::python::detail::keywords<N> const& keywords, char const* doc = 0)  \
220        : ::boost::python::detail::overloads_common<fstubs_name>(                           \
221            doc, keywords.range())                                                          \
222    {                                                                                       \
223        typedef typename ::boost::python::detail::                                          \
224            error::more_keywords_than_function_arguments<                                   \
225                N,n_args>::too_many_keywords assertion;                                     \
226    }
227
228# if defined(BOOST_NO_VOID_RETURNS)
229
230#  define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)   \
231    struct fstubs_name                                                          \
232        : public ::boost::python::detail::overloads_common<fstubs_name>         \
233    {                                                                           \
234        BOOST_PYTHON_GEN_FUNCTION(                                              \
235            fname, non_void_return_type, n_args, n_dflts, return)               \
236        BOOST_PYTHON_GEN_FUNCTION(                                              \
237            fname, void_return_type, n_args, n_dflts, ;)                        \
238                                                                                \
239        BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)        \
240    };
241
242#  define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)       \
243    struct fstubs_name                                                                  \
244        : public ::boost::python::detail::overloads_common<fstubs_name>                 \
245    {                                                                                   \
246        BOOST_PYTHON_GEN_MEM_FUNCTION(                                                  \
247            fname, non_void_return_type, n_args, n_dflts, return)                       \
248        BOOST_PYTHON_GEN_MEM_FUNCTION(                                                  \
249            fname, void_return_type, n_args, n_dflts, ;)                                \
250                                                                                        \
251        BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)                \
252    };
253
254# else // !defined(BOOST_NO_VOID_RETURNS)
255
256#  define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)   \
257    struct fstubs_name                                                          \
258        : public ::boost::python::detail::overloads_common<fstubs_name>         \
259    {                                                                           \
260        BOOST_PYTHON_GEN_FUNCTION(                                              \
261            fname, non_void_return_type, n_args, n_dflts, return)               \
262                                                                                \
263        typedef non_void_return_type void_return_type;                          \
264        BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)        \
265    };
266
267
268#  define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)       \
269    struct fstubs_name                                                                  \
270        : public ::boost::python::detail::overloads_common<fstubs_name>                 \
271    {                                                                                   \
272        BOOST_PYTHON_GEN_MEM_FUNCTION(                                                  \
273            fname, non_void_return_type, n_args, n_dflts, return)                       \
274                                                                                        \
275        typedef non_void_return_type void_return_type;                                  \
276        BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)                \
277    };
278
279# endif // !defined(BOOST_NO_VOID_RETURNS)
280
281///////////////////////////////////////////////////////////////////////////////
282//
283//  MAIN MACROS
284//
285//      Given generator_name, fname, min_args and max_args, These macros
286//      generate function stubs that forward to a function or member function
287//      named fname. max_args is the arity of the function or member function
288//      fname. fname can have default arguments. min_args is the minimum
289//      arity that fname can accept.
290//
291//      There are two versions:
292//
293//          1. BOOST_PYTHON_FUNCTION_OVERLOADS for free functions
294//          2. BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for member functions.
295//
296//      For instance, given a function:
297//
298//      int
299//      foo(int a, char b = 1, unsigned c = 2, double d = 3)
300//      {
301//          return a + b + c + int(d);
302//      }
303//
304//      The macro invocation:
305//
306//          BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4)
307//
308//      Generates this code:
309//
310//      struct foo_stubsNonVoid
311//      {
312//          static const int n_funcs = 4;
313//          static const int max_args = n_funcs;
314//
315//          template <typename SigT>
316//          struct gen
317//          {
318//              typedef typename ::boost::mpl::begin<SigT>::type    rt_iter;
319//              typedef typename rt_iter::type                      RT;
320//              typedef typename rt_iter::next                      iter0;
321//              typedef typename iter0::type                        T0;
322//              typedef typename iter0::next                        iter1;
323//              typedef typename iter1::type                        T1;
324//              typedef typename iter1::next                        iter2;
325//              typedef typename iter2::type                        T2;
326//              typedef typename iter2::next                        iter3;
327//              typedef typename iter3::type                        T3;
328//              typedef typename iter3::next                        iter4;
329//
330//              static RT func_0(T0 arg0)
331//              { return foo(arg0); }
332//
333//              static RT func_1(T0 arg0, T1 arg1)
334//              { return foo(arg0, arg1); }
335//
336//              static RT func_2(T0 arg0, T1 arg1, T2 arg2)
337//              { return foo(arg0, arg1, arg2); }
338//
339//              static RT func_3(T0 arg0, T1 arg1, T2 arg2, T3 arg3)
340//              { return foo(arg0, arg1, arg2, arg3); }
341//          };
342//      };
343//
344//      struct foo_overloads
345//          : public boost::python::detail::overloads_common<foo_overloads>
346//      {
347//          typedef foo_overloadsNonVoid    non_void_return_type;
348//          typedef foo_overloadsNonVoid    void_return_type;
349//
350//          foo_overloads(char const* doc = 0)
351//             : boost::python::detail::overloads_common<foo_overloads>(doc) {}
352//      };
353//
354//      The typedefs non_void_return_type and void_return_type are
355//      used to handle compilers that do not support void returns. The
356//      example above typedefs non_void_return_type and
357//      void_return_type to foo_overloadsNonVoid. On compilers that do
358//      not support void returns, there are two versions:
359//      foo_overloadsNonVoid and foo_overloadsVoid.  The "Void"
360//      version is almost identical to the "NonVoid" version except
361//      for the return type (void) and the lack of the return keyword.
362//
363//      See the overloads_common above for a description of the
364//      foo_overloads' base class.
365//
366///////////////////////////////////////////////////////////////////////////////
367#define BOOST_PYTHON_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args)          \
368    BOOST_PYTHON_GEN_FUNCTION_STUB(                                                         \
369        fname,                                                                              \
370        generator_name,                                                                     \
371        max_args,                                                                           \
372        BOOST_PP_SUB_D(1, max_args, min_args))
373
374#define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args)   \
375    BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(                                                     \
376        fname,                                                                              \
377        generator_name,                                                                     \
378        max_args,                                                                           \
379        BOOST_PP_SUB_D(1, max_args, min_args))
380
381// deprecated macro names (to be removed)
382#define BOOST_PYTHON_FUNCTION_GENERATOR BOOST_PYTHON_FUNCTION_OVERLOADS
383#define BOOST_PYTHON_MEM_FUN_GENERATOR BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
384
385///////////////////////////////////////////////////////////////////////////////
386#endif // DEFAULTS_GEN_JDG20020807_HPP
387
388
Note: See TracBrowser for help on using the repository browser.