Package pyplusplus :: Package module_creator :: Module call_policies_resolver

# Source Code for Module pyplusplus.module_creator.call_policies_resolver

      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  import opaque_types_manager
      7  from pygccxml import declarations
      8  from pyplusplus import decl_wrappers
      9  from pyplusplus import code_creators
     10  from pyplusplus.decl_wrappers import python_traits
     11
     12  #TODO: add opaque to documentation
     13
     14 -class resolver_t( object ):
     15 -    def __init__( self ):
     16          object.__init__( self )
     17
     18 -    def __call__(self, decl, hint=None):
     19          raise NotImplementedError()
     20
     21 -class default_policy_resolver_t(resolver_t):
     22 -    def __init__( self ):
     23          resolver_t.__init__( self )
     24          self.__const_char_pointer \
     25              = declarations.pointer_t( declarations.const_t( declarations.char_t() ) )
     26
     27 -    def _resolve_by_type( self, some_type ):
     28          temp_type = declarations.remove_alias( some_type )
     29          temp_type = declarations.remove_cv( temp_type )
     30          if isinstance( temp_type, declarations.fundamental_t ) \
     31             or isinstance( temp_type, declarations.declarated_t ):
     32              return decl_wrappers.default_call_policies()
     33          if declarations.is_same( some_type, self.__const_char_pointer ):
     34              return decl_wrappers.default_call_policies()
     35          return None
     36
     37 -    def __call__(self, calldef, hint=None):
     38          if not isinstance( calldef, declarations.calldef_t ):
     39              return None
     40
     41          if not isinstance( calldef, declarations.constructor_t ):
     42              return self._resolve_by_type( calldef.return_type )
     43          else:
     44              for arg in calldef.arguments:
     45                  if not self._resolve_by_type( arg.type ):
     46                      return None
     47              return decl_wrappers.default_call_policies()
     48
     49 -class void_pointer_resolver_t(resolver_t):
     50 -    def __init__( self ):
     51          resolver_t.__init__( self )
     52
     53 -    def __call__( self, calldef, hint=None ):
     54          if not isinstance( calldef, declarations.calldef_t ):
     55              return None
     56
     57          if isinstance( calldef, declarations.constructor_t ):
     58              return None
     59          return_type = declarations.remove_alias( calldef.return_type )
     60          void_ptr = declarations.pointer_t( declarations.void_t() )
     61          const_void_ptr = declarations.pointer_t( declarations.const_t( declarations.void_t() ) )
     62          if declarations.is_same( return_type, void_ptr ) \
     63             or declarations.is_same( return_type, const_void_ptr ):
     64              return decl_wrappers.return_value_policy( decl_wrappers.return_opaque_pointer )
     65          return None
     66
     67 -class return_value_policy_resolver_t(resolver_t):
     68 -    def __init__( self ):
     69          resolver_t.__init__( self )
     70          self.__const_wchar_pointer \
     71              = declarations.pointer_t( declarations.const_t( declarations.wchar_t() ) )
     72
     73 -    def __call__(self, calldef, hint=None):
     74          if not isinstance( calldef, declarations.calldef_t ):
     75              return None
     76
     77          if isinstance( calldef, declarations.constructor_t ):
     78              return None
     79
     80          return_type = declarations.remove_alias( calldef.return_type )
     81          if isinstance( return_type, declarations.reference_t ) \
     82             and isinstance( return_type.base, declarations.const_t ):
     83              return decl_wrappers.return_value_policy( decl_wrappers.copy_const_reference )
     84
     85          if declarations.is_same( return_type, self.__const_wchar_pointer ):
     86              return decl_wrappers.return_value_policy( decl_wrappers.return_by_value )
     87
     88          if opaque_types_manager.find_out_opaque_decl( return_type, ensure_opaque_decl=True ):
     89              return decl_wrappers.return_value_policy( decl_wrappers.return_opaque_pointer )
     90
     91          return None
     92
     93 -class return_internal_reference_resolver_t( resolver_t ):
     94 -    def __init__( self ):
     95          resolver_t.__init__( self )
     96
     97 -    def __call__(self, calldef, hint=None):
     98          if not isinstance( calldef, declarations.calldef_t ):
     99              return None
    100
    101          if not isinstance( calldef, declarations.member_operator_t ):
    102              return None
    103
    104          if calldef.symbol != '[]':
    105              return None
    106
    107          return_type = declarations.remove_cv( calldef.return_type )
    108          if declarations.is_reference( return_type ):
    109              return_type = declarations.remove_reference( return_type )
    110          if python_traits.is_immutable( return_type ):
    111              if declarations.is_const( calldef.return_type ):
    112                  return decl_wrappers.return_value_policy( decl_wrappers.copy_const_reference )
    113              else:
    114                  return decl_wrappers.return_value_policy( decl_wrappers.copy_non_const_reference )
    115          else:
    116              return decl_wrappers.return_internal_reference()
    117
    118 -class return_self_resolver_t( resolver_t ):
    119 -    def __init__( self ):
    120          resolver_t.__init__( self )
    121
    122 -    def __call__(self, calldef, hint=None):
    123          if not isinstance( calldef, declarations.member_operator_t ):
    124              return None
    125
    126          if calldef.symbol != '=':
    127              return None
    128
    129          return decl_wrappers.return_self()
    130
    131 -class variable_accessors_resolver_t( resolver_t ):
    132 -    def __init__( self ):
    133          resolver_t.__init__( self )
    134
    135 -    def __call__( self, variable, hint=None ):
    136          if not isinstance( variable, declarations.variable_t ):
    137              return None
    138
    139          assert hint in ( 'get', 'set' )
    140
    141          if not declarations.is_reference( variable.type ):
    142              return None
    143
    144          no_ref = declarations.remove_reference( variable.type )
    145          base_type = declarations.remove_const( no_ref )
    146          if python_traits.is_immutable( base_type ):
    147              #the relevant code creator will generate code, that will return this member variable
    148              #by value
    149              return decl_wrappers.default_call_policies()
    150
    151          if not isinstance( base_type, declarations.declarated_t ):
    152              return None
    153
    154          base_type = declarations.remove_alias( base_type )
    155          decl = base_type.declaration
    156
    157          if declarations.is_class_declaration( decl ):
    158              return None
    159
    160          if decl.is_abstract:
    161              return None
    162          if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ):
    163              return None
    164          if not declarations.has_copy_constructor(decl):
    165              return None
    166          if hint == 'get':
    167              #if we rich this line, it means that we are able to create an obect using
    168              #copy constructor.
    169              if declarations.is_const( no_ref ):
    170                  return decl_wrappers.return_value_policy( decl_wrappers.copy_const_reference )
    171              else:
    172                  return decl_wrappers.return_value_policy( decl_wrappers.copy_non_const_reference )
    173          else:
    174              return decl_wrappers.default_call_policies()
    175
    176 -class built_in_resolver_t(resolver_t):
    177 -    def __init__( self, config=None):
    178          resolver_t.__init__( self )
    179          self.__resolvers = [ default_policy_resolver_t()
    180                               , return_value_policy_resolver_t() ]
    181          assert not config or isinstance( config, code_creators.target_configuration_t )
    182          if not config or config.boost_python_supports_void_ptr:
    183              self.__resolvers.append( void_pointer_resolver_t() )
    184          self.__resolvers.append( return_internal_reference_resolver_t() )
    185          self.__resolvers.append( variable_accessors_resolver_t() )
    186          self.__resolvers.append( return_self_resolver_t() )
    187
    188 -    def __call__( self, calldef, hint=None ):
    189          for resolver in self.__resolvers:
    190              resolved = resolver( calldef, hint )
    191              if resolved:
    192                  return resolved
    193          return None
    194