def add_overriding_functions(data, scope, classname):
    if data.small_buffer_optimization:
        if data.copy_on_write:
            virtual_clone_into = 'std :: shared_ptr < HandleBase < ' + data.interface_type + ' , Buffer > > clone_into ( Buffer & buffer ) const override '
            virtual_clone_into += '{ if ( HeapAllocated ) return std :: make_shared < ' + classname + ' > ( value_ ) ; ' \
                                  'new ( & buffer ) ' + classname + ' ( value_ ) ; ' \
                                  'return std :: shared_ptr < ' + classname + ' > ( std :: shared_ptr < ' + classname + ' > ( ) , ' \
                                                                                                                                                                                                                              'static_cast < ' + classname + ' * >( static_cast < void * > ( &buffer ) ) ) ; }'
            scope.add(
                cpp_file_parser.get_function_from_text(classname, 'clone_into',
                                                       'return ',
                                                       virtual_clone_into))
        else:
            clone_into = 'HandleBase < ' + data.interface_type + ' , Buffer > * clone_into ( Buffer & buffer ) const override { return ' \
                         'type_erasure_detail :: clone_into < HandleBase < ' + data.interface_type + ' , ' \
                         ' Buffer > , Handle < T , ' + data.interface_type + ' ,  Buffer , false > , ' \
                         'Handle < T , ' + data.interface_type + ' , Buffer , true > > ( value_ , buffer ) ; }'
            scope.add(
                cpp_file_parser.get_function_from_text(classname, 'clone_into',
                                                       'return ', clone_into))
            destroy = 'void destroy ( ) noexcept override { if ( HeapAllocated ) delete this ; ' \
                      'else this -> ~ ' + classname + ' ( ) ; }'
            scope.add(
                cpp_file_parser.get_function_from_text(classname, 'destroy',
                                                       '', destroy))
    else:
        clone = code.get_handle_return_type(data, classname) + 'clone ( ) const override { ' \
                'return ' + code.get_generator(data, classname) + '( value_ ) ; }'
        scope.add(
            cpp_file_parser.get_function_from_text(classname, 'clone',
                                                   'return ', clone))
def add_private_section(data, scope, detail_namespace, classname):
    scope.add(cpp.private_access)

    if data.copy_on_write:
        if data.copy_on_write and data.small_buffer_optimization:
            return_type = data.handle_base_typename
        else:
            return_type = data.handle_base_typename + ' < ' + classname
            if data.small_buffer_optimization:
                return_type += ' , Buffer '
            return_type += ' > '
        return_type += ' & '
        if not data.small_buffer_optimization:
            return_type = return_type.replace(data.handle_base_typename, detail_namespace + ' :: ' + data.handle_base_typename)
        const_return_type = 'const ' + return_type

        scope.add(cpp_file_parser.get_function_from_text(classname, 'read', 'return ',
                                                         code.get_read_function(data, const_return_type,
                                                                                data.impl_member)))
        scope.add(cpp_file_parser.get_function_from_text(classname, 'write', 'return ',
                                                         code.get_write_function(data, return_type)))

    if data.small_buffer_optimization and not data.copy_on_write:
        reset = 'void reset ( ) noexcept { if ( ' + data.impl_member + ' ) ' + data.impl_member + ' -> destroy ( ) ; }'
        scope.add(cpp_file_parser.get_function_from_text(classname, 'reset', '', reset))

    scope.add(cpp.Variable(data.get_impl_type(detail_namespace, classname) + ' ' + data.impl_member + ' = nullptr;'))

    if data.small_buffer_optimization:
        scope.add(cpp.Variable('Buffer buffer_ ;'))
def add_operators(data, scope, classname, detail_namespace):
    # assignment operators
    scope.add(
        cpp_file_parser.get_function_from_text(
            classname, 'operator=', 'return ',
            code.get_assignment_from_value(data, classname, detail_namespace),
            cpp.FUNCTION_TEMPLATE))

    if not data.copy_on_write:
        if not data.non_copyable:
            scope.add(
                cpp_file_parser.get_function_from_text(
                    classname, 'operator=', 'return ',
                    code.get_copy_operator(data, classname)))

        scope.add(
            cpp_file_parser.get_function_from_text(
                classname, 'operator=', 'return ',
                code.get_move_operator(data, classname)))

    # operator bool
    function = cpp_file_parser.get_function_from_text(
        classname, 'operator bool', 'return ',
        code.get_operator_bool_for_member_ptr(data.impl_member))
    comment = code.get_operator_bool_comment(function.get_declaration())
    scope.add(cpp.Comment(comment))
    scope.add(function)
def add_handle_constructors(scope):
    # add templated constructors
    # constructor for values and rvalues
    constructor = 'template < class U , ' + code.get_static_value_check('T','U') + ' > '
    constructor += 'explicit Handle ( U && value ) ' + code.noexcept_if_nothrow_constructible
    constructor += ': value_ ( std :: forward < U > ( value ) ) { }'
    scope.add( cpp_file_parser.get_function_from_text('Handle', 'Handle', '', constructor, 'constructor') )

    # constructor for references
    constructor = 'template < class U , ' + code.static_reference_check + ' > '
    constructor += 'explicit Handle ( U && value ) noexcept : value_ ( value ) { }'
    scope.add( cpp_file_parser.get_function_from_text('Handle', 'Handle', '', constructor, 'constructor') )
