Package pyplusplus :: Package code_repository :: Module call_policies

Source Code for Module pyplusplus.code_repository.call_policies

  1  # Copyright 2004-2008 Roman Yakovenko.
 
  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  
 
  6  """
 
  7  This file contains C++ code - custom call policies
 
  8  """ 
  9  
 
 10  from pyplusplus.decl_wrappers import call_policies 
 11  
 
 12  namespace = "pyplusplus::call_policies" 
 13  
 
 14  file_name = call_policies.PYPP_CALL_POLICIES_HEADER_FILE 
 15  
 
 16  code = \
 
 17  """// Copyright 2004-2008 Roman Yakovenko.
 
 18  // Distributed under the Boost Software License, Version 1.0. (See
 
 19  // accompanying file LICENSE_1_0.txt or copy at
 
 20  // http://www.boost.org/LICENSE_1_0.txt)
 
 21  
 
 22  #ifndef call_policies_pyplusplus_hpp__
 
 23  #define call_policies_pyplusplus_hpp__
 
 24  
 
 25  #include "boost/python.hpp"
 
 26  #include "boost/cstdint.hpp"
 
 27  #include "boost/mpl/int.hpp"
 
 28  #include "boost/function.hpp"
 
 29  #include "boost/utility/addressof.hpp"
 
 30  #include "boost/type_traits/is_same.hpp"
 
 31  #include "boost/python/object/class_detail.hpp"
 
 32  
 
 33  namespace pyplusplus{ namespace call_policies{
 
 34  
 
 35  namespace bpl = boost::python;
 
 36  
 
 37  namespace memory_managers{
 
 38  
 
 39      struct none{
 
 40          template< typename T>
 
 41          static void deallocate_array(T*){}
 
 42      };
 
 43  
 
 44      struct delete_{
 
 45          template< typename T>
 
 46          static void deallocate_array(T* arr){
 
 47              delete[] arr;
 
 48          }
 
 49      };
 
 50  
 
 51  }/*memory_managers*/
 
 52  
 
 53  
 
 54  namespace detail{
 
 55  
 
 56  struct make_value_holder{
 
 57  
 
 58      template <class T>
 
 59      static PyObject* execute(T* p){
 
 60          if (p == 0){
 
 61              return bpl::detail::none();
 
 62          }
 
 63          else{
 
 64              bpl::object p_value( *p );
 
 65              return bpl::incref( p_value.ptr() );
 
 66          }
 
 67      }
 
 68  };
 
 69  
 
 70  template <class R>
 
 71  struct return_pointee_value_requires_a_pointer_return_type
 
 72  # if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
 
 73  {}
 
 74  # endif
 
 75  ;
 
 76  
 
 77  struct make_addressof_holder{
 
 78  
 
 79      template <class T>
 
 80      static PyObject* execute(T* p){
 
 81          if (p == 0){
 
 82              return bpl::detail::none();
 
 83          }
 
 84          else{
 
 85              boost::uint32_t addressof_p = reinterpret_cast< boost::uint32_t >( p );
 
 86              bpl::object p_address( addressof_p );
 
 87              return bpl::incref( p_address.ptr() );
 
 88          }
 
 89      }
 
 90  
 
 91  };
 
 92  
 
 93  template <class R>
 
 94  struct return_addressof_value_requires_a_pointer_return_type
 
 95  # if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
 
 96  {}
 
 97  # endif
 
 98  ;
 
 99  
 
100  
 
101  } //detail
 
102  
 
103  struct return_pointee_value{
 
104  
 
105      template <class T>
 
106      struct apply{
 
107  
 
108          BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value );
 
109  
 
110          typedef typename boost::mpl::if_c<
 
111              ok
 
112              , bpl::to_python_indirect<T, detail::make_value_holder>
 
113              , detail::return_pointee_value_requires_a_pointer_return_type<T>
 
114          >::type type;
 
115  
 
116      };
 
117  
 
118  };
 
119  
 
120  struct return_addressof{
 
121  
 
122      template <class T>
 
123      struct apply{
 
124  
 
125          BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value );
 
126  
 
127          typedef typename boost::mpl::if_c<
 
128              ok
 
129              , bpl::to_python_indirect<T, detail::make_addressof_holder>
 
130              , detail::return_addressof_value_requires_a_pointer_return_type<T>
 
131          >::type type;
 
132  
 
133      };
 
134  
 
135  };
 
136  
 
137  template< typename CallPolicies, class T >
 
138  bpl::object make_object( T x ){
 
139      //constructs object using CallPolicies result_converter
 
140      typedef BOOST_DEDUCED_TYPENAME CallPolicies::result_converter:: template apply< T >::type result_converter_t;
 
141      result_converter_t rc;
 
142      return bpl::object( bpl::handle<>( rc( x ) ) );
 
143  }
 
144  
 
145  namespace arrays{
 
146  
 
147  namespace details{
 
148  
 
149  template< unsigned int size, typename MemoryManager, typename CallPolicies>
 
150  struct as_tuple_impl{
 
151  
 
152      template <class U>
 
153      inline PyObject* operator()(U const* arr) const{
 
154          if( !arr ){
 
155              return bpl::incref( bpl::tuple().ptr() );
 
156          }
 
157          bpl::list list_;
 
158          for( unsigned int i = 0; i < size; ++i ){
 
159              list_.append( make_object< CallPolicies>( arr[i] ) );
 
160          }
 
161          MemoryManager::deallocate_array( arr );
 
162          return bpl::incref( bpl::tuple( list_ ).ptr() );
 
163      }
 
164  };
 
165  
 
166  }
 
167  
 
168  template< unsigned int size, typename MemoryManager, typename MakeObjectCallPolicies=bpl::default_call_policies>
 
169  struct as_tuple{
 
170  public:
 
171  
 
172      template <class T>
 
173      struct apply{
 
174          BOOST_STATIC_CONSTANT( bool, ok = boost::is_pointer<T>::value );
 
175          typedef details::as_tuple_impl<size, MemoryManager, MakeObjectCallPolicies> type;
 
176      };
 
177  
 
178  };
 
179  
 
180  } /*arrays*/
 
181  
 
182  } /*pyplusplus*/ } /*call_policies*/
 
183  
 
184  
 
185  #endif//call_policies_pyplusplus_hpp__
 
186  
 
187  """ 
188