Package pyplusplus :: Package code_creators :: Module calldef |

# Source Code for Module pyplusplus.code_creators.calldef

       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 os
       7  import algorithm
       8  import code_creator
       9  import calldef_utils
      10  import declaration_based
      11  import registration_based
      12  import class_declaration
      13  from pygccxml import declarations
      14  from pyplusplus import decl_wrappers
      15
      16  #TODO:
      17  #Add to docs:
      18  #public memebr functions - call, override, call base implementation
      19  #protected member functions - call, override
      20  #private - override
      21
      22 -class calldef_t( registration_based.registration_based_t
      23                   , declaration_based.declaration_based_t ):
      24 -    def __init__(self, function, wrapper=None ):
      25          registration_based.registration_based_t.__init__( self )
      26          declaration_based.declaration_based_t.__init__( self, declaration=function )
      27          self._wrapper = wrapper
      28          self._associated_decl_creators = []
      29
      30      @property
      31 -    def associated_decl_creators( self ):
      32          """ references to declaration code creators. """
      33          return self._associated_decl_creators
      34
      35 -    def _get_wrapper( self ):
      36          return self._wrapper
      37 -    def _set_wrapper( self, new_wrapper ):
      38          self._wrapper = new_wrapper
      39      wrapper = property( _get_wrapper, _set_wrapper )
      40
      41 -    def def_identifier( self ):
      42          return algorithm.create_identifier( self, '::boost::python::def' )
      43
      44 -    def pure_virtual_identifier( self ):
      45          return algorithm.create_identifier( self, '::boost::python::pure_virtual' )
      46
      47 -    def param_sep(self):
      48          return os.linesep + self.indent( self.PARAM_SEPARATOR )
      49
      50 -    def create_keywords_args(self):
      51          arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) )
      52          return arg_utils.keywords_args()
      53
      54 -    def create_call_policies( self, default_generates_code_too=False ):
      55          if False == default_generates_code_too \
      56             and self.declaration.call_policies.is_default():
      57              return ''
      58          else:
      59              return self.declaration.call_policies.create( self )
      60
      61 -    def create_def_code( self ):
      62          if not self.works_on_instance:
      63              return '%s.def' % self.parent.class_var_name
      64          else:
      65              return 'def'
      66
      67 -    def create_doc(self):
      68          return self.documentation
      69
      70 -    def create_function_ref_code( self, use_function_alias=False ):
      71          raise NotImplementedError()
      72
      73 -    def _get_function_type_alias( self ):
      74          return self.alias + '_function_type'
      75      function_type_alias = property( _get_function_type_alias )
      76
      77 -    def _get_exported_class_alias( self ):
      78          return 'exported_class_t'
      79      exported_class_alias = property( _get_exported_class_alias )
      80
      81 -    def create_function_type_alias_code( self, exported_class_alias=None ):
      82          raise NotImplementedError()
      83
      84 -    def _create_impl( self ):
      85          if self.declaration.already_exposed:
      86              return ''
      87
      88          result = []
      89
      90          if not self.works_on_instance:
      91              exported_class_alias = None
      92              if declarations.templates.is_instantiation( self.declaration.parent.name ):
      93                  exported_class_alias = self.exported_class_alias
      94                  result.append( 'typedef %s %s;' % ( self.parent.decl_identifier, exported_class_alias ) )
      95                  result.append( os.linesep )
      96              result.append( self.create_function_type_alias_code(exported_class_alias) )
      97              result.append( os.linesep * 2 )
      98
      99          result.append( self.create_def_code() + '( ' )
     100          result.append( os.linesep + self.indent( '"%s"' % self.alias ) )
     101
     102          result.append( self.param_sep() )
     103          result.append( self.create_function_ref_code( not self.works_on_instance ) )
     104
     105          if self.declaration.use_keywords:
     106              keywd_args = self.create_keywords_args()
     107              if keywd_args:
     108                  result.append( self.param_sep() )
     109                  result.append( keywd_args )
     110
     111          if self.declaration.call_policies:
     112              c_p_code = self.create_call_policies()
     113              if c_p_code:
     114                  result.append( self.param_sep() )
     115                  result.append( c_p_code )
     116          else:
     117              result.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) )
     118
     119          doc = self.create_doc()
     120          if doc:
     121              result.append( self.param_sep() )
     122              result.append( doc )
     123
     124          result.append( ' )' )
     125          if not self.works_on_instance:
     126              result.append( ';' )
     127
     128          if not self.works_on_instance:
     129              #indenting and adding scope
     130              code = ''.join( result )
     131              result = [ '{ //%s' % declarations.full_name( self.declaration, with_defaults=False ) ]
     132              result.append( os.linesep * 2 )
     133              result.append( self.indent( code ) )
     134              result.append( os.linesep * 2 )
     135              result.append( '}' )
     136
     137          return ''.join( result )
     138
     139 -    def _get_system_headers_impl( self ):
     140          files = []
     141          if self.declaration.call_policies:
     142              files.append( self.declaration.call_policies.header_file )
     143          return files
     144
     145 -class calldef_wrapper_t( code_creator.code_creator_t
     146                           , declaration_based.declaration_based_t):
     147 -    def __init__(self, function ):
     148          code_creator.code_creator_t.__init__( self )
     149          declaration_based.declaration_based_t.__init__( self, declaration=function )
     150
     151 -    def override_identifier(self):
     152          return algorithm.create_identifier( self, '::boost::python::override' )
     153
     154 -    def function_call_args( self ):
     155          arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) )
     156          return arg_utils.call_args()
     157
     158 -    def args_declaration( self ):
     159          arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) )
     160          return arg_utils.args_declaration()
     161
     162 -    def wrapped_class_identifier( self ):
     163          return algorithm.create_identifier( self, self.declaration.parent.partial_decl_string )
     164
     165 -    def unoverriden_function_body( self ):
     166          return 'throw std::logic_error("%s");' % self.declaration.non_overridable_reason
     167
     168 -    def throw_specifier_code( self ):
     169          if self.declaration.does_throw:
     170              if not self.declaration.exceptions:
     171                  return ''
     172              else:
     173                  exceptions = map( lambda exception: algorithm.create_identifier( self, exception.partial_decl_string )
     174                                    , self.declaration.exceptions )
     175                  return ' throw( ' + self.PARAM_SEPARATOR.join( exceptions ) + ' )'
     176          else:
     177              return ' throw()'
     178
     179 -    def _get_system_headers_impl( self ):
     180          files = []
     181          if self.declaration.transformations:
     182              ft = self.declaration.transformations[0]
     183              files.extend( ft.required_headers() )
     184          if self.declaration.call_policies:
     185              files.append( self.declaration.call_policies.header_file )
     186          return files
     187
     188 -class free_function_t( calldef_t ):
     189 -    def __init__( self, function ):
     190          calldef_t.__init__( self, function=function )
     191          self.works_on_instance = False
     192
     193 -    def create_def_code( self ):
     194          return self.def_identifier()
     195
     196 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     197          f_type = self.declaration.function_type()
     198          return 'typedef ' + f_type.create_typedef( self.function_type_alias, with_defaults=False ) + ';'
     199
     200 -    def create_function_ref_code(self, use_function_alias=False):
     201          fname = declarations.full_name( self.declaration, with_defaults=False )
     202          if use_function_alias:
     203              return '%s( &%s )' % ( self.function_type_alias, fname )
     204          elif self.declaration.create_with_signature:
     205              return '(%s)( &%s )' % ( self.declaration.function_type().partial_decl_string, fname )
     206          else:
     207              return '&%s' % fname
     208
     209 -class mem_fun_t( calldef_t ):
     210 -    def __init__( self, function ):
     211          calldef_t.__init__( self, function=function )
     212
     213 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     214          ftype = self.declaration.function_type()
     215          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias, with_defaults=False )
     216
     217 -    def create_function_ref_code(self, use_function_alias=False):
     218          fname = declarations.full_name( self.declaration, with_defaults=False )
     219          if use_function_alias:
     220              return '%s( &%s )' % ( self.function_type_alias, fname )
     221          elif self.declaration.create_with_signature:
     222              return '(%s)( &%s )' % ( self.declaration.function_type().partial_decl_string, fname )
     223          else:
     224              return '&%s' % fname
     225
     226 -class make_constructor_t( calldef_t ):
     227 -    def __init__( self, function ):
     228          calldef_t.__init__( self, function=function )
     229
     230 -    def make_cnstr_identifier( self ):
     231          return algorithm.create_identifier( self, '::boost::python::make_constructor' )
     232
     233 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     234          ftype = self.declaration.function_type()
     235          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias, with_defaults=False )
     236
     237 -    def create_function_ref_code(self, use_function_alias=False):
     238          fname = declarations.full_name( self.declaration, with_defaults=False )
     239          if use_function_alias:
     240              return '%s( &%s )' % ( self.function_type_alias, fname )
     241          elif self.declaration.create_with_signature:
     242              return '(%s)( &%s )' % ( self.declaration.function_type().partial_decl_string, fname )
     243          else:
     244              return '&%s' % fname
     245
     246 -    def _create_impl( self ):
     247          if self.declaration.already_exposed:
     248              return ''
     249
     250          result = []
     251
     252          if not self.works_on_instance:
     253              result.append( self.create_function_type_alias_code() )
     254              result.append( os.linesep * 2 )
     255
     256          result.append( self.create_def_code() + '( ' )
     257          result.append( os.linesep + self.indent( '"__init__"' ) )
     258
     259          result.append( self.param_sep() )
     260          result.append( self.make_cnstr_identifier()  + '( ')
     261          result.append( self.create_function_ref_code( not self.works_on_instance ) )
     262
     263          keywd_args = None
     264          if self.declaration.use_keywords:
     265              keywd_args = self.create_keywords_args()
     266
     267          if self.declaration.call_policies:
     268              default_generates_code_too = bool( keywd_args )
     269              c_p_code = self.create_call_policies( default_generates_code_too )
     270              if c_p_code:
     271                  result.append( self.indent( self.param_sep(), 3 ) )
     272                  result.append( c_p_code )
     273
     274          if keywd_args:
     275              result.append( self.indent( self.param_sep(), 3 ) )
     276              result.append( keywd_args )
     277
     278          result.append( ' )' ) #make_constructor
     279
     280          doc = self.create_doc()
     281          if doc:
     282              result.append( self.param_sep() )
     283              result.append( doc )
     284
     285          result.append( ' )' )
     286          if not self.works_on_instance:
     287              result.append( ';' )
     288
     289          if not self.works_on_instance:
     290              #indenting and adding scope
     291              code = ''.join( result )
     292              result = [ '{ //%s' % declarations.full_name( self.declaration, with_defaults=False ) ]
     293              result.append( os.linesep * 2 )
     294              result.append( self.indent( code ) )
     295              result.append( os.linesep * 2 )
     296              result.append( '}' )
     297
     298          return ''.join( result )
     299
     300
     301 -class mem_fun_pv_t( calldef_t ):
     302 -    def __init__( self, function, wrapper ):
     303          calldef_t.__init__( self, function=function, wrapper=wrapper )
     304
     305 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     306          ftype = self.declaration.function_type()
     307          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias )
     308
     309 -    def create_function_ref_code(self, use_function_alias=False):
     310          fname = declarations.full_name( self.declaration, with_defaults=False )
     311          if use_function_alias:
     312              return '%s( %s(&%s) )' \
     313                     % ( self.pure_virtual_identifier()
     314                         , self.function_type_alias
     315                         , fname )
     316          elif self.declaration.create_with_signature:
     317              return '%s( (%s)(&%s) )' \
     318                     % ( self.pure_virtual_identifier()
     319                         , self.declaration.function_type().partial_decl_string
     320                         , fname )
     321          else:
     322              return '%s( &%s )' % ( self.pure_virtual_identifier(), fname)
     323
     324 -class mem_fun_pv_wrapper_t( calldef_wrapper_t ):
     325 -    def __init__( self, function ):
     326          calldef_wrapper_t.__init__( self, function=function )
     327
     328 -    def create_declaration(self):
     329          template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s%(throw)s'
     330
     331          constness = ''
     332          if self.declaration.has_const:
     333              constness = ' const '
     334
     335          return template % {
     336              'return_type' : self.declaration.return_type.partial_decl_string
     337              , 'name' : self.declaration.name
     338              , 'args' : self.args_declaration()
     339              , 'constness' : constness
     340              , 'throw' : self.throw_specifier_code()
     341          }
     342
     343 -    def create_body( self ):
     344          auto_ptr_traits = declarations.auto_ptr_traits
     345          if not self.declaration.overridable:
     346              return self.unoverriden_function_body()
     347          template = []
     348          precall_code = self.declaration.override_precall_code
     349          if precall_code:
     350              template.append( os.linesep.join( precall_code ) )
     351          template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' )
     352          if self.declaration.return_type \
     353             and auto_ptr_traits.is_smart_pointer( self.declaration.return_type ):
     354              template.append( 'boost::python::object %(alias)s_result = func_%(alias)s( %(args)s );' )
     355              template.append( 'return boost::python::extract< %(return_type)s >( %(alias)s_result );' )
     356          else:
     357              template.append( '%(return_)sfunc_%(alias)s( %(args)s );')
     358          template = os.linesep.join( template )
     359
     360          return_ = ''
     361          if not declarations.is_void( self.declaration.return_type ):
     362              return_ = 'return '
     363
     364          return_type = ''
     365          if self.declaration.return_type:
     366             return_type = self.declaration.return_type.decl_string
     367
     368          return template % {
     369              'override' : self.override_identifier()
     370              , 'alias' : self.declaration.alias
     371              , 'return_' : return_
     372              , 'args' : self.function_call_args()
     373              , 'return_type' : return_type
     374          }
     375
     376 -    def _create_impl(self):
     377          answer = [ self.create_declaration() + '{' ]
     378          answer.append( self.indent( self.create_body() ) )
     379          answer.append( '}' )
     380          return os.linesep.join( answer )
     381
     382 -class mem_fun_v_t( calldef_t ):
     383 -    def __init__( self, function, wrapper=None ):
     384          calldef_t.__init__( self, function=function, wrapper=wrapper )
     385          self.default_function_type_alias = 'default_' + self.function_type_alias
     386
     387 -    def create_function_type_alias_code( self, exported_class_alias=None ):
     388          result = []
     389
     390          ftype = self.declaration.function_type()
     391          result.append( 'typedef %s;'
     392                         % ftype.create_typedef( self.function_type_alias
     393                                                 , exported_class_alias
     394                                                 , with_defaults=False)  )
     395          if self.wrapper:
     396              result.append( os.linesep )
     397              ftype = self.wrapper.function_type()
     398              result.append( 'typedef %s;'
     399                             % ftype.create_typedef( self.default_function_type_alias
     400                                                     , with_defaults=False) )
     401          return ''.join( result )
     402
     403 -    def create_doc(self):
     404          return None
     405
     406 -    def create_function_ref_code(self, use_function_alias=False):
     407          fname = declarations.full_name( self.declaration, with_defaults=False )
     408          result = []
     409          if use_function_alias:
     410              result.append( '%s(&%s)' % ( self.function_type_alias, fname) )
     411              if self.wrapper:
     412                  result.append( self.param_sep() )
     413                  result.append( '%s(&%s)'
     414                                  % ( self.default_function_type_alias, self.wrapper.default_full_name() ) )
     415          elif self.declaration.create_with_signature:
     416              result.append( '(%s)(&%s)'
     417                             % ( self.declaration.function_type().partial_decl_string
     418                                 , fname) )
     419              if self.wrapper:
     420                  result.append( self.param_sep() )
     421                  result.append( '(%s)(&%s)'
     422                                 % ( self.wrapper.function_type().partial_decl_string
     423                                     , self.wrapper.default_full_name() ) )
     424          else:
     425              result.append( '&%s'% fname )
     426              if self.wrapper:
     427                  result.append( self.param_sep() )
     428                  result.append( '&%s' % self.wrapper.default_full_name() )
     429          return ''.join( result )
     430
     431 -class mem_fun_v_wrapper_t( calldef_wrapper_t ):
     432 -    def __init__( self, function ):
     433          calldef_wrapper_t.__init__( self, function=function )
     434
     435 -    def default_full_name(self):
     436          return self.parent.full_name + '::default_' + self.declaration.alias
     437
     438 -    def function_type(self):
     439          return declarations.member_function_type_t(
     440                  return_type=self.declaration.return_type
     441                  , class_inst=declarations.dummy_type_t( self.parent.full_name )
     442                  , arguments_types=map( lambda arg: arg.type, self.declaration.arguments )
     443                  , has_const=self.declaration.has_const )
     444
     445 -    def create_declaration(self, name, has_virtual=True):
     446          template = '%(virtual)s%(return_type)s %(name)s( %(args)s )%(constness)s %(throw)s'
     447
     448          virtual = 'virtual '
     449          if not has_virtual:
     450              virtual = ''
     451
     452          constness = ''
     453          if self.declaration.has_const:
     454              constness = ' const '
     455
     456          return template % {
     457              'virtual' : virtual
     458              , 'return_type' : self.declaration.return_type.partial_decl_string
     459              , 'name' : name
     460              , 'args' : self.args_declaration()
     461              , 'constness' : constness
     462              , 'throw' : self.throw_specifier_code()
     463          }
     464
     465 -    def create_virtual_body(self):
     466          template = []
     467          precall_code = self.declaration.override_precall_code
     468          if precall_code:
     469              template.append( os.linesep.join( precall_code ) )
     470          template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' )
     471          template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') )
     472          template.append( 'else' )
     473          template.append( self.indent('%(return_)sthis->%(wrapped_class)s::%(name)s( %(args)s );') )
     474          template = os.linesep.join( template )
     475
     476          return_ = ''
     477          if not declarations.is_void( self.declaration.return_type ):
     478              return_ = 'return '
     479
     480          return template % {
     481              'override' : self.override_identifier()
     482              , 'name' : self.declaration.partial_name
     483              , 'alias' : self.declaration.alias
     484              , 'return_' : return_
     485              , 'args' : self.function_call_args()
     486              , 'wrapped_class' : self.wrapped_class_identifier()
     487          }
     488
     489 -    def create_default_body(self):
     490          function_call = declarations.call_invocation.join( self.declaration.partial_name
     491                                                             , [ self.function_call_args() ] )
     492          body = self.wrapped_class_identifier() + '::' + function_call + ';'
     493          if not declarations.is_void( self.declaration.return_type ):
     494              body = 'return ' + body
     495          precall_code = self.declaration.default_precall_code
     496          if precall_code:
     497              body = os.linesep.join( precall_code ) + os.linesep + body
     498          return body
     499
     500
     501 -    def create_function(self):
     502          answer = [ self.create_declaration(self.declaration.partial_name) + '{' ]
     503          answer.append( self.indent( self.create_virtual_body() ) )
     504          answer.append( '}' )
     505          return os.linesep.join( answer )
     506
     507 -    def create_default_function( self ):
     508          answer = [ self.create_declaration('default_' + self.declaration.alias, False) + '{' ]
     509          answer.append( self.indent( self.create_default_body() ) )
     510          answer.append( '}' )
     511          return os.linesep.join( answer )
     512
     513 -    def _create_impl(self):
     514          answer = [ self.create_function() ]
     515          answer.append( os.linesep )
     516          answer.append( self.create_default_function() )
     517          return os.linesep.join( answer )
     518
     519
     520 -class mem_fun_protected_t( calldef_t ):
     521 -    def __init__( self, function, wrapper ):
     522          calldef_t.__init__( self, function=function, wrapper=wrapper )
     523
     524 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     525          ftype = self.wrapper.function_type()
     526          return 'typedef ' + ftype.create_typedef( self.function_type_alias, with_defaults=False ) + ';'
     527
     528 -    def create_function_ref_code(self, use_function_alias=False):
     529          if use_function_alias:
     530              return '%s( &%s )' \
     531                     % ( self.function_type_alias, self.wrapper.full_name() )
     532          elif self.declaration.create_with_signature:
     533              return '(%s)(&%s)' \
     534                     % ( self.wrapper.function_type().decl_string, self.wrapper.full_name() )
     535          else:
     536              return '&%s' % self.wrapper.full_name()
     537
     538 -class mem_fun_protected_wrapper_t( calldef_wrapper_t ):
     539 -    def __init__( self, function ):
     540          calldef_wrapper_t.__init__( self, function=function )
     541
     542 -    def full_name(self):
     543          return '::'.join( [self.parent.full_name, self.declaration.partial_name] )
     544
     545 -    def function_type(self):
     546          return declarations.member_function_type_t(
     547                  return_type=self.declaration.return_type
     548                  , class_inst=declarations.dummy_type_t( self.parent.full_name )
     549                  , arguments_types=map( lambda arg: arg.type, self.declaration.arguments )
     550                  , has_const=self.declaration.has_const )
     551
     552 -    def create_declaration(self, name):
     553          template = '%(return_type)s %(name)s( %(args)s )%(constness)s%(throw)s'
     554
     555          constness = ''
     556          if self.declaration.has_const:
     557              constness = ' const '
     558
     559          return template % {
     560              'return_type' : self.declaration.return_type.partial_decl_string
     561              , 'name' : name
     562              , 'args' : self.args_declaration()
     563              , 'constness' : constness
     564              , 'throw' : self.throw_specifier_code()
     565          }
     566
     567 -    def create_body(self):
     568          tmpl = '%(return_)s%(wrapped_class)s::%(name)s( %(args)s );'
     569
     570          return_ = ''
     571          if not declarations.is_void( self.declaration.return_type ):
     572              return_ = 'return '
     573
     574          return tmpl % {
     575              'name' : self.declaration.partial_name
     576              , 'return_' : return_
     577              , 'args' : self.function_call_args()
     578              , 'wrapped_class' : self.wrapped_class_identifier()
     579          }
     580
     581 -    def create_function(self):
     582          answer = [ self.create_declaration(self.declaration.partial_name) + '{' ]
     583          answer.append( self.indent( self.create_body() ) )
     584          answer.append( '}' )
     585          return os.linesep.join( answer )
     586
     587 -    def _create_impl(self):
     588          return self.create_function()
     589
     590
     591
     592 -class mem_fun_protected_s_t( calldef_t ):
     593 -    def __init__( self, function, wrapper ):
     594          calldef_t.__init__( self, function=function, wrapper=wrapper )
     595
     596 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     597          ftype = self.wrapper.function_type()
     598          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, with_defaults=False )
     599
     600 -    def create_function_ref_code(self, use_function_alias=False):
     601          if use_function_alias:
     602              return '%s( &%s )' \
     603                     % ( self.function_type_alias, self.wrapper.full_name() )
     604          elif self.declaration.create_with_signature:
     605              return '(%s)(&%s)' \
     606                     % ( self.wrapper.function_type().partial_decl_string, self.wrapper.full_name() )
     607          else:
     608              return '&%s' % self.wrapper.full_name()
     609
     610 -class mem_fun_protected_s_wrapper_t( calldef_wrapper_t ):
     611 -    def __init__( self, function ):
     612          calldef_wrapper_t.__init__( self, function=function )
     613
     614 -    def full_name(self):
     615          return '::'.join( [self.parent.full_name, self.declaration.name] )
     616
     617 -    def function_type(self):
     618          return declarations.free_function_type_t(
     619                  return_type=self.declaration.return_type
     620                  , arguments_types=map( lambda arg: arg.type, self.declaration.arguments ) )
     621
     622 -    def create_declaration(self, name):
     623          template = 'static %(return_type)s %(name)s( %(args)s )%(throw)s'
     624
     625          return template % {
     626              'return_type' : self.declaration.return_type.partial_decl_string
     627              , 'name' : name
     628              , 'args' : self.args_declaration()
     629              , 'throw' : self.throw_specifier_code()
     630          }
     631
     632 -    def create_body(self):
     633          tmpl = '%(return_)s%(wrapped_class)s::%(name)s( %(args)s );'
     634
     635          return_ = ''
     636          if not declarations.is_void( self.declaration.return_type ):
     637              return_ = 'return '
     638
     639          return tmpl % {
     640              'name' : self.declaration.name
     641              , 'return_' : return_
     642              , 'args' : self.function_call_args()
     643              , 'wrapped_class' : self.wrapped_class_identifier()
     644          }
     645
     646 -    def create_function(self):
     647          answer = [ self.create_declaration(self.declaration.name) + '{' ]
     648          answer.append( self.indent( self.create_body() ) )
     649          answer.append( '}' )
     650          return os.linesep.join( answer )
     651
     652 -    def _create_impl(self):
     653          return self.create_function()
     654
     655 -class mem_fun_protected_v_t( calldef_t ):
     656 -    def __init__( self, function, wrapper ):
     657          calldef_t.__init__( self, function=function, wrapper=wrapper )
     658
     659 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     660          ftype = self.wrapper.function_type()
     661          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, with_defaults=False )
     662
     663 -    def create_function_ref_code(self, use_function_alias=False):
     664          if use_function_alias:
     665              return '%s( &%s )' \
     666                     % ( self.function_type_alias, self.wrapper.full_name() )
     667          elif self.declaration.create_with_signature:
     668              return '(%s)(&%s)' \
     669                     % ( self.wrapper.function_type().partial_decl_string, self.wrapper.full_name() )
     670          else:
     671              return '&%s' % self.wrapper.full_name()
     672
     673 -class mem_fun_protected_v_wrapper_t( calldef_wrapper_t ):
     674 -    def __init__( self, function):
     675          calldef_wrapper_t.__init__( self, function=function )
     676
     677 -    def full_name(self):
     678          return self.parent.full_name + '::' + self.declaration.name
     679
     680 -    def function_type(self):
     681          return declarations.member_function_type_t(
     682                  return_type=self.declaration.return_type
     683                  , class_inst=declarations.dummy_type_t( self.parent.full_name )
     684                  , arguments_types=map( lambda arg: arg.type, self.declaration.arguments )
     685                  , has_const=self.declaration.has_const )
     686
     687 -    def create_declaration(self, name):
     688          template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s%(throw)s'
     689
     690          constness = ''
     691          if self.declaration.has_const:
     692              constness = ' const '
     693
     694          return template % {
     695              'return_type' : self.declaration.return_type.partial_decl_string
     696              , 'name' : name
     697              , 'args' : self.args_declaration()
     698              , 'constness' : constness
     699              , 'throw' : self.throw_specifier_code()
     700          }
     701
     702 -    def create_virtual_body(self):
     703          template = []
     704
     705          precall_code = self.declaration.override_precall_code
     706          if precall_code:
     707              template.append( os.linesep.join( precall_code ) )
     708
     709          template.append( 'if( %(override)s func_%(alias)s = this->get_override( "%(alias)s" ) )' )
     710          template.append( self.indent('%(return_)sfunc_%(alias)s( %(args)s );') )
     711          template.append( 'else' )
     712          template.append( self.indent('%(return_)sthis->%(wrapped_class)s::%(name)s( %(args)s );') )
     713          template = os.linesep.join( template )
     714
     715          return_ = ''
     716          if not declarations.is_void( self.declaration.return_type ):
     717              return_ = 'return '
     718
     719          return template % {
     720              'override' : self.override_identifier()
     721              , 'name' : self.declaration.partial_name
     722              , 'alias' : self.declaration.alias
     723              , 'return_' : return_
     724              , 'args' : self.function_call_args()
     725              , 'wrapped_class' : self.wrapped_class_identifier()
     726          }
     727
     728 -    def create_function(self):
     729          answer = [ self.create_declaration(self.declaration.partial_name) + '{' ]
     730          answer.append( self.indent( self.create_virtual_body() ) )
     731          answer.append( '}' )
     732          return os.linesep.join( answer )
     733
     734 -    def _create_impl(self):
     735          return self.create_function()
     736
     737 -class mem_fun_protected_pv_t( calldef_t ):
     738 -    def __init__( self, function, wrapper ):
     739          calldef_t.__init__( self, function=function, wrapper=wrapper )
     740
     741 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
     742          ftype = self.wrapper.function_type()
     743          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, with_defaults=False )
     744
     745 -    def create_function_ref_code(self, use_function_alias=False):
     746          if use_function_alias:
     747              return '%s( &%s )' \
     748                     % ( self.function_type_alias, self.wrapper.full_name() )
     749          elif self.declaration.create_with_signature:
     750              return '(%s)(&%s)' \
     751                     % ( self.wrapper.function_type().partial_decl_string, self.wrapper.full_name() )
     752          else:
     753              return '&%s' % self.wrapper.full_name()
     754
     755 -class mem_fun_protected_pv_wrapper_t( calldef_wrapper_t ):
     756 -    def __init__( self, function):
     757          calldef_wrapper_t.__init__( self, function=function )
     758
     759 -    def full_name(self):
     760          return self.parent.full_name + '::' + self.declaration.partial_name
     761
     762 -    def function_type(self):
     763          return declarations.member_function_type_t(
     764                  return_type=self.declaration.return_type
     765                  , class_inst=declarations.dummy_type_t( self.parent.full_name )
     766                  , arguments_types=map( lambda arg: arg.type, self.declaration.arguments )
     767                  , has_const=self.declaration.has_const )
     768
     769 -    def create_declaration(self):
     770          template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s%(throw)s'
     771
     772          constness = ''
     773          if self.declaration.has_const:
     774              constness = ' const '
     775
     776          return template % {
     777              'return_type' : self.declaration.return_type.partial_decl_string
     778              , 'name' : self.declaration.name
     779              , 'args' : self.args_declaration()
     780              , 'constness' : constness
     781              , 'throw' : self.throw_specifier_code()
     782          }
     783
     784 -    def create_body( self ):
     785          if not self.declaration.overridable:
     786              return self.unoverriden_function_body()
     787
     788          template = []
     789
     790          precall_code = self.declaration.override_precall_code
     791          if precall_code:
     792              template.append( os.linesep.join( precall_code ) )
     793
     794          template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' )
     795          template.append( '%(return_)sfunc_%(alias)s( %(args)s );')
     796          template = os.linesep.join( template )
     797
     798          return_ = ''
     799          if not declarations.is_void( self.declaration.return_type ):
     800              return_ = 'return '
     801
     802          return template % {
     803              'override' : self.override_identifier()
     804              , 'alias' : self.declaration.alias
     805              , 'return_' : return_
     806              , 'args' : self.function_call_args()
     807          }
     808
     809 -    def _create_impl(self):
     810          answer = [ self.create_declaration() + '{' ]
     811          answer.append( self.indent( self.create_body() ) )
     812          answer.append( '}' )
     813          return os.linesep.join( answer )
     814
     815 -class mem_fun_private_v_wrapper_t( calldef_wrapper_t ):
     816 -    def __init__( self, function):
     817          calldef_wrapper_t.__init__( self, function=function )
     818
     819 -    def full_name(self):
     820          return self.parent.full_name + '::' + self.declaration.partial_name
     821
     822 -    def function_type(self):
     823          return declarations.member_function_type_t(
     824                  return_type=self.declaration.return_type
     825                  , class_inst=declarations.dummy_type_t( self.parent.full_name )
     826                  , arguments_types=map( lambda arg: arg.type, self.declaration.arguments )
     827                  , has_const=self.declaration.has_const )
     828
     829 -    def create_declaration(self):
     830          template = 'virtual %(return_type)s %(name)s( %(args)s )%(constness)s%(throw)s'
     831
     832          constness = ''
     833          if self.declaration.has_const:
     834              constness = ' const '
     835
     836          return template % {
     837              'return_type' : self.declaration.return_type.partial_decl_string
     838              , 'name' : self.declaration.name
     839              , 'args' : self.args_declaration()
     840              , 'constness' : constness
     841              , 'throw' : self.throw_specifier_code()
     842          }
     843
     844 -    def create_body( self ):
     845          if not self.declaration.overridable:
     846              return self.unoverriden_function_body()
     847
     848          template = []
     849
     850          precall_code = self.declaration.override_precall_code
     851          if precall_code:
     852              template.append( os.linesep.join( precall_code ) )
     853
     854          template.append( '%(override)s func_%(alias)s = this->get_override( "%(alias)s" );' )
     855          template.append( '%(return_)sfunc_%(alias)s( %(args)s );')
     856          template = os.linesep.join( template )
     857
     858          return_ = ''
     859          if not declarations.is_void( self.declaration.return_type ):
     860              return_ = 'return '
     861
     862          return template % {
     863              'override' : self.override_identifier()
     864              , 'alias' : self.declaration.alias
     865              , 'return_' : return_
     866              , 'args' : self.function_call_args()
     867          }
     868
     869 -    def _create_impl(self):
     870          answer = [ self.create_declaration() + '{' ]
     871          answer.append( self.indent( self.create_body() ) )
     872          answer.append( '}' )
     873          return os.linesep.join( answer )
     874
     875  mem_fun_private_pv_wrapper_t = mem_fun_private_v_wrapper_t
     876
     877 -class constructor_t( calldef_t ):
     878      """
     879      Creates boost.python code needed to expose constructor.
     880      """
     881 -    def __init__(self, constructor, wrapper=None ):
     882          calldef_t.__init__( self, function=constructor, wrapper=wrapper )
     883
     884 -    def _create_arg_code( self, arg ):
     885          temp = arg.type
     886          if declarations.is_const( temp ):
     887              #By David Abrahams:
     888              #Function parameters declared consts are ignored by C++
     889              #except for the purpose of function definitions
     890              temp = declarations.remove_const( temp )
     891          return algorithm.create_identifier( self, temp.partial_decl_string )
     892
     893 -    def _generate_definition_args(self):
     894          answer = []
     895          optionals = []
     896          for arg in self.declaration.arguments:
     897              if arg.default_value or optionals:
     898                  optionals.append( self._create_arg_code( arg ) )
     899              else:
     900                  answer.append( self._create_arg_code( arg ) )
     901
     902          optionals_str = ''
     903          if optionals:
     904              optionals_str = algorithm.create_identifier( self, '::boost::python::optional' )
     905              optionals_str = optionals_str + '< ' + ', '.join( optionals ) + ' >'
     906              answer.append( optionals_str )
     907          return ', '.join( answer )
     908
     909 -    def create_init_code(self):
     910          init_identifier = algorithm.create_identifier( self, '::boost::python::init' )
     911          args = [ self._generate_definition_args() ]
     912          answer = [ '%s' % declarations.templates.join( init_identifier, args ) ]
     913          answer.append( '(' )
     914          keywords_args = None
     915          if self.declaration.use_keywords:
     916              keywords_args = self.create_keywords_args()
     917              answer.append( '%s' % keywords_args )
     918          if self.documentation:
     919              if keywords_args:
     920                  answer.append( ', ' )
     921              answer.append( self.documentation )
     922          answer.append( ')' )
     923          if self.declaration.call_policies and not self.declaration.call_policies.is_default():
     924              answer.append('[%s]' % self.declaration.call_policies.create( self ) )
     925          return ''.join( answer )
     926
     927 -    def _create_impl( self ):
     928          code = 'def( %s )' % self.create_init_code()
     929          if not self.works_on_instance:
     930              code = self.parent.class_var_name + '.' + code + ';'
     931          return code
     932
     933 -class static_method_t( declaration_based.declaration_based_t
     934                         , registration_based.registration_based_t ):
     935      """
     936      Creates boost.python code that expose member function as static function.
     937      """
     938 -    def __init__(self, function, function_code_creator=None ):
     939          registration_based.registration_based_t.__init__( self )
     940          declaration_based.declaration_based_t.__init__( self, declaration=function )
     941
     942          self._function_code_creator = function_code_creator
     943
     944 -    def _get_function_code_creator(self):
     945          return self._function_code_creator
     946 -    def _set_function_code_creator(self, new_function_code_creator ):
     947          self._function_code_creator = new_function_code_creator
     948      function_code_creator = property( _get_function_code_creator, _set_function_code_creator )
     949
     950 -    def _create_impl( self ):
     951          return 'staticmethod( "%s" )' % self.function_code_creator.alias
     952
     953 -    def _get_system_headers_impl( self ):
     954          return []
     955
     956 -class constructor_wrapper_t( calldef_wrapper_t ):
     957      """
     958      Creates C++ code that builds wrapper arround exposed constructor.
     959      """
     960
     961 -    def __init__( self, constructor ):
     962          calldef_wrapper_t.__init__( self, function=constructor )
     963
     964 -    def _create_declaration(self):
     965          result = []
     966          result.append( self.parent.wrapper_alias )
     967          result.append( '(' )
     968          args = []
     969          if not self.target_configuration.boost_python_has_wrapper_held_type \
     970             or self.declaration.parent.require_self_reference:
     971              args.append( 'PyObject* self' )
     972          args_decl = self.args_declaration()
     973          if args_decl:
     974              args.append( args_decl )
     975          result.append( ', '.join( args ) )
     976          result.append( ' )' )
     977          return ''.join( result )
     978
     979 -    def _create_constructor_call( self ):
     980          answer = [ algorithm.create_identifier( self, self.parent.declaration.decl_string ) ]
     981          answer.append( '( ' )
     982          arg_utils = calldef_utils.argument_utils_t( self.declaration, algorithm.make_id_creator( self ) )
     983          params = arg_utils.call_args()
     984          answer.append( params )
     985          if params:
     986              answer.append(' ')
     987          answer.append( ')' )
     988          return ''.join( answer )
     989
     990 -    def _create_impl(self):
     991          answer = [ self._create_declaration() ]
     992          answer.append( ': ' + self._create_constructor_call() )
     993          answer.append( '  , ' +  self.parent.boost_wrapper_identifier + '(){' )
     994          if( self.declaration.is_copy_constructor ):
     995              answer.append( self.indent( '// copy constructor' ) )
     996          elif not self.declaration.arguments:
     997              answer.append( self.indent( '// null constructor' ) )
     998          else:
     999              answer.append( self.indent( '// constructor' ) )
    1000          answer.append( self.declaration.body )
    1001          answer.append( '}' )
    1002          return os.linesep.join( answer )
    1003
    1004  #There is something I don't understand
    1005  #There are usecases when boost.python requeres
    1006  #constructor for wrapper class from exposed class
    1007  #I should understand this more
    1008 -class copy_constructor_wrapper_t( code_creator.code_creator_t
    1009                                    , declaration_based.declaration_based_t ):
    1010      """
    1011      Creates wrapper class constructor from wrapped class instance.
    1012      """
    1013 -    def __init__( self, constructor ):
    1014          code_creator.code_creator_t.__init__( self )
    1015          declaration_based.declaration_based_t.__init__( self, declaration=constructor )
    1016
    1017      @property
    1018 -    def parent_class( self ):
    1019          return self.declaration.parent
    1020
    1021 -    def _create_declaration(self):
    1022          result = []
    1023          result.append( self.parent_class.wrapper_alias )
    1024          result.append( '(' )
    1025          if not self.target_configuration.boost_python_has_wrapper_held_type \
    1026             or self.parent_class.require_self_reference:
    1027              result.append( 'PyObject* self, ' )
    1028          declarated = declarations.declarated_t( self.parent_class )
    1029          const_decl = declarations.const_t( declarated )
    1030          const_ref_decl = declarations.reference_t( const_decl )
    1031          identifier = algorithm.create_identifier( self, const_ref_decl.decl_string )
    1032          result.append( identifier + ' arg' )
    1033          result.append( ' )' )
    1034          return ''.join( result )
    1035
    1036 -    def _create_constructor_call( self ):
    1037          answer = [ algorithm.create_identifier( self, self.parent_class.decl_string ) ]
    1038          answer.append( '( arg )' )
    1039          return ''.join( answer )
    1040
    1041 -    def _create_impl(self):
    1042          answer = [ self._create_declaration() ]
    1043          answer.append( ': ' + self._create_constructor_call() )
    1044          answer.append( '  , ' +  self.parent.boost_wrapper_identifier + '(){' )
    1045          answer.append( self.indent( '// copy constructor' ) )
    1046          answer.append( self.indent( self.declaration.body ) )
    1047          answer.append( '}' )
    1048          return os.linesep.join( answer )
    1049
    1050 -    def _get_system_headers_impl( self ):
    1051          return []
    1052
    1053 -class null_constructor_wrapper_t( code_creator.code_creator_t
    1054                                    , declaration_based.declaration_based_t ):
    1055      """
    1056      Creates wrapper for compiler generated null constructor.
    1057      """
    1058 -    def __init__( self, constructor ):
    1059          code_creator.code_creator_t.__init__( self )
    1060          declaration_based.declaration_based_t.__init__( self, declaration=constructor )
    1061
    1062      @property
    1063 -    def parent_class( self ):
    1064          return self.declaration.parent
    1065
    1066 -    def _create_constructor_call( self ):
    1067          return algorithm.create_identifier( self, self.parent_class.decl_string ) + '()'
    1068
    1069 -    def _create_impl(self):
    1070          answer = [ self.parent_class.wrapper_alias + '(' ]
    1071          if not self.target_configuration.boost_python_has_wrapper_held_type \
    1072             or self.parent_class.require_self_reference:
    1073              answer[0] = answer[0] + 'PyObject* self'
    1074          answer[0] = answer[0] + ')'
    1075          answer.append( ': ' + self._create_constructor_call() )
    1076          answer.append( '  , ' +  self.parent.boost_wrapper_identifier + '(){' )
    1077          answer.append( self.indent( '// null constructor' ) )
    1078          answer.append( self.indent( self.declaration.body ) )
    1079          answer.append( '}' )
    1080          return os.linesep.join( answer )
    1081
    1082 -    def _get_system_headers_impl( self ):
    1083          return []
    1084
    1085  #in python all operators are members of class, while in C++
    1086  #you can define operators that are not.
    1087 -class operator_t( registration_based.registration_based_t
    1088                    , declaration_based.declaration_based_t ):
    1089      """
    1090      Creates boost.python code needed to expose supported subset of C++ operators.
    1091      """
    1092 -    class SELF_POSITION:
    1093          FIRST = 'first'
    1094          SECOND = 'second'
    1095          BOTH = 'both'
    1096
    1097 -    def __init__(self, operator ):
    1098          registration_based.registration_based_t.__init__( self )
    1099          declaration_based.declaration_based_t.__init__( self, declaration=operator )
    1100
    1101 -    def _call_type_constructor( self, type ):
    1102          x = declarations.remove_reference( type )
    1103          x = declarations.remove_cv( x )
    1104          other = algorithm.create_identifier( self, '::boost::python::other' )
    1105          type_ = algorithm.create_identifier( self, x.partial_decl_string )
    1106          return declarations.templates.join( other, [ type_ ] ) + '()'
    1107
    1108 -    def _findout_self_position(self):
    1109          assert not declarations.is_unary_operator( self.declaration )
    1110          decompose_type = declarations.decompose_type
    1111          parent_decl_string = self.parent.declaration.decl_string
    1112          arg0 = decompose_type( self.declaration.arguments[0].type )[-1].decl_string
    1113          if isinstance( self.declaration, declarations.member_operator_t ):
    1114              if parent_decl_string == arg0:
    1115                  return self.SELF_POSITION.BOTH
    1116              else:
    1117                  return self.SELF_POSITION.FIRST #may be wrong in case ++, --, but any way boost.python does not expose them
    1118          #now we deal with non global operators
    1119          arg1 = decompose_type( self.declaration.arguments[1].type )[-1].decl_string
    1120          if arg0 == arg1:
    1121              assert parent_decl_string == arg0 #in this case I have bug in module creator
    1122              return operator_t.SELF_POSITION.BOTH
    1123          elif arg0 != arg1 and arg0 == parent_decl_string:
    1124              return operator_t.SELF_POSITION.FIRST
    1125          elif arg0 != arg1 and arg1 == parent_decl_string:
    1126              return operator_t.SELF_POSITION.SECOND
    1127          else:
    1128              assert not "Unable to find out boost::python::self position. " + str( self.declaration )
    1129
    1130 -    def _create_binary_operator(self):
    1131          self_identifier = algorithm.create_identifier( self, '::boost::python::self' )
    1132
    1133          if self.declaration.symbol == '<<':
    1134              str_identifier = algorithm.create_identifier( self, '::boost::python::self_ns::str' )
    1135              return '%s( %s )' % ( str_identifier, self_identifier )
    1136
    1137          answer = [ None, self.declaration.symbol, None ]
    1138          self_position = self._findout_self_position()
    1139          if self_position == self.SELF_POSITION.FIRST:
    1140              answer[0] = self_identifier
    1141              type_ = None
    1142              if len( self.declaration.arguments ) == 2:
    1143                  type_ = self.declaration.arguments[1].type
    1144              else:
    1145                  type_ = self.declaration.arguments[0].type
    1146              answer[2] = self._call_type_constructor( type_ )
    1147          elif self_position == self.SELF_POSITION.SECOND:
    1148              answer[0] = self._call_type_constructor(self.declaration.arguments[0].type )
    1149              answer[2] = self_identifier
    1150          else:
    1151              answer[0] = self_identifier
    1152              answer[2] = self_identifier
    1153          return ' '.join( answer )
    1154
    1155 -    def _create_unary_operator(self):
    1156          return self.declaration.symbol + algorithm.create_identifier( self, '::boost::python::self' )
    1157
    1158 -    def _create_impl( self ):
    1159          code = None
    1160          if declarations.is_binary_operator( self.declaration ):
    1161              code = self._create_binary_operator()
    1162          else:
    1163              code = self._create_unary_operator()
    1164          return 'def( %s )' % code
    1165
    1166 -    def _get_system_headers_impl( self ):
    1167          return []
    1168
    1169 -class casting_operator_t( registration_based.registration_based_t
    1170                            , declaration_based.declaration_based_t ):
    1171      """
    1172      Creates boost.python code needed to register type conversions( implicitly_convertible )
    1173      """
    1174 -    def __init__( self, operator ):
    1175          registration_based.registration_based_t.__init__( self )
    1176          declaration_based.declaration_based_t.__init__( self, declaration=operator )
    1177          self.works_on_instance = False
    1178
    1179 -    def _create_impl(self):
    1180          #TODO add comment in case of non const operator
    1181          implicitly_convertible = algorithm.create_identifier( self, '::boost::python::implicitly_convertible' )
    1182          from_name = declarations.full_name( self.declaration.parent, with_defaults=False )
    1183          from_arg = algorithm.create_identifier( self, from_name )
    1184
    1185          to_arg = algorithm.create_identifier( self
    1186                                                , self.declaration.return_type.partial_decl_string )
    1187          return declarations.templates.join(implicitly_convertible
    1188                                             , [ from_arg , to_arg ] )  \
    1189                 + '();'
    1190
    1191 -    def _get_system_headers_impl( self ):
    1192          return []
    1193
    1194 -class casting_member_operator_t( registration_based.registration_based_t
    1195                                   , declaration_based.declaration_based_t ):
    1196      """
    1197      Creates boost.python code needed to register casting operators. For some
    1198      operators Pythonic name is given: __int__, __long__, __float__, __str__
    1199      """
    1200
    1201 -    def __init__( self, operator ):
    1202          registration_based.registration_based_t.__init__( self )
    1203          declaration_based.declaration_based_t.__init__( self, declaration=operator )
    1204
    1205 -    def _create_impl(self):
    1206          template = 'def( "%(function_name)s", &%(class_name)s::operator %(destination_type)s %(call_policies)s%(doc)s )'
    1207          p_name = declarations.full_name( self.declaration.parent, with_defaults=False )
    1208          class_name = algorithm.create_identifier( self, p_name )
    1209
    1210          policies = ''
    1211          if self.declaration.call_policies:
    1212              if not self.declaration.call_policies.is_default():
    1213                  policies = ',' + self.declaration.call_policies.create( self )
    1214          else:
    1215              policies = '/*, undefined call policies */'
    1216
    1217          doc = ''
    1218          if self.documentation:
    1219              doc = ', %s' % self.documentation
    1220
    1221          return template % { 'function_name' : self.declaration.alias
    1222                              , 'class_name' : class_name
    1223                              , 'destination_type' : self.declaration.return_type.partial_decl_string
    1224                              , 'call_policies' : policies
    1225                              , 'doc' : doc
    1226                 }
    1227
    1228 -    def _get_system_headers_impl( self ):
    1229          return []
    1230
    1231 -class casting_constructor_t( registration_based.registration_based_t
    1232                               , declaration_based.declaration_based_t ):
    1233      """
    1234      Creates boost.python code needed to register type conversions( implicitly_convertible ).
    1235      This case treat situation when class has public non explicit constuctor from
    1236      another type.
    1237      """
    1238 -    def __init__( self, constructor ):
    1239          registration_based.registration_based_t.__init__( self )
    1240          declaration_based.declaration_based_t.__init__( self, declaration=constructor )
    1241          self.works_on_instance = False
    1242
    1243 -    def _create_impl(self):
    1244          implicitly_convertible = algorithm.create_identifier( self, '::boost::python::implicitly_convertible' )
    1245          from_arg = algorithm.create_identifier( self
    1246                                                  ,  self.declaration.arguments[0].type.partial_decl_string)
    1247
    1248          to_name = declarations.full_name( self.declaration.parent, with_defaults=False )
    1249          to_arg = algorithm.create_identifier( self, to_name )
    1250          return declarations.templates.join(implicitly_convertible, [from_arg, to_arg ]) \
    1251                 + '();'
    1252
    1253 -    def _get_system_headers_impl( self ):
    1254          return []
    1255
    1256 -class destructor_wrapper_t( code_creator.code_creator_t
    1257                              , declaration_based.declaration_based_t ):
    1258      """
    1259      Creates class wrapper destructor from the code provided by the user
    1260      """
    1261 -    def __init__( self, class_ ):
    1262          code_creator.code_creator_t.__init__( self )
    1263          declaration_based.declaration_based_t.__init__( self, declaration=class_ )
    1264
    1265 -    def _create_impl(self):
    1266          answer = [ 'virtual ~%s(){' % self.declaration.wrapper_alias ]
    1267          answer.append( self.indent( os.linesep.join( self.declaration.destructor_code ) ) )
    1268          answer.append( '}' )
    1269          return os.linesep.join( answer )
    1270
    1271 -    def _get_system_headers_impl( self ):
    1272          return []
    1273
    1274
    1275 -class calldef_overloads_class_t( code_creator.code_creator_t ):
    1276 -    def __init__( self, functions ):
    1277          #precondition: all member functions belong to same class and
    1278          #they all have same alias, otherwise it does not makes sense
    1279          code_creator.code_creator_t.__init__( self )
    1280          self._functions = functions
    1281          self._functions.sort() #I need this for "stabble" code generation
    1282          self._max_fun = None #function with maximal number of arguments
    1283
    1284      @property
    1285 -    def functions( self ):
    1286          return self._functions
    1287
    1288 -    def min_max_num_of_args( self ):
    1289          #returns tuple( minimal, maximal ) number of arguments
    1290          min_ = None
    1291          max_ = 0
    1292          for f in self.functions:
    1293              f_max = len( f.arguments )
    1294              f_min = f_max - len( filter( lambda arg: arg.default_value, f.arguments ) )
    1295              if None is min_:
    1296                  min_ = f_min
    1297              else:
    1298                  min_ = min( min_, f_min )
    1299              max_tmp = max( max_, f_max )
    1300              if max_ < max_tmp:
    1301                  max_ = max_tmp
    1302                  self._max_fun = f
    1303          return ( min_, max_ )
    1304
    1305      @property
    1306 -    def max_function( self ):
    1307          if not self._max_fun:
    1308              initialize_max_fun_var = self.min_max_num_of_args()
    1309          return self._max_fun
    1310
    1311      @property
    1312 -    def max_function_identifier( self ):
    1313          return algorithm.create_identifier( self, declarations.full_name( self.max_function ) )
    1314
    1315      @property
    1316 -    def alias( self ):
    1317          return self.functions[0].alias
    1318
    1319      @property
    1320 -    def parent_decl( self ):
    1321          return self.functions[0].parent
    1322
    1323      @property
    1324 -    def name( self ):
    1325          return '%s_%s_overloads' % ( self.parent_decl.alias, self.alias )
    1326
    1327 -class mem_fun_overloads_class_t( calldef_overloads_class_t ):
    1328 -    def __init__( self, mem_funs ):
    1329          #precondition: all member functions belong to same class and
    1330          #they all have same alias, otherwise it does not makes sense
    1331          calldef_overloads_class_t.__init__( self, mem_funs )
    1332
    1333 -    def _create_impl(self):
    1334          if self.max_function.already_exposed:
    1335              return ''
    1336
    1337          min_, max_ = self.min_max_num_of_args()
    1338          return "BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( %(overloads_cls)s, %(fun)s, %(min)d, %(max)d )" \
    1339                 % {   'overloads_cls' : self.name
    1340                     , 'fun' : self.max_function_identifier
    1341                     , 'min' : min_
    1342                     , 'max' : max_
    1343                 }
    1344
    1345 -    def _get_system_headers_impl( self ):
    1346          return []
    1347
    1348 -class free_fun_overloads_class_t( calldef_overloads_class_t ):
    1349 -    def __init__( self, free_funs ):
    1350          #precondition: all member functions belong to same class and
    1351          #they all have same alias, otherwise it does not makes sense
    1352          calldef_overloads_class_t.__init__( self, free_funs )
    1353
    1354 -    def _create_impl(self):
    1355          if self.max_function.already_exposed:
    1356              return ''
    1357
    1358          min_, max_ = self.min_max_num_of_args()
    1359          return "BOOST_PYTHON_FUNCTION_OVERLOADS( %(overloads_cls)s, %(fun)s, %(min)d, %(max)d )" \
    1360                 % {   'overloads_cls' : self.name
    1361                     , 'fun' : self.max_function_identifier
    1362                     , 'min' : min_
    1363                     , 'max' : max_
    1364                 }
    1365
    1366 -    def _get_system_headers_impl( self ):
    1367          return []
    1368
    1369 -class calldef_overloads_t( registration_based.registration_based_t ):
    1370 -    def __init__( self, overloads_class ):
    1371          registration_based.registration_based_t.__init__( self )
    1372          self._overloads_class = overloads_class
    1373
    1374      @property
    1375 -    def overloads_class( self ):
    1376          return self._overloads_class
    1377
    1378 -    def create_def_code( self ):
    1379          raise NotImplementedError()
    1380
    1381 -    def create_end_def_code( self ):
    1382          raise NotImplementedError()
    1383
    1384 -    def create_keywords_args(self):
    1385          result = [ algorithm.create_identifier( self, '::boost::python::args' ) ]
    1386          result.append( '( ' )
    1387          args = []
    1388          for arg in self.overloads_class.max_function.arguments:
    1389              if 0 < len( args ):
    1390                  args.append( self.PARAM_SEPARATOR )
    1391              args.append( '"%s"' % arg.name )
    1392          result.extend( args )
    1393          result.append( ' )' )
    1394          return ''.join( result )
    1395
    1396 -    def _get_function_type_alias( self ):
    1397          return self.overloads_class.alias + '_function_type'
    1398      function_type_alias = property( _get_function_type_alias )
    1399
    1400 -    def create_function_type_alias_code( self, exported_class_alias=None ):
    1401          raise NotImplementedError()
    1402
    1403 -    def create_overloads_cls( self ):
    1404          result = [ self.overloads_class.name ]
    1405          result.append( '( ' )
    1406          if self.overloads_class.max_function.use_keywords:
    1407              result.append( os.linesep + self.indent( self.create_keywords_args(), 3 ) )
    1408          if self.overloads_class.max_function.documentation:
    1409              if self.overloads_class.max_function.use_keywords:
    1410                  result.append( os.linesep + self.indent( self.PARAM_SEPARATOR, 3 ) )
    1411              result.append( self.overloads_class.max_function.documentation )
    1412          result.append( ' )' )
    1413          if self.overloads_class.max_function.call_policies \
    1414             and not self.overloads_class.max_function.call_policies.is_default():
    1415              result.append( os.linesep + self.indent('', 3) )
    1416              result.append('[ %s ]' % self.overloads_class.max_function.call_policies.create( self ) )
    1417          return ''.join( result )
    1418
    1419 -    def _create_impl(self):
    1420          result = []
    1421          if not self.works_on_instance:
    1422              exported_class_alias = None
    1423              if declarations.templates.is_instantiation( self.overloads_class.max_function.parent.name ):
    1424                  exported_class_alias = self.exported_class_alias
    1425                  result.append( 'typedef %s %s;' % ( self.parent.decl_identifier, exported_class_alias ) )
    1426                  result.append( os.linesep )
    1427              result.append( self.create_function_type_alias_code(exported_class_alias) )
    1428              result.append( os.linesep * 2 )
    1429
    1430          result.append( self.create_def_code() + '( ' )
    1431          result.append( os.linesep + self.indent( '"%s"' % self.overloads_class.alias ) )
    1432
    1433          result.append( os.linesep + self.indent( self.PARAM_SEPARATOR ) )
    1434          result.append( self.create_function_ref_code( not self.works_on_instance ) )
    1435
    1436          result.append( os.linesep + self.indent( self.PARAM_SEPARATOR ) )
    1437          result.append( self.create_overloads_cls() )
    1438
    1439          result.append( ' )' )
    1440          result.append( self.create_end_def_code() )
    1441
    1442          if not self.works_on_instance:
    1443              #indenting and adding scope
    1444              code = ''.join( result )
    1445              result = [ '{ //%s' % declarations.full_name( self.overloads_class.max_function ) ]
    1446              result.append( os.linesep * 2 )
    1447              result.append( self.indent( code ) )
    1448              result.append( os.linesep * 2 )
    1449              result.append( '}' )
    1450
    1451          return ''.join( result )
    1452
    1453 -    def _get_system_headers_impl( self ):
    1454          return []
    1455
    1456 -class mem_fun_overloads_t( calldef_overloads_t ):
    1457 -    def __init__( self, overloads_class ):
    1458          calldef_overloads_t.__init__( self, overloads_class )
    1459
    1460 -    def create_def_code( self ):
    1461          if not self.works_on_instance:
    1462              return '%s.def' % self.parent.class_var_name
    1463          else:
    1464              return 'def'
    1465
    1466 -    def create_end_def_code( self ):
    1467          if not self.works_on_instance:
    1468              return ';'
    1469          else:
    1470              return ''
    1471
    1472 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
    1473          ftype = self.overloads_class.max_function.function_type()
    1474          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias )
    1475
    1476 -    def create_function_ref_code(self, use_function_alias=False):
    1477          fname = declarations.full_name( self.overloads_class.max_function )
    1478          if use_function_alias:
    1479              return '%s( &%s )' % ( self.function_type_alias, fname )
    1480          elif self.overloads_class.max_function.create_with_signature:
    1481              return '(%s)( &%s )' % ( self.overloads_class.max_function.function_type().decl_string, fname )
    1482          else:
    1483              return '&%s' % fname
    1484
    1485
    1486 -class free_fun_overloads_t( calldef_overloads_t ):
    1487 -    def __init__( self, overloads_class ):
    1488          calldef_overloads_t.__init__( self, overloads_class )
    1489
    1490 -    def create_def_code( self ):
    1491          return algorithm.create_identifier( self, '::boost::python::def' )
    1492
    1493 -    def create_end_def_code( self ):
    1494          return ';'
    1495
    1496 -    def create_function_type_alias_code( self, exported_class_alias=None  ):
    1497          ftype = self.overloads_class.max_function.function_type()
    1498          return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias )
    1499
    1500 -    def create_function_ref_code(self, use_function_alias=False):
    1501          fname = declarations.full_name( self.overloads_class.max_function )
    1502          if use_function_alias:
    1503              return '%s( &%s )' % ( self.function_type_alias, fname )
    1504          elif self.overloads_class.max_function.create_with_signature:
    1505              return '(%s)( &%s )' % ( self.overloads_class.max_function.function_type().decl_string, fname )
    1506          else:
    1507              return '&%s' % fname
    1508