def add_pure_virtual_functions_for_small_buffer_optimization(
        data, scope, classname):
    clone_into = 'virtual ' + code.get_handle_return_type(
        data, classname) + 'clone_into ( Buffer & ) const = 0 ;'
    scope.add(
        cpp_file_parser.get_function_from_text(classname, 'clone_into',
                                               'return ', clone_into))
    if not data.copy_on_write:
        destroy = 'virtual void destroy ( ) noexcept = 0 ;'
        scope.add(
            cpp_file_parser.get_function_from_text(classname, 'destroy', '',
                                                   destroy))
Exemple #6
0
def add_casts(data, scope, classname, detail_namespace):
    function = cpp_file_parser.get_function_from_text(classname, 'target', 'return ',
                                                      code.get_cast(data, classname, detail_namespace, ''),
                                                      cpp.FUNCTION_TEMPLATE)
    comment = code.get_handle_cast_comment(function.get_declaration())
    scope.add(cpp.Comment(comment))
    scope.add(function)

    function = cpp_file_parser.get_function_from_text(classname, 'target', 'return ',
                                                      code.get_cast(data, classname, detail_namespace, 'const'),
                                                      cpp.FUNCTION_TEMPLATE)
    comment = code.get_handle_cast_comment(function.get_declaration(), 'const')
    scope.add(cpp.Comment(comment))
    scope.add(function)
 def visit_function(self, function_):
     function = copy.deepcopy(function_)
     tokens = function.tokens[:cpp.get_declaration_end_index(
         function.name, function.tokens)]
     index, offset = cpp.find_function_name(function.name, tokens)
     cpp_file_parser.replace_in_tokens(function.classname,
                                       self.data.interface_type,
                                       tokens[:index])
     function_name = cpp_file_parser.get_function_name_for_type_erasure(
         function)
     code = util.concat(tokens[:index], ' ') + function_name + ' ( '
     cpp_file_parser.replace_in_tokens(function.classname, 'HandleBase',
                                       tokens[index:])
     code += cpp_file_parser.const_specifier(
         function) + self.data.interface_type + ' & '
     for arg in cpp.get_function_arguments(function):
         code += ' , ' + arg.in_declaration()
     code += util.concat(
         tokens[cpp.get_arguments_end_index(function.name, tokens):cpp.
                get_declaration_end_index(function.name, tokens)], ' ')
     if not code.startswith('virtual '):
         code = 'virtual ' + code
     if not code.endswith('= 0'):
         code += ' = 0'
     code += ' ;'
     self.scope.add(
         cpp_file_parser.get_function_from_text(function.classname,
                                                function_name,
                                                function.return_str, code))
Exemple #8
0
    def visit_function(self,function):
        index, offset = cpp.find_function_name(function.name, function.tokens)
#        returns_self = cpp.contains_sequence(function.tokens[:index], [cpp.SimpleToken(function.classname), cpp.SimpleToken('&')])
        returns_self_by_reference = cpp.contains_sequence(function.tokens[:index], [cpp.SimpleToken(function.classname), cpp.SimpleToken('&')])
        member = self.data.impl_const_access if cpp.is_const(function) else self.data.impl_access
        if self.in_private_section:
            return
        code = function.get_declaration()
        code += '{ assert ( ' + self.data.impl_member + ' ) ; '
        code += function.return_str + self.data.function_table_member + ' . ' + cpp_file_parser.get_function_name_for_type_erasure(function)
        code += ' ( '
        if returns_self_by_reference:
            code += '* this , '
        code += member + ' '
        arguments = cpp.get_function_arguments(function)
        for arg in arguments:
            code += ' , '
            if cpp_file_parser.contains(function.classname, arg.tokens):
                code += arg.name() + ' . ' + self.data.impl_raw_member
            else:
                code += arg.in_single_function_call()
        code += ' ) ; }'

        self.scope.add(cpp_file_parser.get_function_from_text(self.classname,function.name,function.return_str,
                                                              code))
    def visit_function(self,function):
        if self.in_private_section:
            return

        code = util.concat(function.tokens[:cpp.get_declaration_end_index(function.name, function.tokens)], ' ')
        code += ' { assert ( ' + self.data.impl_member + ' ) ; ' + function.return_str
        if self.data.copy_on_write:
            if cpp.is_const(function):
                code += 'read ( ) . '
            else:
                code += 'write ( ) . '
        else:
            code += self.data.impl_member + ' -> '
        code += cpp_file_parser.get_function_name_for_type_erasure(function) + ' ( * this '
        arguments = cpp.get_function_arguments(function)
        for arg in arguments:
            code += ' , '
            if self.scope.get_open_scope().name + ' &' in arg.type():
                code += ' * ' + arg.in_single_function_call() + ' . ' + self.data.impl_member + ' '
            elif self.scope.get_open_scope().name + ' *' in arg.type():
                    code += arg.in_single_function_call() + ' -> ' + self.data.impl_member
            else:
                code += arg.in_single_function_call()
        code += ' ) ; }'

        self.scope.add(cpp_file_parser.get_function_from_text(function.classname, function.name, function.return_str, code))
    def visit_function(self, function):
        if self.in_private_section:
            return

        code = util.concat(
            function.tokens[:cpp.get_declaration_end_index(
                function.name, function.tokens)], ' ')
        code += ' { assert ( ' + self.data.impl_member + ' ) ; ' + function.return_str
        if self.data.copy_on_write:
            if cpp.is_const(function):
                code += 'read ( ) . '
            else:
                code += 'write ( ) . '
        else:
            code += self.data.impl_member + ' -> '
        code += cpp_file_parser.get_function_name_for_type_erasure(
            function) + ' ( * this '
        arguments = cpp.get_function_arguments(function)
        for arg in arguments:
            code += ' , '
            if self.scope.get_open_scope().name + ' &' in arg.type():
                code += ' * ' + arg.in_single_function_call(
                ) + ' . ' + self.data.impl_member + ' '
            elif self.scope.get_open_scope().name + ' *' in arg.type():
                code += arg.in_single_function_call(
                ) + ' -> ' + self.data.impl_member
            else:
                code += arg.in_single_function_call()
        code += ' ) ; }'

        self.scope.add(
            cpp_file_parser.get_function_from_text(function.classname,
                                                   function.name,
                                                   function.return_str, code))
