pyplusplus.code_repository.call_policies

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