pyplusplus.code_creators.member_variable

Package pyplusplus :: Package code_creators :: Module member_variable |

# Source Code for Module pyplusplus.code_creators.member_variable

      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 declaration_based
     10  from pyplusplus import code_repository
     11  from pyplusplus.decl_wrappers import call_policies
     12  from pyplusplus.decl_wrappers import python_traits
     13  import registration_based
     14  from pygccxml import declarations
     15
     16 -class member_variable_base_t( registration_based.registration_based_t
     17                                , declaration_based.declaration_based_t ):
     18      """
     19      Base class for all member variables code creators. Mainly exists to
     20      simplify file writers algorithms.
     21      """
     22
     23 -    def __init__(self, variable, wrapper=None ):
     24          registration_based.registration_based_t.__init__( self )
     25          declaration_based.declaration_based_t.__init__( self, declaration=variable)
     26          self._wrapper = wrapper
     27
     28 -    def _get_wrapper( self ):
     29          return self._wrapper
     30 -    def _set_wrapper( self, new_wrapper ):
     31          self._wrapper = new_wrapper
     32      wrapper = property( _get_wrapper, _set_wrapper )
     33
     34 -    def _get_system_headers_impl( self ):
     35          files = []
     36          if self.declaration.getter_call_policies:
     37              files.append( self.declaration.getter_call_policies.header_file )
     38          if self.declaration.setter_call_policies:
     39              files.append( self.declaration.setter_call_policies.header_file )
     40          return files
     41
     42 -class member_variable_t( member_variable_base_t ):
     43      """
     44      Creates boost.python code that exposes member variable.
     45      """
     46 -    def __init__(self, variable, wrapper=None ):
     47          member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper )
     48
     49      #>    On Wednesday, 19. April 2006 23:05, Ralf W. Grosse-Kunstleve wrote:
     50      #>   .add_property("p", make_function(&A::get_p, return_value_policy<reference_existing_object>()))
     51 -    def _generate_for_pointer( self ):
     52          doc = '' #static property does not support documentation
     53          if self.declaration.type_qualifiers.has_static:
     54              add_property = 'add_static_property'
     55          else:
     56              if self.documentation:
     57                  doc = self.documentation
     58              add_property = 'add_property'
     59          answer = [ add_property ]
     60          answer.append( '( ' )
     61          answer.append('"%s"' % self.alias)
     62          answer.append( self.PARAM_SEPARATOR )
     63
     64          #according to David Abrahams:
     65          #http://mail.python.org/pipermail/c++-sig/2003-January/003276.html
     66          call_pol = call_policies.return_internal_reference().create( self )
     67          make_function = algorithm.create_identifier( self, '::boost::python::make_function' )
     68
     69          answer.append( '%(mk_func)s( (%(getter_type)s)(&%(wfname)s), %(call_pol)s )'
     70                         % { 'mk_func' : make_function
     71                             , 'getter_type' : self.wrapper.getter_type
     72                             , 'wfname' : self.wrapper.getter_full_name
     73                             , 'call_pol' : call_pol } )
     74
     75          #don't generate setter method, right now I don't know how to do it.
     76          if self.wrapper.has_setter:
     77              answer.append( self.PARAM_SEPARATOR )
     78              call_pol = ''
     79              if not self.declaration.type_qualifiers.has_static:
     80                  call_pol = ", " + call_policies.with_custodian_and_ward_postcall( 1, 2 ).create(self)
     81              answer.append( '%(mk_func)s( (%(setter_type)s)(&%(wfname)s)%(call_pol)s )'
     82                         % { 'mk_func' : make_function
     83                             , 'setter_type' : self.wrapper.setter_type
     84                             , 'wfname' : self.wrapper.setter_full_name
     85                             , 'call_pol' : call_pol } )
     86          if doc:
     87              answer.append( self.PARAM_SEPARATOR )
     88              answer.append( doc )
     89          answer.append( ' ) ' )
     90
     91          code = ''.join( answer )
     92          if len( code ) <= self.LINE_LENGTH:
     93              return code
     94          else:
     95              for i in range( len( answer ) ):
     96                  if answer[i] == self.PARAM_SEPARATOR:
     97                      answer[i] = os.linesep + self.indent( self.indent( self.indent( answer[i] ) ) )
     98              return ''.join( answer )
     99
    100 -    def _generate_for_none_pointer( self ):
    101          tmpl = None
    102          if self.declaration.type_qualifiers.has_static:
    103              tmpl = '%(access)s( "%(alias)s", %(name)s%(doc)s )'
    104          else:
    105              tmpl = '%(access)s( "%(alias)s", &%(name)s%(doc)s )'
    106
    107          access = 'def_readwrite'
    108          if self.declaration.is_read_only:
    109              access = 'def_readonly'
    110          doc = ''
    111          if self.documentation:
    112              doc = ', %s' % self.documentation
    113          result = tmpl % {
    114                      'access' : access
    115                      , 'alias' : self.alias
    116                      , 'name' : self.decl_identifier
    117                      , 'doc' : doc }
    118
    119          return result
    120
    121 -    def _generate_using_functions( self ):
    122          doc = ''
    123          add_property = ''
    124          make_getter = algorithm.create_identifier( self, '::boost::python::make_getter')
    125          make_setter = algorithm.create_identifier( self, '::boost::python::make_setter')
    126          if self.declaration.type_qualifiers.has_static:
    127              add_property = 'add_static_property'
    128          else:
    129              if self.documentation:
    130                  doc = self.documentation
    131              add_property = 'add_property'
    132          add_property_args = [ '"%s"' % self.alias ]
    133          getter_code = declarations.call_invocation.join(
    134                            make_getter
    135                          , [ '&' + self.decl_identifier
    136                              , self.declaration.getter_call_policies.create( self ) ]
    137                          , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) )
    138
    139          add_property_args.append( getter_code )
    140          if not self.declaration.is_read_only:
    141              setter_code = ''
    142              setter_args = [ '&' + self.decl_identifier ]
    143              if self.declaration.setter_call_policies \
    144                 and not self.declaration.setter_call_policies.is_default():
    145                     setter_args.append( self.declaration.setter_call_policies.create( self ) )
    146              setter_code = declarations.call_invocation.join(
    147                                make_setter
    148                              , setter_args
    149                              , os.linesep + self.indent( self.PARAM_SEPARATOR, 6) )
    150              add_property_args.append( setter_code)
    151          if doc:
    152              add_property_args.append( doc )
    153          return declarations.call_invocation.join(
    154                      add_property
    155                      , add_property_args
    156                      , os.linesep + self.indent( self.PARAM_SEPARATOR, 4 ) )
    157
    158 -    def _create_impl( self ):
    159          if declarations.is_pointer( self.declaration.type ):
    160              return self._generate_for_pointer()
    161          elif self.declaration.apply_smart_ptr_wa or self.declaration.use_make_functions:
    162              return self._generate_using_functions()
    163          else:
    164              return self._generate_for_none_pointer()
    165
    166 -class member_variable_wrapper_t( code_creator.code_creator_t
    167                                   , declaration_based.declaration_based_t ):
    168      """
    169      Creates C++ code that creates accessor for pointer class variables
    170      """
    171      #TODO: give user a way to set call policies
    172      #      treat void* pointer
    173      indent = code_creator.code_creator_t.indent
    174      MV_GET_TEMPLATE = os.linesep.join([
    175            'static %(type)s get_%(name)s(%(cls_type)s inst ){'
    176          , indent( 'return inst.%(name)s;' )
    177          , '}'
    178          , ''
    179      ])
    180
    181      MV_STATIC_GET_TEMPLATE = os.linesep.join([
    182            'static %(type)s get_%(name)s(){'
    183          , indent( 'return %(cls_type)s::%(name)s;' )
    184          , '}'
    185          , ''
    186      ])
    187
    188      MV_SET_TEMPLATE = os.linesep.join([
    189            'static void set_%(name)s( %(cls_type)s inst, %(type)s new_value ){ '
    190          , indent( 'inst.%(name)s = new_value;' )
    191          , '}'
    192          , ''
    193      ])
    194
    195      MV_STATIC_SET_TEMPLATE = os.linesep.join([
    196            'static void set_%(name)s( %(type)s new_value ){ '
    197          , indent( '%(cls_type)s::%(name)s = new_value;' )
    198          , '}'
    199          , ''
    200      ])
    201
    202 -    def __init__(self, variable ):
    203          code_creator.code_creator_t.__init__( self )
    204          declaration_based.declaration_based_t.__init__( self, declaration=variable)
    205
    206 -    def _get_getter_full_name(self):
    207          return self.parent.full_name + '::' + 'get_' + self.declaration.name
    208      getter_full_name = property( _get_getter_full_name )
    209
    210 -    def inst_arg_type( self, has_const ):
    211          inst_arg_type = declarations.declarated_t( self.declaration.parent )
    212          if has_const:
    213              inst_arg_type = declarations.const_t(inst_arg_type)
    214          inst_arg_type = declarations.reference_t(inst_arg_type)
    215          return inst_arg_type
    216
    217 -    def _get_getter_type(self):
    218          if self.declaration.type_qualifiers.has_static:
    219              arguments_types=[]
    220          else:
    221              arguments_types=[ self.inst_arg_type(True) ]
    222
    223          return declarations.free_function_type_t.create_decl_string(
    224                  return_type=self.declaration.type
    225                  , arguments_types=arguments_types
    226                  , with_defaults=False)
    227      getter_type = property( _get_getter_type )
    228
    229 -    def _get_setter_full_name(self):
    230          return self.parent.full_name + '::' + 'set_' + self.declaration.name
    231      setter_full_name = property(_get_setter_full_name)
    232
    233 -    def _get_setter_type(self):
    234          if self.declaration.type_qualifiers.has_static:
    235              arguments_types=[ self.declaration.type ]
    236          else:
    237              arguments_types=[ self.inst_arg_type(False), self.declaration.type  ]
    238
    239          return declarations.free_function_type_t.create_decl_string(
    240                  return_type=declarations.void_t()
    241                  , arguments_types=arguments_types
    242                  , with_defaults=False)
    243      setter_type = property( _get_setter_type )
    244
    245 -    def _get_has_setter( self ):
    246          return not declarations.is_const( self.declaration.type )
    247      has_setter = property( _get_has_setter )
    248
    249 -    def _create_impl(self):
    250          answer = []
    251          if self.declaration.type_qualifiers.has_static:
    252              substitutions = {
    253                  'type' : self.declaration.type.decl_string
    254                  , 'name' : self.declaration.name
    255                  , 'cls_type' : declarations.full_name( self.declaration.parent )
    256              }
    257              answer.append( self.MV_STATIC_GET_TEMPLATE % substitutions)
    258              if self.has_setter:
    259                  answer.append( self.MV_STATIC_SET_TEMPLATE % substitutions )
    260          else:
    261              answer.append( self.MV_GET_TEMPLATE % {
    262                  'type' : self.declaration.type.decl_string
    263                  , 'name' : self.declaration.name
    264                  , 'cls_type' : self.inst_arg_type( has_const=True ) })
    265              if self.has_setter:
    266                  answer.append( self.MV_SET_TEMPLATE % {
    267                  'type' : self.declaration.type.decl_string
    268                  , 'name' : self.declaration.name
    269                  , 'cls_type' : self.inst_arg_type( has_const=False ) })
    270          return os.linesep.join( answer )
    271
    272 -    def _get_system_headers_impl( self ):
    273          return []
    274
    275 -class bit_field_t( member_variable_base_t ):
    276      """
    277      Creates boost.python code that exposes bit fields member variables
    278      """
    279 -    def __init__(self, variable, wrapper ):
    280          member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper )
    281
    282 -    def _create_impl( self ):
    283          doc = ''
    284          if self.declaration.type_qualifiers.has_static:
    285              add_property = 'add_static_property'
    286          else:
    287              if self.documentation:
    288                  doc = self.documentation
    289              add_property = 'add_property'
    290          answer = [ add_property ]
    291          answer.append( '( ' )
    292          answer.append('"%s"' % self.alias)
    293          answer.append( self.PARAM_SEPARATOR )
    294          answer.append( '(%s)(&%s)'
    295                         % ( self.wrapper.getter_type, self.wrapper.getter_full_name ) )
    296
    297          if self.wrapper.has_setter:
    298              answer.append( self.PARAM_SEPARATOR )
    299              answer.append( '(%s)(&%s)'
    300                             % ( self.wrapper.setter_type, self.wrapper.setter_full_name ) )
    301          if doc:
    302              answer.append( self.PARAM_SEPARATOR )
    303              answer.append( doc )
    304          answer.append( ' ) ' )
    305
    306          code = ''.join( answer )
    307          if len( code ) <= self.LINE_LENGTH:
    308              return code
    309          else:
    310              for i in range( len( answer ) ):
    311                  if answer[i] == self.PARAM_SEPARATOR:
    312                      answer[i] = os.linesep + self.indent( self.indent( self.indent( answer[i] ) ) )
    313              return ''.join( answer )
    314
    315 -class bit_field_wrapper_t( code_creator.code_creator_t
    316                             , declaration_based.declaration_based_t ):
    317      """
    318      Creates C++ code that creates accessor for bit fields
    319      """
    320
    321      indent = code_creator.code_creator_t.indent
    322      BF_GET_TEMPLATE = os.linesep.join([
    323            '%(type)s get_%(name)s() const {'
    324          , indent( 'return %(name)s;' )
    325          , '}'
    326          , ''
    327      ])
    328
    329      BF_SET_TEMPLATE = os.linesep.join([
    330            'void set_%(name)s( %(type)s new_value ){ '
    331          , indent( '%(name)s = new_value;' )
    332          , '}'
    333          , ''
    334      ])
    335
    336 -    def __init__(self, variable ):
    337          code_creator.code_creator_t.__init__( self )
    338          declaration_based.declaration_based_t.__init__( self, declaration=variable)
    339
    340 -    def _get_getter_full_name(self):
    341          return self.parent.full_name + '::' + 'get_' + self.declaration.name
    342      getter_full_name = property( _get_getter_full_name )
    343
    344 -    def _get_getter_type(self):
    345          return declarations.member_function_type_t.create_decl_string(
    346                  return_type=self.declaration.type
    347                  , class_decl_string=self.parent.full_name
    348                  , arguments_types=[]
    349                  , has_const=True
    350                  , with_defaults=False)
    351      getter_type = property( _get_getter_type )
    352
    353 -    def _get_setter_full_name(self):
    354          return self.parent.full_name + '::' + 'set_' + self.declaration.name
    355      setter_full_name = property(_get_setter_full_name)
    356
    357 -    def _get_setter_type(self):
    358          return declarations.member_function_type_t.create_decl_string(
    359                  return_type=declarations.void_t()
    360                  , class_decl_string=self.parent.full_name
    361                  , arguments_types=[self.declaration.type]
    362                  , has_const=False
    363                  , with_defaults=False)
    364      setter_type = property( _get_setter_type )
    365
    366 -    def _get_has_setter( self ):
    367          return not declarations.is_const( self.declaration.type )
    368      has_setter = property( _get_has_setter )
    369
    370 -    def _create_impl(self):
    371          answer = []
    372          substitutions = dict( type=self.declaration.type.decl_string
    373                                , name=self.declaration.name )
    374          answer.append( self.BF_GET_TEMPLATE % substitutions )
    375          if self.has_setter:
    376              answer.append( self.BF_SET_TEMPLATE % substitutions )
    377          return os.linesep.join( answer )
    378
    379 -    def _get_system_headers_impl( self ):
    380          return []
    381
    382 -class array_mv_t( member_variable_base_t ):
    383      """
    384      Creates boost.python code that exposes array member variable.
    385      """
    386 -    def __init__(self, variable, wrapper ):
    387          member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper )
    388          self.works_on_instance = False
    389
    390 -    def _create_body( self ):
    391          answer = []
    392          answer.append( 'typedef %s;' % self.wrapper.wrapper_creator_type.create_typedef( 'array_wrapper_creator' ) )
    393          answer.append( os.linesep * 2 )
    394
    395          doc = ''
    396          if self.declaration.type_qualifiers.has_static:
    397              answer.append( self.parent.class_var_name + '.add_static_property' )
    398          else:
    399              if self.documentation:
    400                  doc = self.documentation
    401              answer.append( self.parent.class_var_name + '.add_property' )
    402          answer.append( '( ' )
    403          answer.append('"%s"' % self.declaration.name )
    404          answer.append( os.linesep + self.indent( self.PARAM_SEPARATOR ) )
    405          temp = [ algorithm.create_identifier( self, "::boost::python::make_function" ) ]
    406          temp.append( '( ' )
    407          temp.append( 'array_wrapper_creator(&%s)' % self.wrapper.wrapper_creator_full_name )
    408          if not self.declaration.type_qualifiers.has_static:
    409              temp.append( os.linesep + self.indent( self.PARAM_SEPARATOR, 6 ) )
    410              temp.append( call_policies.with_custodian_and_ward_postcall( 0, 1 ).create(self) )
    411          temp.append( ' )' )
    412          answer.append( ''.join( temp ) )
    413          if doc:
    414              answer.append( os.linesep )
    415              answer.append( self.PARAM_SEPARATOR )
    416              answer.append( doc )
    417          answer.append( ' );' )
    418          return ''.join( answer )
    419
    420 -    def _create_impl( self ):
    421          answer = []
    422          answer.append( '{ //%s, type=%s' % ( self.declaration, self.declaration.type ) )
    423          answer.append( os.linesep * 2 )
    424          answer.append( self.indent( self._create_body() ) )
    425          answer.append( os.linesep )
    426          answer.append( '}' )
    427          return ''.join( answer )
    428
    429 -    def _get_system_headers_impl( self ):
    430          return []
    431
    432
    433  #TODO: generated fucntion should be static and take instance of the wrapped class
    434  #as first argument.
    435 -class array_mv_wrapper_t( code_creator.code_creator_t
    436                            , declaration_based.declaration_based_t ):
    437      """
    438      Creates C++ code that register array class.
    439      """
    440
    441 -    def __init__(self, variable ):
    442          code_creator.code_creator_t.__init__( self )
    443          declaration_based.declaration_based_t.__init__( self, declaration=variable)
    444
    445      @property
    446 -    def wrapper_type( self ):
    447          tmpl = "%(namespace)s::%(constness)sarray_1_t< %(item_type)s, %(array_size)d>"
    448
    449          constness = ''
    450          if declarations.is_const( self.declaration.type ):
    451              constness = 'const_'
    452          result = tmpl % {
    453                  'namespace' : code_repository.array_1.namespace
    454                , 'constness' : constness
    455                , 'item_type' : declarations.array_item_type( self.declaration.type ).decl_string
    456                , 'array_size': declarations.array_size( self.declaration.type )
    457          }
    458          return declarations.dummy_type_t( result )
    459
    460      @property
    461 -    def wrapped_class_type( self ):
    462          wrapped_cls_type = declarations.declarated_t( self.declaration.parent )
    463          if declarations.is_const( self.declaration.type ):
    464              wrapped_cls_type = declarations.const_t( wrapped_cls_type )
    465          return declarations.reference_t( wrapped_cls_type )
    466
    467      @property
    468 -    def wrapper_creator_type(self):
    469          return declarations.free_function_type_t(
    470                  return_type=self.wrapper_type
    471                  , arguments_types=[self.wrapped_class_type] )
    472
    473      @property
    474 -    def wrapper_creator_name(self):
    475          return '_'.join( ['pyplusplus', self.declaration.name, 'wrapper'] )
    476
    477      @property
    478 -    def wrapper_creator_full_name(self):
    479          return '::'.join( [self.parent.full_name, self.wrapper_creator_name] )
    480
    481 -    def _create_impl( self ):
    482          tmpl = os.linesep.join([
    483              "static %(wrapper_type)s"
    484            , "%(wrapper_creator_name)s( %(wrapped_class_type)s inst ){"
    485            , self.indent( "return %(wrapper_type)s( inst.%(mem_var_ref)s );" )
    486            , "}"
    487          ])
    488          return tmpl % {
    489                  'wrapper_type' : self.wrapper_type.decl_string
    490                , 'wrapper_creator_name' : self.wrapper_creator_name
    491                , 'wrapped_class_type' : self.wrapped_class_type.decl_string
    492                , 'mem_var_ref' : self.declaration.name
    493              }
    494
    495 -    def _get_system_headers_impl( self ):
    496          return [code_repository.array_1.file_name]
    497
    498
    499 -class mem_var_ref_t( member_variable_base_t ):
    500      """
    501      Creates C++ code that creates accessor for class member variable, that has type reference.
    502      """
    503 -    def __init__(self, variable, wrapper ):
    504          member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper )
    505          self.param_sep = os.linesep + self.indent( self.PARAM_SEPARATOR, 2 )
    506          self.works_on_instance = False
    507
    508 -    def _create_getter( self ):
    509          answer = ['def']
    510          answer.append( '( ' )
    511          answer.append( '"get_%s"' % self.alias)
    512          answer.append( self.param_sep )
    513          answer.append( '(%s)(&%s)'
    514                         % ( self.wrapper.getter_type.decl_string, self.wrapper.getter_full_name ) )
    515          if self.declaration.getter_call_policies:
    516              if not self.declaration.getter_call_policies.is_default():
    517                  answer.append( self.param_sep )
    518                  answer.append( self.declaration.getter_call_policies.create( self ) )
    519          else:
    520              answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) )
    521          if self.documentation:
    522              answer.append( self.param_sep )
    523              answer.append( self.documentation )
    524          answer.append( ' )' )
    525          return ''.join( answer )
    526
    527 -    def _create_setter( self ):
    528          answer = ['def']
    529          answer.append( '( ' )
    530          answer.append( '"set_%s"' % self.alias)
    531          answer.append( self.param_sep )
    532          answer.append( '(%s)(&%s)'
    533                         % ( self.wrapper.setter_type.decl_string, self.wrapper.setter_full_name ) )
    534          if self.declaration.setter_call_policies:
    535              if not self.declaration.setter_call_policies.is_default():
    536                  answer.append( self.param_sep )
    537                  answer.append( self.declaration.setter_call_policies.create( self ) )
    538          else:
    539              answer.append( os.linesep + self.indent( '/* undefined call policies */', 2 ) )
    540          answer.append( ' )' )
    541          return ''.join( answer )
    542
    543 -    def _create_impl( self ):
    544          #TODO: fix me, should not force class scope usage
    545          answer = []
    546          class_var_name = self.parent.class_var_name
    547          answer.append( "%s.%s;" % (class_var_name, self._create_getter() ) )
    548          if self.wrapper.has_setter:
    549              answer.append( os.linesep )
    550              answer.append( "%s.%s;" % (class_var_name, self._create_setter() ) )
    551          return ''.join( answer )
    552
    553 -class mem_var_ref_wrapper_t( code_creator.code_creator_t
    554                               , declaration_based.declaration_based_t ):
    555      """
    556      Creates C++ code that creates accessor for class member variable, that has type reference.
    557      """
    558
    559      indent = code_creator.code_creator_t.indent
    560      GET_TEMPLATE = os.linesep.join([
    561            'static %(type)s get_%(name)s( %(class_type)s& inst ) {'
    562          , indent( 'return inst.%(name)s;' )
    563          , '}'
    564          , ''
    565      ])
    566
    567      SET_TEMPLATE = os.linesep.join([
    568            'static void set_%(name)s( %(class_type)s& inst, %(type)s new_value ){ '
    569          , indent( 'inst.%(name)s = new_value;' )
    570          , '}'
    571          , ''
    572      ])
    573
    574 -    def __init__(self, variable ):
    575          code_creator.code_creator_t.__init__( self )
    576          declaration_based.declaration_based_t.__init__( self, declaration=variable)
    577
    578 -    def _get_getter_full_name(self):
    579          return self.parent.full_name + '::' + 'get_' + self.declaration.name
    580      getter_full_name = property( _get_getter_full_name )
    581
    582 -    def _get_class_inst_type( self ):
    583          return declarations.declarated_t( self.declaration.parent )
    584
    585 -    def _get_exported_var_type( self ):
    586          type_ = declarations.remove_reference( self.declaration.type )
    587          type_ = declarations.remove_const( type_ )
    588          if python_traits.is_immutable( type_ ):
    589              return type_
    590          else:
    591              return self.declaration.type
    592
    593 -    def _get_getter_type(self):
    594          return declarations.free_function_type_t(
    595                  return_type=self._get_exported_var_type()
    596                  , arguments_types=[ declarations.reference_t( self._get_class_inst_type() ) ] )
    597      getter_type = property( _get_getter_type )
    598
    599 -    def _get_setter_full_name(self):
    600          return self.parent.full_name + '::' + 'set_' + self.declaration.name
    601      setter_full_name = property(_get_setter_full_name)
    602
    603 -    def _get_setter_type(self):
    604          return declarations.free_function_type_t(
    605                  return_type=declarations.void_t()
    606                  , arguments_types=[ declarations.reference_t( self._get_class_inst_type() )
    607                                      , self._get_exported_var_type() ] )
    608      setter_type = property( _get_setter_type )
    609
    610 -    def _get_has_setter( self ):
    611          if declarations.is_const( declarations.remove_reference( self.declaration.type ) ):
    612              return False
    613          elif python_traits.is_immutable( self._get_exported_var_type() ):
    614              return True
    615          else:
    616              pass
    617
    618          no_ref = declarations.remove_reference( self.declaration.type )
    619          no_const = declarations.remove_const( no_ref )
    620          base_type = declarations.remove_alias( no_const )
    621          if not isinstance( base_type, declarations.declarated_t ):
    622              return True #TODO ????
    623          decl = base_type.declaration
    624          if decl.is_abstract:
    625              return False
    626          if declarations.has_destructor( decl ) and not declarations.has_public_destructor( decl ):
    627              return False
    628          if not declarations.has_copy_constructor(decl):
    629              return False
    630          return True
    631      has_setter = property( _get_has_setter )
    632
    633 -    def _create_impl(self):
    634          answer = []
    635          cls_type = algorithm.create_identifier( self, self.declaration.parent.decl_string )
    636
    637          substitutions = dict( type=self._get_exported_var_type().decl_string
    638                                , class_type=cls_type
    639                                , name=self.declaration.name )
    640          answer.append( self.GET_TEMPLATE % substitutions )
    641          if self.has_setter:
    642              answer.append( self.SET_TEMPLATE % substitutions )
    643          return os.linesep.join( answer )
    644
    645 -    def _get_system_headers_impl( self ):
    646          return []
    647
    648 -class member_variable_addressof_t( member_variable_base_t ):
    649      """
    650      Creates boost.python code that exposes address of member variable.
    651
    652      This functionality is pretty powerful if you use it with "ctypes" -
    653      standard package.
    654
    655      """
    656 -    def __init__(self, variable, wrapper=None ):
    657          member_variable_base_t.__init__( self, variable=variable, wrapper=wrapper )
    658
    659 -    def _create_m_var( self ):
    660          answer = [ 'add_property' ]
    661          answer.append( '( ' )
    662          answer.append('"%s"' % self.alias)
    663          answer.append( self.PARAM_SEPARATOR )
    664          answer.append( 'pyplus_conv::make_addressof_getter(&%s)'
    665                         % self.decl_identifier )
    666          if self.documentation:
    667              answer.append( self.PARAM_SEPARATOR )
    668              answer.append( self.documentation )
    669          answer.append( ' ) ' )
    670          return ''.join( answer )
    671
    672 -    def _create_s_var( self ):
    673          return 'def( %(def_visitor)s("%(name)s", %(var)s) )' \
    674                 % {   'def_visitor' : 'pyplus_conv::register_addressof_static_var'
    675                     , 'name' : self.alias
    676                     , 'var' : self.decl_identifier }
    677
    678
    679 -    def _create_impl( self ):
    680          if self.declaration.type_qualifiers.has_static:
    681              return self._create_s_var()
    682          else:
    683              return self._create_m_var()
    684 -    def _get_system_headers_impl( self ):
    685          return [code_repository.ctypes_integration.file_name]
    686