def add_handle_constructors(scope):
    # add templated constructors
    # constructor for values and rvalues
    constructor = 'template < class U , ' + code.get_static_value_check(
        'T', 'U') + ' > '
    constructor += 'explicit Handle ( U && value ) ' + code.noexcept_if_nothrow_constructible
    constructor += ': value_ ( std :: forward < U > ( value ) ) { }'
    scope.add(
        cpp_file_parser.get_function_from_text('Handle', 'Handle', '',
                                               constructor, 'constructor'))

    # constructor for references
    constructor = 'template < class U , ' + code.static_reference_check + ' > '
    constructor += 'explicit Handle ( U && value ) noexcept : value_ ( value ) { }'
    scope.add(
        cpp_file_parser.get_function_from_text('Handle', 'Handle', '',
                                               constructor, 'constructor'))
def add_constructors(data, scope, class_scope, detail_namespace):
    classname = class_scope.get_name()
    constexpr = '' if data.small_buffer_optimization else 'constexpr'
    constructor = code.get_default_default_constructor(classname,'noexcept',constexpr)
    scope.add( cpp_file_parser.get_function_from_text(classname, classname, '',
                                                      constructor,
                                                      cpp.CONSTRUCTOR) )
    scope.add(cpp_file_parser.get_function_from_text(classname, classname, '',
                                                 code.get_handle_constructor(data, classname, detail_namespace),
                                                 cpp.CONSTRUCTOR_TEMPLATE))
    if not data.copy_on_write:
        if not data.non_copyable:
            scope.add(cpp_file_parser.get_function_from_text(classname, classname, '',
                                                             code.get_copy_constructor(data, classname),
                                                             cpp.CONSTRUCTOR))
        scope.add( cpp_file_parser.get_function_from_text(classname, classname, '',
                                                          code.get_move_constructor(data, classname),
                                                          cpp.CONSTRUCTOR) )
def add_operators(data, scope, classname, detail_namespace):
    # assignment operators
    scope.add(cpp_file_parser.get_function_from_text(classname, 'operator=', 'return ',
                                                     code.get_assignment_from_value(data, classname, detail_namespace),
                                                     cpp.FUNCTION_TEMPLATE))

    if not data.copy_on_write or data.small_buffer_optimization:
        if not data.non_copyable:
            scope.add(cpp_file_parser.get_function_from_text(classname, 'operator=', 'return ',
                                                             code.get_copy_operator(data, classname)))

        scope.add(cpp_file_parser.get_function_from_text(classname, 'operator=', 'return ',
                                                         code.get_move_operator(data, classname)))

    # operator bool
    function = cpp_file_parser.get_function_from_text(classname, 'operator bool', 'return ',
                                                      code.get_operator_bool_for_member_ptr(data.impl_member))
    comment = code.get_operator_bool_comment(function.get_declaration())
    scope.add(cpp.Comment(comment))
    scope.add(function)
