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

Revision 857, 7.5 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 ARG_TO_PYTHON_DWA200265_HPP
6# define ARG_TO_PYTHON_DWA200265_HPP
7
8# include <boost/python/ptr.hpp>
9# include <boost/python/tag.hpp>
10# include <boost/python/to_python_indirect.hpp>
11
12# include <boost/python/converter/registered.hpp>
13# include <boost/python/converter/registered_pointee.hpp>
14# include <boost/python/converter/arg_to_python_base.hpp>
15# include <boost/python/converter/shared_ptr_to_python.hpp>
16// Bring in specializations
17# include <boost/python/converter/builtin_converters.hpp>
18
19# include <boost/python/object/function_handle.hpp>
20
21# include <boost/python/base_type_traits.hpp>
22
23# include <boost/python/detail/indirect_traits.hpp>
24# include <boost/python/detail/convertible.hpp>
25# include <boost/python/detail/string_literal.hpp>
26# include <boost/python/detail/value_is_shared_ptr.hpp>
27
28# include <boost/type_traits/cv_traits.hpp>
29# include <boost/type_traits/composite_traits.hpp>
30# include <boost/type_traits/function_traits.hpp>
31
32
33# include <boost/mpl/or.hpp>
34
35namespace boost { namespace python { namespace converter {
36
37template <class T> struct is_object_manager;
38
39namespace detail
40{
41  template <class T>
42  struct function_arg_to_python : handle<>
43  {
44      function_arg_to_python(T const& x);
45  };
46
47  template <class T>
48  struct reference_arg_to_python : handle<>
49  {
50      reference_arg_to_python(T& x);
51   private:
52      static PyObject* get_object(T& x);
53  };
54
55  template <class T>
56  struct shared_ptr_arg_to_python : handle<>
57  {
58      shared_ptr_arg_to_python(T const& x);
59   private:
60      static PyObject* get_object(T& x);
61  };
62
63  template <class T>
64  struct value_arg_to_python : arg_to_python_base
65  {
66      // Throw an exception if the conversion can't succeed
67      value_arg_to_python(T const&);
68  };
69
70  template <class Ptr>
71  struct pointer_deep_arg_to_python : arg_to_python_base
72  {
73      // Throw an exception if the conversion can't succeed
74      pointer_deep_arg_to_python(Ptr);
75  };
76
77  template <class Ptr>
78  struct pointer_shallow_arg_to_python : handle<>
79  {
80      // Throw an exception if the conversion can't succeed
81      pointer_shallow_arg_to_python(Ptr);
82   private:
83      static PyObject* get_object(Ptr p);
84  };
85
86  // Convert types that manage a Python object to_python
87  template <class T>
88  struct object_manager_arg_to_python
89  {
90      object_manager_arg_to_python(T const& x) : m_src(x) {}
91     
92      PyObject* get() const
93      {
94          return python::upcast<PyObject>(get_managed_object(m_src, tag));
95      }
96     
97   private:
98      T const& m_src;
99  };
100
101  template <class T>
102  struct select_arg_to_python
103  {
104      typedef typename unwrap_reference<T>::type unwrapped_referent;
105      typedef typename unwrap_pointer<T>::type unwrapped_ptr;
106
107      typedef typename mpl::if_<
108          // Special handling for char const[N]; interpret them as char
109          // const* for the sake of conversion
110          python::detail::is_string_literal<T const>
111        , arg_to_python<char const*>
112
113        , typename mpl::if_<
114              python::detail::value_is_shared_ptr<T>
115            , shared_ptr_arg_to_python<T>
116     
117            , typename mpl::if_<
118                mpl::or_<
119                    is_function<T>
120                  , indirect_traits::is_pointer_to_function<T>
121                  , is_member_function_pointer<T>
122                >
123                , function_arg_to_python<T>
124
125                , typename mpl::if_<
126                      is_object_manager<T>
127                    , object_manager_arg_to_python<T>
128
129                    , typename mpl::if_<
130                          is_pointer<T>
131                        , pointer_deep_arg_to_python<T>
132
133                        , typename mpl::if_<
134                              is_pointer_wrapper<T>
135                            , pointer_shallow_arg_to_python<unwrapped_ptr>
136
137                            , typename mpl::if_<
138                                  is_reference_wrapper<T>
139                                , reference_arg_to_python<unwrapped_referent>
140                                , value_arg_to_python<T>
141                              >::type
142                          >::type
143                      >::type
144                  >::type
145              >::type
146          >::type
147      >::type
148     
149      type;
150  };
151}
152
153template <class T>
154struct arg_to_python
155    : detail::select_arg_to_python<T>::type
156{
157    typedef typename detail::select_arg_to_python<T>::type base;
158 public: // member functions
159    // Throw an exception if the conversion can't succeed
160    arg_to_python(T const& x);
161};
162
163//
164// implementations
165//
166namespace detail
167{
168  // reject_raw_object_ptr -- cause a compile-time error if the user
169  // should pass a raw Python object pointer
170  using python::detail::yes_convertible;
171  using python::detail::no_convertible;
172  using python::detail::unspecialized;
173 
174  template <class T> struct cannot_convert_raw_PyObject;
175
176  template <class T, class Convertibility>
177  struct reject_raw_object_helper
178  {
179      static void error(Convertibility)
180      {
181          cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
182      }
183      static void error(...) {}
184  };
185 
186  template <class T>
187  inline void reject_raw_object_ptr(T*)
188  {
189      reject_raw_object_helper<T,yes_convertible>::error(
190          python::detail::convertible<PyObject const volatile*>::check((T*)0));
191     
192      typedef typename remove_cv<T>::type value_type;
193     
194      reject_raw_object_helper<T,no_convertible>::error(
195          python::detail::convertible<unspecialized*>::check(
196              (base_type_traits<value_type>*)0
197              ));
198  }
199  // ---------
200     
201  template <class T>
202  inline function_arg_to_python<T>::function_arg_to_python(T const& x)
203      : handle<>(python::objects::make_function_handle(x))
204  {
205  }
206
207  template <class T>
208  inline value_arg_to_python<T>::value_arg_to_python(T const& x)
209      : arg_to_python_base(&x, registered<T>::converters)
210  {
211  }
212
213  template <class Ptr>
214  inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
215      : arg_to_python_base(x, registered_pointee<Ptr>::converters)
216  {
217      detail::reject_raw_object_ptr((Ptr)0);
218  }
219
220  template <class T>
221  inline PyObject* reference_arg_to_python<T>::get_object(T& x)
222  {
223      to_python_indirect<T&,python::detail::make_reference_holder> convert;
224      return convert(x);
225  }
226
227  template <class T>
228  inline reference_arg_to_python<T>::reference_arg_to_python(T& x)
229      : handle<>(reference_arg_to_python<T>::get_object(x))
230  {
231  }
232
233  template <class T>
234  inline shared_ptr_arg_to_python<T>::shared_ptr_arg_to_python(T const& x)
235      : handle<>(shared_ptr_to_python(x))
236  {
237  }
238
239  template <class Ptr>
240  inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x)
241      : handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x))
242  {
243      detail::reject_raw_object_ptr((Ptr)0);
244  }
245
246  template <class Ptr>
247  inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)
248  {
249      to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
250      return convert(x);
251  }
252}
253
254template <class T>
255inline arg_to_python<T>::arg_to_python(T const& x)
256    : base(x)
257{}
258
259}}} // namespace boost::python::converter
260
261#endif // ARG_TO_PYTHON_DWA200265_HPP
Note: See TracBrowser for help on using the repository browser.