source: NonGTP/Boost/boost/python/converter/return_from_python.hpp @ 857

Revision 857, 4.3 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 RETURN_FROM_PYTHON_DWA200265_HPP
6# define RETURN_FROM_PYTHON_DWA200265_HPP
7
8# include <boost/python/converter/from_python.hpp>
9# include <boost/python/converter/rvalue_from_python_data.hpp>
10# include <boost/python/converter/registered.hpp>
11# include <boost/python/converter/registered_pointee.hpp>
12# include <boost/python/converter/object_manager.hpp>
13# include <boost/python/detail/void_ptr.hpp>
14# include <boost/python/detail/void_return.hpp>
15# include <boost/python/errors.hpp>
16# include <boost/python/handle.hpp>
17# include <boost/type_traits/has_trivial_copy.hpp>
18# include <boost/mpl/and.hpp>
19# include <boost/mpl/bool.hpp>
20
21namespace boost { namespace python { namespace converter {
22
23template <class T> struct is_object_manager;
24
25namespace detail
26{
27  template <class T>
28  struct return_pointer_from_python
29  {
30      typedef T result_type;
31      T operator()(PyObject*) const;
32  };
33 
34  template <class T>
35  struct return_reference_from_python
36  {
37      typedef T result_type;
38      T operator()(PyObject*) const;
39  };
40 
41  template <class T>
42  struct return_rvalue_from_python
43  {
44      typedef T result_type;
45
46      return_rvalue_from_python();
47      result_type operator()(PyObject*);
48   private:
49      rvalue_from_python_data<T> m_data;
50  };
51 
52  template <class T>
53  struct return_object_manager_from_python
54  {
55      typedef T result_type;
56      result_type operator()(PyObject*) const;
57  };
58 
59  template <class T>
60  struct select_return_from_python
61  {
62      BOOST_STATIC_CONSTANT(
63          bool, obj_mgr = is_object_manager<T>::value);
64
65      BOOST_STATIC_CONSTANT(
66          bool, ptr = is_pointer<T>::value);
67   
68      BOOST_STATIC_CONSTANT(
69          bool, ref = is_reference<T>::value);
70
71      typedef typename mpl::if_c<
72          obj_mgr
73          , return_object_manager_from_python<T>
74          , typename mpl::if_c<
75              ptr
76              , return_pointer_from_python<T>
77              , typename mpl::if_c<
78                  ref
79                  , return_reference_from_python<T>
80                  , return_rvalue_from_python<T>
81                >::type
82            >::type
83         >::type type;
84  };
85}
86
87template <class T>
88struct return_from_python
89    : detail::select_return_from_python<T>::type
90{
91};
92
93// Specialization as a convenience for call and call_method
94template <>
95struct return_from_python<void>
96{
97    typedef python::detail::returnable<void>::type result_type;
98   
99    result_type operator()(PyObject* x) const
100    {
101        (void_result_from_python)(x);
102# ifdef BOOST_NO_VOID_RETURNS
103        return result_type();
104# endif
105    }
106};
107
108//
109// Implementations
110//
111namespace detail
112{
113  template <class T>
114  inline return_rvalue_from_python<T>::return_rvalue_from_python()
115      : m_data(
116          const_cast<registration*>(&registered<T>::converters)
117          )
118  {
119  }
120 
121  template <class T>
122  inline typename return_rvalue_from_python<T>::result_type
123  return_rvalue_from_python<T>::operator()(PyObject* obj)
124  {
125    // Take possession of the source object here.  If the result is in
126    // fact going to be a copy of an lvalue embedded in the object,
127    // and we take possession inside rvalue_result_from_python, it
128    // will be destroyed too early.
129    handle<> holder(obj);
130
131      return *(T*)
132          (rvalue_result_from_python)(obj, m_data.stage1);
133  }
134
135  template <class T>
136  inline T return_reference_from_python<T>::operator()(PyObject* obj) const
137  {
138      return python::detail::void_ptr_to_reference(
139          (reference_result_from_python)(obj, registered<T>::converters)
140          , (T(*)())0);
141  }
142
143  template <class T>
144  inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
145  {
146      return T(
147          (pointer_result_from_python)(obj, registered_pointee<T>::converters)
148          );
149  }
150
151  template <class T>
152  inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const
153  {
154      return T(
155          object_manager_traits<T>::adopt(expect_non_null(obj))
156          );
157  }
158}
159 
160}}} // namespace boost::python::converter
161
162#endif // RETURN_FROM_PYTHON_DWA200265_HPP
Note: See TracBrowser for help on using the repository browser.