def add_private_section(data, scope, detail_namespace, classname):
    scope.add(cpp.private_access)

    if data.copy_on_write:
        if data.copy_on_write and data.small_buffer_optimization:
            return_type = data.handle_base_typename
        else:
            return_type = data.handle_base_typename + ' < ' + classname
            if data.small_buffer_optimization:
                return_type += ' , Buffer '
            return_type += ' > '
        return_type += ' & '
        if not data.small_buffer_optimization:
            return_type = return_type.replace(
                data.handle_base_typename,
                detail_namespace + ' :: ' + data.handle_base_typename)
        const_return_type = 'const ' + return_type

        scope.add(
            cpp_file_parser.get_function_from_text(
                classname, 'read', 'return ',
                code.get_read_function(data, const_return_type,
                                       data.impl_member)))
        scope.add(
            cpp_file_parser.get_function_from_text(
                classname, 'write', 'return ',
                code.get_write_function(data, return_type)))

    if data.small_buffer_optimization and not data.copy_on_write:
        reset = 'void reset ( ) noexcept { if ( ' + data.impl_member + ' ) ' + data.impl_member + ' -> destroy ( ) ; }'
        scope.add(
            cpp_file_parser.get_function_from_text(classname, 'reset', '',
                                                   reset))

    scope.add(
        cpp.Variable(
            data.get_impl_type(detail_namespace, classname) + ' ' +
            data.impl_member + ' = nullptr;'))

    if data.small_buffer_optimization:
        scope.add(cpp.Variable('Buffer buffer_ ;'))
Exemple #15
0
def add_private_section(data, scope, detail_namespace, classname):
    scope.add(cpp.private_access)

    if data.copy_on_write:
        return_type = 'void *'
        const_return_type = return_type
        scope.add(cpp_file_parser.get_function_from_text(classname, 'read', 'return ',
                                                         code.get_read_function(data, const_return_type,
                                                                                data.impl_member)))
        scope.add(cpp_file_parser.get_function_from_text(classname, 'write', 'return ',
                                                         code.get_write_function(data, return_type)))

    function_table_var = detail_namespace + '::' + data.function_table_type + '<' + classname
    if data.small_buffer_optimization:
        function_table_var += ', Buffer'
    function_table_var += '>' + data.function_table_member + ';'
    scope.add(cpp.Variable(function_table_var))
    if not data.no_rtti:
        scope.add(cpp.Variable('std::size_t type_id_;'))

    if data.copy_on_write:
        scope.add(cpp.Variable('std::shared_ptr<void> ' + data.impl_member + ' = nullptr;'))
    else:
        scope.add(cpp.Variable('void* ' + data.impl_member + ' = nullptr;'))

    if not data.copy_on_write:
        reset = 'void reset ( ) noexcept { if ( ' + data.impl_member + ' '
        if data.small_buffer_optimization:
            reset += ' && type_erasure_table_detail :: is_heap_allocated ( ' + data.impl_raw_member + ' , buffer_ ) '
        reset += ') ' + data.function_table_member + ' . del ( ' + data.impl_raw_member + ' ) ; }'
        scope.add(cpp_file_parser.get_function_from_text(classname, 'reset', '', reset))

        if not data.non_copyable and data.small_buffer_optimization:
            clone_into = 'void * clone_into ( Buffer & buffer ) const { if ( ! ' + data.impl_member + ' ) return nullptr ; '
            clone_into += 'if ( type_erasure_table_detail :: is_heap_allocated ( ' + data.impl_raw_member + ' , buffer_ ) ) '
            clone_into += 'return ' + data.function_table_member + ' . clone ( ' + data.impl_member + ' ) ; else '
            clone_into += 'return ' + data.function_table_member + ' . clone_into ( ' + data.impl_member + ' , buffer ) ; }'
            scope.add(cpp_file_parser.get_function_from_text(classname, 'clone_into', 'return ', clone_into))

    if data.small_buffer_optimization:
        scope.add(cpp.Variable('Buffer buffer_ ;'))
Exemple #16
0
def add_constructors(data, scope, class_scope, detail_namespace):
    classname = class_scope.get_name()
    constructor = classname + ' ( ) noexcept : ' + data.impl_member + ' ( nullptr ) { }'
    scope.add( cpp_file_parser.get_function_from_text(classname, classname, '',
                                                      constructor,
                                                      cpp.CONSTRUCTOR) )

    table_constructor_extractor = TableConstructorExtractor(data, class_scope.get_name(), detail_namespace)
    class_scope.visit(table_constructor_extractor)
    constructor = table_constructor_extractor.constructor + table_constructor_extractor.constructor_end
    scope.add(cpp_file_parser.get_function_from_text(class_scope.get_name(), class_scope.get_name(), '',
                                                     constructor,
                                                     cpp.CONSTRUCTOR_TEMPLATE))
    if not data.copy_on_write or data.small_buffer_optimization:
        if not data.non_copyable:
            scope.add(cpp_file_parser.get_function_from_text(classname, classname, '',
                                                             code.get_copy_constructor(data, classname),
                                                             cpp.CONSTRUCTOR))
        scope.add( cpp_file_parser.get_function_from_text(classname, classname, '',
                                                          code.get_move_constructor(data, classname),
                                                          cpp.CONSTRUCTOR) )
