Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / python / converter / return_from_python.hpp
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
21 namespace boost { namespace python { namespace converter { 
22
23 template <class T> struct is_object_manager;
24
25 namespace 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
87 template <class T>
88 struct return_from_python
89     : detail::select_return_from_python<T>::type
90 {
91 };
92
93 // Specialization as a convenience for call and call_method
94 template <>
95 struct 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 //
111 namespace 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