source: NonGTP/Boost/boost/python/object/py_function.hpp @ 857

Revision 857, 4.0 KB checked in by igarcia, 18 years ago (diff)
Line 
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
8# include <boost/python/detail/signature.hpp>
9# include <boost/detail/workaround.hpp>
10# include <boost/mpl/size.hpp>
11# include <memory>
12
13namespace boost { namespace python { namespace objects {
14
15// This type is used as a "generalized Python callback", wrapping the
16// function signature:
17//
18//      PyObject* (PyObject* args, PyObject* keywords)
19
20struct BOOST_PYTHON_DECL py_function_impl_base
21{
22    virtual ~py_function_impl_base();
23    virtual PyObject* operator()(PyObject*, PyObject*) = 0;
24    virtual unsigned min_arity() const = 0;
25    virtual unsigned max_arity() const;
26    virtual python::detail::signature_element const* signature() const = 0;
27};
28
29template <class Caller>
30struct caller_py_function_impl : py_function_impl_base
31{
32    caller_py_function_impl(Caller const& caller)
33        : m_caller(caller)
34    {}
35   
36    PyObject* operator()(PyObject* args, PyObject* kw)
37    {
38        return m_caller(args, kw);
39    }
40   
41    virtual unsigned min_arity() const
42    {
43        return m_caller.min_arity();
44    }
45   
46    virtual python::detail::signature_element const* signature() const
47    {
48        return m_caller.signature();
49    }
50
51 private:
52    Caller m_caller;
53};
54
55template <class Caller, class Sig>
56struct signature_py_function_impl : py_function_impl_base
57{
58    signature_py_function_impl(Caller const& caller)
59        : m_caller(caller)
60    {}
61   
62    PyObject* operator()(PyObject* args, PyObject* kw)
63    {
64        return m_caller(args, kw);
65    }
66   
67    virtual unsigned min_arity() const
68    {
69        return mpl::size<Sig>::value - 1;
70    }
71   
72    virtual python::detail::signature_element const* signature() const
73    {
74        return python::detail::signature<Sig>::elements();
75    }
76
77 private:
78    Caller m_caller;
79};
80
81template <class Caller, class Sig>
82struct full_py_function_impl : py_function_impl_base
83{
84    full_py_function_impl(Caller const& caller, unsigned min_arity, unsigned max_arity)
85      : m_caller(caller)
86      , m_min_arity(min_arity)
87      , m_max_arity(max_arity > min_arity ? max_arity : min_arity)
88    {}
89   
90    PyObject* operator()(PyObject* args, PyObject* kw)
91    {
92        return m_caller(args, kw);
93    }
94   
95    virtual unsigned min_arity() const
96    {
97        return m_min_arity;
98    }
99   
100    virtual unsigned max_arity() const
101    {
102        return m_max_arity;
103    }
104   
105    virtual python::detail::signature_element const* signature() const
106    {
107        return python::detail::signature<Sig>::elements();
108    }
109
110 private:
111    Caller m_caller;
112    unsigned m_min_arity;
113    unsigned m_max_arity;
114};
115
116struct py_function
117{
118    template <class Caller>
119    py_function(Caller const& caller)
120        : m_impl(new caller_py_function_impl<Caller>(caller))
121    {}
122
123    template <class Caller, class Sig>
124    py_function(Caller const& caller, Sig)
125      : m_impl(new signature_py_function_impl<Caller, Sig>(caller))
126    {}
127
128    template <class Caller, class Sig>
129    py_function(Caller const& caller, Sig, int min_arity, int max_arity = 0)
130      : m_impl(new full_py_function_impl<Caller, Sig>(caller, min_arity, max_arity))
131    {}
132
133    py_function(py_function const& rhs)
134        : m_impl(rhs.m_impl)
135    {}
136
137    PyObject* operator()(PyObject* args, PyObject* kw) const
138    {
139        return (*m_impl)(args, kw);
140    }
141
142    unsigned min_arity() const
143    {
144        return m_impl->min_arity();
145    }
146   
147    unsigned max_arity() const
148    {
149        return m_impl->max_arity();
150    }
151
152    python::detail::signature_element const* signature() const
153    {
154        return m_impl->signature();
155    }
156   
157 private:
158    mutable std::auto_ptr<py_function_impl_base> m_impl;
159};
160
161}}} // namespace boost::python::objects
162
163#endif // PY_FUNCTION_DWA200286_HPP
Note: See TracBrowser for help on using the repository browser.