Exemple #17
0
def add_default_interface(data, scope, class_scope, detail_namespace):
    classname = class_scope.get_name()
    scope.add( cpp.private_access )
    add_aliases(data, scope, detail_namespace)
    scope.add( cpp.public_access )
    add_constructors(data, scope, class_scope, detail_namespace)
    if not data.copy_on_write:
            destructor = '~ ' + classname + ' ( ) { reset ( ) ; }'
            scope.add( cpp_file_parser.get_function_from_text(classname, '~'+classname, '',
                                                                 destructor, 'destructor'))

    add_operators(data, scope, classname, detail_namespace)
def add_overriding_functions(data, scope, classname):
    if data.small_buffer_optimization:
        if data.copy_on_write:
            virtual_clone_into = 'std :: shared_ptr < HandleBase < ' + data.interface_type + ' , Buffer > > clone_into ( Buffer & buffer ) const override '
            virtual_clone_into += '{ if ( HeapAllocated ) return std :: make_shared < ' + classname + ' > ( value_ ) ; ' \
                                  'new ( & buffer ) ' + classname + ' ( value_ ) ; ' \
                                  'return std :: shared_ptr < ' + classname + ' > ( std :: shared_ptr < ' + classname + ' > ( ) , ' \
                                                                                                                                                                                                                              'static_cast < ' + classname + ' * >( static_cast < void * > ( &buffer ) ) ) ; }'
            scope.add(cpp_file_parser.get_function_from_text(classname, 'clone_into', 'return ', virtual_clone_into))
        else:
            clone_into = 'HandleBase < ' + data.interface_type + ' , Buffer > * clone_into ( Buffer & buffer ) const override { return ' \
                         'type_erasure_detail :: clone_into < HandleBase < ' + data.interface_type + ' , ' \
                         ' Buffer > , Handle < T , ' + data.interface_type + ' ,  Buffer , false > , ' \
                         'Handle < T , ' + data.interface_type + ' , Buffer , true > > ( value_ , buffer ) ; }'
            scope.add(cpp_file_parser.get_function_from_text(classname, 'clone_into', 'return ', clone_into))
            destroy = 'void destroy ( ) noexcept override { if ( HeapAllocated ) delete this ; ' \
                      'else this -> ~ ' + classname + ' ( ) ; }'
            scope.add(cpp_file_parser.get_function_from_text(classname, 'destroy', '', destroy))
    else:
        clone = code.get_handle_return_type(data, classname) + 'clone ( ) const override { ' \
                'return ' + code.get_generator(data, classname) + '( value_ ) ; }'
        scope.add(cpp_file_parser.get_function_from_text(classname, 'clone', 'return ', clone))
def add_constructors(data, scope, class_scope, detail_namespace):
    classname = class_scope.get_name()
    constexpr = '' if data.small_buffer_optimization else 'constexpr'
    constructor = code.get_default_default_constructor(classname, 'noexcept',
                                                       constexpr)
    scope.add(
        cpp_file_parser.get_function_from_text(classname, classname, '',
                                               constructor, cpp.CONSTRUCTOR))
    scope.add(
        cpp_file_parser.get_function_from_text(
            classname, classname, '',
            code.get_handle_constructor(data, classname, detail_namespace),
            cpp.CONSTRUCTOR_TEMPLATE))
    if not data.copy_on_write:
        if not data.non_copyable:
            scope.add(
                cpp_file_parser.get_function_from_text(
                    classname, classname, '',
                    code.get_copy_constructor(data, classname),
                    cpp.CONSTRUCTOR))
        scope.add(
            cpp_file_parser.get_function_from_text(
                classname, classname, '',
                code.get_move_constructor(data, classname), cpp.CONSTRUCTOR))
    def visit_function(self,function_):
        function = copy.deepcopy(function_)
        tokens = function.tokens[:cpp.get_declaration_end_index(function.name, function.tokens)]
        index, offset = cpp.find_function_name(function.name, function.tokens)
        cpp_file_parser.replace_in_tokens(function.classname, self.data.interface_type, tokens[:index])
        function_name = cpp_file_parser.get_function_name_for_type_erasure(function)
        code = util.concat(tokens[:index], ' ') + function_name + ' ( '
        cpp_file_parser.replace_in_tokens(function.classname, 'HandleBase', tokens[index:])
        code += cpp_file_parser.const_specifier(function) + self.data.interface_type + ' & ' + self.data.interface_variable + ' '
        for arg in cpp.get_function_arguments(function):
            if 'HandleBase' in arg.type():
                cpp_file_parser.replace_in_tokens('HandleBase', self.data.handle_base_type, arg.tokens)
            code += ' , ' + arg.in_declaration()
        code += util.concat(tokens[cpp.get_arguments_end_index(function.name, tokens):
        cpp.get_declaration_end_index(function.name, tokens)], ' ')

        if code.startswith('virtual '):
            code = code[len('virtual '):]
        if code.endswith(' = 0'):
            code = code[:-len(' = 0')]

        code += 'override { '
        contains_class_ref = util.concat(tokens[:index], ' ') in ['const ' + self.data.interface_type + ' & ',
                                                                  self.data.interface_type + ' & ']
        if not contains_class_ref:
            code += function.return_str
        code += 'value_ . ' + function.name + ' ( '

        arguments = cpp.get_function_arguments(function)
        for arg in arguments:
            if arg.type() == 'const HandleBase & ':
                code += 'static_cast < ' + 'const ' + self.data.handle_type + ' & > ( '
                code += arg.name() + ' ) . value_ '
            elif arg.type() == 'HandleBase & ':
                code += 'static_cast < ' + self.data.handle_type + ' & > ( '
                code += arg.name() + ' ) . value_ '
            else:
                code += arg.in_single_function_call()
            if arg is not arguments[-1]:
                code += ' , '

        code += ' ) ; '
        if contains_class_ref:
            code += 'return ' + self.data.interface_variable + ' ;'
        code += ' }'

        self.scope.add(cpp_file_parser.get_function_from_text(function.classname, function_name,
                                                  function.return_str, code))
