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