Exemple #21
0
    def visit_class(self, class_object):
        if class_object.get_name() != self.data.classname:
            return

        class_object.content.append(
            cpp_file_parser.AccessSpecifier(cpp_file_parser.PUBLIC))

        default_constructor = self.data.classname + ' ( ) '
        if self.data.implicit_default_constructor:
            default_constructor += ': pimpl_( new ' + self.data.private_classname + ' ( ) ) { }'
        else:
            default_constructor += '{ }'
        class_object.content.append(
            cpp_file_parser.get_function_from_text(
                self.data.classname, self.data.classname, '',
                default_constructor, cpp_file_parser.CONSTRUCTOR))
        destructor = '~ ' + self.data.classname + ' ( ) { } '
        class_object.content.append(
            cpp_file_parser.get_function_from_text(self.data.classname,
                                                   '~' + self.data.classname,
                                                   '', destructor,
                                                   cpp_file_parser.DESTRUCTOR))

        if not self.data.non_copyable:
            copy_assignment = code.get_pimpl_copy_assignment(
                self.data, self.data.classname, self.data.private_classname,
                'pimpl_')
            class_object.content.append(
                cpp_file_parser.get_function_from_text(
                    self.data.classname, 'operator=', '', copy_assignment,
                    cpp_file_parser.ASSIGNMENT_OPERATOR))
            copy_constructor = code.get_pimpl_copy_constructor(
                self.data, self.data.classname, self.data.private_classname,
                'pimpl_')
            class_object.content.append(
                cpp_file_parser.get_function_from_text(
                    self.data.classname, self.data.classname, '',
                    copy_constructor, cpp_file_parser.CONSTRUCTOR))

        if not self.data.non_moveable:
            move_assignment = code.get_pimpl_move_assignment(
                self.data, self.data.classname, 'pimpl_')
            class_object.content.append(
                cpp_file_parser.get_function_from_text(
                    self.data.classname, 'operator=', '', move_assignment,
                    cpp_file_parser.ASSIGNMENT_OPERATOR))
            move_constructor = code.get_pimpl_move_constructor(
                self.data, self.data.classname, 'pimpl_')
            class_object.content.append(
                cpp_file_parser.get_function_from_text(
                    self.data.classname, self.data.classname, '',
                    move_constructor, cpp_file_parser.CONSTRUCTOR))
def add_handle_base(data, scope, class_scope):
    classname = 'HandleBase'

    handle_base = 'template < class ' + data.interface_type
    if data.small_buffer_optimization:
        handle_base += ', class Buffer '
    handle_base += '> struct HandleBase'
    scope.add(cpp.get_template_struct_from_text(classname, handle_base))

    destructor = 'virtual ~ ' + classname + ' ( ) = default ;'
    scope.add( cpp_file_parser.get_function_from_text(classname, '~' + classname, '', destructor, 'destructor') )
    if data.small_buffer_optimization:
        add_pure_virtual_functions_for_small_buffer_optimization(data, scope, classname)
    else:
        add_pure_virtual_clone_function(data, scope, classname)

    class_scope.visit(PureVirtualFunctionExtractor(data, scope))

    scope.close()
 def visit_function(self,function_):
     function = copy.deepcopy(function_)
     tokens = function.tokens[:cpp.get_declaration_end_index(function.name, function.tokens)]
     index, offset = cpp.find_function_name(function.name, tokens)
     cpp_file_parser.replace_in_tokens(function.classname, self.data.interface_type, tokens[:index])
     function_name = cpp_file_parser.get_function_name_for_type_erasure(function)
     code = util.concat(tokens[:index], ' ') + function_name + ' ( '
     cpp_file_parser.replace_in_tokens(function.classname, 'HandleBase', tokens[index:])
     code += cpp_file_parser.const_specifier(function) + self.data.interface_type + ' & '
     for arg in cpp.get_function_arguments(function):
         code += ' , ' + arg.in_declaration()
     code += util.concat(tokens[cpp.get_arguments_end_index(function.name, tokens):
     cpp.get_declaration_end_index(function.name, tokens)], ' ')
     if not code.startswith('virtual '):
         code = 'virtual ' + code
     if not code.endswith('= 0'):
         code += ' = 0'
     code += ' ;'
     self.scope.add(cpp_file_parser.get_function_from_text(function.classname, function_name,
                                                           function.return_str, code))
def add_handle_base(data, scope, class_scope):
    classname = 'HandleBase'

    handle_base = 'template < class ' + data.interface_type
    if data.small_buffer_optimization:
        handle_base += ', class Buffer '
    handle_base += '> struct HandleBase'
    scope.add(cpp.get_template_struct_from_text(classname, handle_base))

    destructor = 'virtual ~ ' + classname + ' ( ) = default ;'
    scope.add(
        cpp_file_parser.get_function_from_text(classname, '~' + classname, '',
                                               destructor, 'destructor'))
    if data.small_buffer_optimization:
        add_pure_virtual_functions_for_small_buffer_optimization(
            data, scope, classname)
    else:
        add_pure_virtual_clone_function(data, scope, classname)

    class_scope.visit(PureVirtualFunctionExtractor(data, scope))

    scope.close()
    def visit_class(self,class_object):
        if class_object.get_name() != self.data.classname:
            return

        class_object.content.append(cpp_file_parser.AccessSpecifier(cpp_file_parser.PUBLIC))

        default_constructor = self.data.classname + ' ( ) '
        if self.data.implicit_default_constructor:
            default_constructor += ': pimpl_( new ' + self.data.private_classname + ' ( ) ) { }'
        else:
            default_constructor += '{ }'
        class_object.content.append(cpp_file_parser.get_function_from_text(self.data.classname, self.data.classname,
                                                                           '', default_constructor,
                                                                           cpp_file_parser.CONSTRUCTOR))
        destructor = '~ ' + self.data.classname + ' ( ) { } '
        class_object.content.append(cpp_file_parser.get_function_from_text(self.data.classname,
                                                                           '~' + self.data.classname,
                                                                           '', destructor,
                                                                           cpp_file_parser.DESTRUCTOR))

        if not self.data.non_copyable:
            copy_assignment = code.get_pimpl_copy_assignment(self.data, self.data.classname,
                                                             self.data.private_classname, 'pimpl_')
            class_object.content.append(cpp_file_parser.get_function_from_text(self.data.classname, 'operator=',
                                                                               '', copy_assignment,
                                                                               cpp_file_parser.ASSIGNMENT_OPERATOR))
            copy_constructor = code.get_pimpl_copy_constructor(self.data, self.data.classname,
                                                               self.data.private_classname, 'pimpl_')
            class_object.content.append(cpp_file_parser.get_function_from_text(self.data.classname, self.data.classname,
                                                                               '', copy_constructor,
                                                                               cpp_file_parser.CONSTRUCTOR))

        if not self.data.non_moveable:
            move_assignment = code.get_pimpl_move_assignment(self.data, self.data.classname, 'pimpl_')
            class_object.content.append(cpp_file_parser.get_function_from_text(self.data.classname, 'operator=',
                                                                               '', move_assignment,
                                                                               cpp_file_parser.ASSIGNMENT_OPERATOR))
            move_constructor = code.get_pimpl_move_constructor(self.data, self.data.classname, 'pimpl_')
            class_object.content.append(cpp_file_parser.get_function_from_text(self.data.classname, self.data.classname,
                                                                               '', move_constructor,
                                                                               cpp_file_parser.CONSTRUCTOR))
def add_pure_virtual_clone_function(data, scope, classname):
    clone = 'virtual ' + code.get_handle_return_type(data, classname) + 'clone ( ) const = 0 ;'
    scope.add( cpp_file_parser.get_function_from_text(classname, 'clone', 'return ', clone) )
def add_pure_virtual_clone_function(data, scope, classname):
    clone = 'virtual ' + code.get_handle_return_type(
        data, classname) + 'clone ( ) const = 0 ;'
    scope.add(
        cpp_file_parser.get_function_from_text(classname, 'clone', 'return ',
                                               clone))
    def visit_function(self,function_):
        function = copy.deepcopy(function_)
        name = cpp_file_parser.get_function_name_for_type_erasure(function)
        index, offset = cpp.find_function_name(function.name, function.tokens)
        returns_self = util.contains(function.tokens[:index], function.classname)
        returns_self_by_reference = cpp.contains_sequence(function.tokens[:index],
                                                          [cpp.SimpleToken(function.classname), cpp.SimpleToken('&')])
        if returns_self:
            cpp_file_parser.replace_in_tokens(function.classname, self.data.interface_type, function.tokens[:index])
        arguments = copy.deepcopy(cpp.get_function_arguments(function))

        wrapper = 'static ' + util.concat(function.tokens[:index], ' ')
        wrapper += name + ' ( '
        if returns_self_by_reference:
            wrapper += cpp_file_parser.const_specifier(function) + self.data.interface_type + ' & ' + self.data.interface_variable + ' , '
        wrapper += ' void * impl '
        for arg in arguments:
            if cpp_file_parser.contains(function.classname, arg.tokens):
                wrapper += ' , void * ' + arg.tokens[-1].spelling
            else:
                wrapper += ' , ' + arg.in_declaration()
        wrapper += ' ) '
        if 'noexcept' in function.tokens[cpp.get_arguments_end_index(function.name, function.tokens):
                                         cpp.get_declaration_end_index(function.name, function.tokens)]:
            wrapper += 'noexcept '

        wrapper += '{ '
        returns_class_ref = cpp.returns_class_ref(self.data.interface_type, function)
        if not returns_class_ref:
            wrapper +=  function.return_str + ' '
        wrapper += 'static_cast '
        const = 'const ' if cpp.is_const(function) else ''
        if self.for_reference_wrapper:
            wrapper += '< std :: reference_wrapper < Impl > * > ( impl ) -> get ( ) . '
        else:
            wrapper += '< ' + const + ' Impl * > ( impl ) -> '
        wrapper += function.name + ' ( '
        for arg in arguments:
            if cpp_file_parser.contains(function.classname, arg.tokens):
                typename = util.concat(arg.tokens[:-1], ' ')
                typename = typename.replace(' ' + function.classname + ' ', ' Impl ')

                if self.for_reference_wrapper:
                    if typename.endswith('* '):
                        wrapper += '& '
                    wrapper += 'static_cast < std :: reference_wrapper < Impl > * > ( ' + arg.in_single_function_call()
                    wrapper += ' ) -> get ( )'
                else:
                    if typename.endswith('& '):
                        wrapper += '* '
                    wrapper += 'static_cast< ' + ('const ' if cpp.is_const(function) else '')
                    wrapper += 'Impl * > ( ' + arg.in_single_function_call() + ' )'
            else:
                wrapper += arg.in_single_function_call()
            if arg is not arguments[-1]:
                wrapper += ' ,  '
        wrapper += ' ) ; '
        if returns_class_ref:
            wrapper += 'return interface ; '
        wrapper += '}'

        self.scope.add(cpp_file_parser.get_function_from_text('execution_wrapper', name, function.return_str,
                                                              wrapper))
    def visit_function(self, function_):
        function = copy.deepcopy(function_)
        tokens = function.tokens[:cpp.get_declaration_end_index(
            function.name, function.tokens)]
        index, offset = cpp.find_function_name(function.name, function.tokens)
        cpp_file_parser.replace_in_tokens(function.classname,
                                          self.data.interface_type,
                                          tokens[:index])
        function_name = cpp_file_parser.get_function_name_for_type_erasure(
            function)
        code = util.concat(tokens[:index], ' ') + function_name + ' ( '
        cpp_file_parser.replace_in_tokens(function.classname, 'HandleBase',
                                          tokens[index:])
        code += cpp_file_parser.const_specifier(
            function
        ) + self.data.interface_type + ' & ' + self.data.interface_variable + ' '
        for arg in cpp.get_function_arguments(function):
            if 'HandleBase' in arg.type():
                cpp_file_parser.replace_in_tokens('HandleBase',
                                                  self.data.handle_base_type,
                                                  arg.tokens)
            code += ' , ' + arg.in_declaration()
        code += util.concat(
            tokens[cpp.get_arguments_end_index(function.name, tokens):cpp.
                   get_declaration_end_index(function.name, tokens)], ' ')

        if code.startswith('virtual '):
            code = code[len('virtual '):]
        if code.endswith(' = 0'):
            code = code[:-len(' = 0')]

        code += 'override { '
        contains_class_ref = util.concat(tokens[:index], ' ') in [
            'const ' + self.data.interface_type + ' & ',
            self.data.interface_type + ' & '
        ]
        if not contains_class_ref:
            code += function.return_str
        code += 'value_ . ' + function.name + ' ( '

        arguments = cpp.get_function_arguments(function)
        for arg in arguments:
            if arg.type() == 'const HandleBase & ':
                code += 'static_cast < ' + 'const ' + self.data.handle_type + ' & > ( '
                code += arg.name() + ' ) . value_ '
            elif arg.type() == 'HandleBase & ':
                code += 'static_cast < ' + self.data.handle_type + ' & > ( '
                code += arg.name() + ' ) . value_ '
            else:
                code += arg.in_single_function_call()
            if arg is not arguments[-1]:
                code += ' , '

        code += ' ) ; '
        if contains_class_ref:
            code += 'return ' + self.data.interface_variable + ' ;'
        code += ' }'

        self.scope.add(
            cpp_file_parser.get_function_from_text(function.classname,
                                                   function_name,
                                                   function.return_str, code))
def add_pure_virtual_functions_for_small_buffer_optimization(data, scope, classname):
    clone_into = 'virtual ' + code.get_handle_return_type(data, classname) + 'clone_into ( Buffer & ) const = 0 ;'
    scope.add(cpp_file_parser.get_function_from_text(classname, 'clone_into', 'return ', clone_into))
    if not data.copy_on_write:
        destroy = 'virtual void destroy ( ) noexcept = 0 ;'
        scope.add(cpp_file_parser.get_function_from_text(classname, 'destroy', '', destroy))