⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classexporter.py

📁 C++的一个好库。。。现在很流行
💻 PY
📖 第 1 页 / 共 3 页
字号:
        overloads = '_overloads_%i_%i' % (method.minArgs, method.maxArgs)    
        return name + overloads

    
    def GetAddedMethods(self):
        added_methods = self.info.__added__
        result = []
        if added_methods:
            for name, rename in added_methods:
                decl = self.GetDeclaration(name)
                self.info[name].rename = rename
                result.append(decl)
        return result

                
    def ExportMethods(self):
        '''Export all the non-virtual methods of this class, plus any function
        that is to be exported as a method'''
            
        declared = {}
        def DeclareOverloads(m):
            'Declares the macro for the generation of the overloads'
            if (isinstance(m, Method) and m.static) or type(m) == Function:
                func = m.FullName()
                macro = 'BOOST_PYTHON_FUNCTION_OVERLOADS'
            else:
                func = m.name
                macro = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS' 
            code = '%s(%s, %s, %i, %i)\n' % (macro, self.OverloadName(m), func, m.minArgs, m.maxArgs)
            if code not in declared:
                declared[code] = True
                self.Add('declaration', code)


        def Pointer(m):
            'returns the correct pointer declaration for the method m'
            # check if this method has a wrapper set for him
            wrapper = self.info[m.name].wrapper
            if wrapper:
                return '&' + wrapper.FullName()
            else:
                return m.PointerDeclaration() 

        def IsExportable(m):
            'Returns true if the given method is exportable by this routine'
            ignore = (Constructor, ClassOperator, Destructor)
            return isinstance(m, Function) and not isinstance(m, ignore) and not m.virtual        
        
        methods = [x for x in self.public_members if IsExportable(x)]        
        methods.extend(self.GetAddedMethods())
        
        staticmethods = {}
        
        for method in methods:
            method_info = self.info[method.name]
            
            # skip this method if it was excluded by the user
            if method_info.exclude:
                continue 

            # rename the method if the user requested
            name = method_info.rename or method.name
            
            # warn the user if this method needs a policy and doesn't have one
            method_info.policy = exporterutils.HandlePolicy(method, method_info.policy)
            
            # check for policies
            policy = method_info.policy or ''
            if policy:
                policy = ', %s%s()' % (namespaces.python, policy.Code())
            # check for overloads
            overload = ''
            if method.minArgs != method.maxArgs and not method_info.wrapper: 
                # add the overloads for this method
                DeclareOverloads(method)
                overload_name = self.OverloadName(method)
                overload = ', %s%s()' % (namespaces.pyste, overload_name)
        
            # build the .def string to export the method
            pointer = Pointer(method)
            code = '.def("%s", %s' % (name, pointer)
            code += policy
            code += overload
            code += ')'
            self.Add('inside', code)
            # static method
            if isinstance(method, Method) and method.static:
                staticmethods[name] = 1
            # add wrapper code if this method has one
            wrapper = method_info.wrapper
            if wrapper and wrapper.code:
                self.Add('declaration', wrapper.code)
        
        # export staticmethod statements
        for name in staticmethods:
            code = '.staticmethod("%s")' % name
            self.Add('inside', code) 


                
    def MakeNonVirtual(self):
        '''Make all methods that the user indicated to no_override no more virtual, delegating their
        export to the ExportMethods routine'''
        for member in self.class_:
            if type(member) == Method and member.virtual:
                member.virtual = not self.info[member.name].no_override 


    def ExportVirtualMethods(self, codeunit):        
        # check if this class has any virtual methods
        has_virtual_methods = False
        for member in self.class_:
            if type(member) == Method and member.virtual:
                has_virtual_methods = True
                break

        holder = self.info.holder
        if has_virtual_methods:
            generator = _VirtualWrapperGenerator(self.class_, self.ClassBases(), self.info, codeunit)
            if holder:
                self.Add('template', holder(generator.FullName()))
            else:
                self.Add('template', generator.FullName())
            for definition in generator.GenerateDefinitions():
                self.Add('inside', definition)
            self.Add('declaration', generator.GenerateVirtualWrapper(self.INDENT))
        else:
            if holder:
                self.Add('template', holder(self.class_.FullName()))

    # operators natively supported by boost
    BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -= '\
        '*= /= %= ^= &= |= <<= >>='.split()
    # create a map for faster lookup
    BOOST_SUPPORTED_OPERATORS = dict(zip(BOOST_SUPPORTED_OPERATORS, range(len(BOOST_SUPPORTED_OPERATORS))))

    # a dict of operators that are not directly supported by boost, but can be exposed
    # simply as a function with a special name
    BOOST_RENAME_OPERATORS = {
        '()' : '__call__',
    }

    # converters which have a special name in python
    # it's a map of a regular expression of the converter's result to the
    # appropriate python name
    SPECIAL_CONVERTERS = {
        re.compile(r'(const)?\s*double$') : '__float__',
        re.compile(r'(const)?\s*float$') : '__float__',
        re.compile(r'(const)?\s*int$') : '__int__',
        re.compile(r'(const)?\s*long$') : '__long__',
        re.compile(r'(const)?\s*char\s*\*?$') : '__str__',
        re.compile(r'(const)?.*::basic_string<.*>\s*(\*|\&)?$') : '__str__',
    }
        
    
    def ExportOperators(self):
        'Export all member operators and free operators related to this class'
        
        def GetFreeOperators():
            'Get all the free (global) operators related to this class'
            operators = []
            for decl in self.declarations:
                if isinstance(decl, Operator):
                    # check if one of the params is this class
                    for param in decl.parameters:
                        if param.name == self.class_.FullName():
                            operators.append(decl)
                            break
            return operators

        def GetOperand(param):
            'Returns the operand of this parameter (either "self", or "other<type>")'
            if param.name == self.class_.FullName():
                return namespaces.python + 'self'
            else:
                return namespaces.python + ('other< %s >()' % param.name)


        def HandleSpecialOperator(operator):
            # gatter information about the operator and its parameters
            result_name = operator.result.name                        
            param1_name = ''
            if operator.parameters:
                param1_name = operator.parameters[0].name
                
            # check for str
            ostream = 'basic_ostream'
            is_str = result_name.find(ostream) != -1 and param1_name.find(ostream) != -1
            if is_str:
                namespace = namespaces.python + 'self_ns::'
                self_ = namespaces.python + 'self'
                return '.def(%sstr(%s))' % (namespace, self_)

            # is not a special operator
            return None
                

        
        frees = GetFreeOperators()
        members = [x for x in self.public_members if type(x) == ClassOperator]
        all_operators = frees + members
        operators = [x for x in all_operators if not self.info['operator'][x.name].exclude]
        
        for operator in operators:
            # gatter information about the operator, for use later
            wrapper = self.info['operator'][operator.name].wrapper
            if wrapper:
                pointer = '&' + wrapper.FullName()
                if wrapper.code:
                    self.Add('declaration-outside', wrapper.code)
            else:
                pointer = operator.PointerDeclaration()                 
            rename = self.info['operator'][operator.name].rename

            # check if this operator will be exported as a method
            export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS
            
            # check if this operator has a special representation in boost
            special_code = HandleSpecialOperator(operator)
            has_special_representation = special_code is not None
            
            if export_as_method:
                # export this operator as a normal method, renaming or using the given wrapper
                if not rename:
                    if wrapper:
                        rename = wrapper.name
                    else:
                        rename = self.BOOST_RENAME_OPERATORS[operator.name]
                policy = ''
                policy_obj = self.info['operator'][operator.name].policy
                if policy_obj:
                    policy = ', %s()' % policy_obj.Code() 
                self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy))
            
            elif has_special_representation:
                self.Add('inside', special_code)
                
            elif operator.name in self.BOOST_SUPPORTED_OPERATORS:
                # export this operator using boost's facilities
                op = operator
                is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\
                           isinstance(op, ClassOperator) and len(op.parameters) == 0
                if is_unary:
                    self.Add('inside', '.def( %s%sself )' % \
                        (operator.name, namespaces.python))
                else:
                    # binary operator
                    if len(operator.parameters) == 2:
                        left_operand = GetOperand(operator.parameters[0])
                        right_operand = GetOperand(operator.parameters[1])
                    else:
                        left_operand = namespaces.python + 'self'
                        right_operand = GetOperand(operator.parameters[0])
                    self.Add('inside', '.def( %s %s %s )' % \
                        (left_operand, operator.name, right_operand))

        # export the converters.
        # export them as simple functions with a pre-determined name

        converters = [x for x in self.public_members if type(x) == ConverterOperator]
                
        def ConverterMethodName(converter):
            result_fullname = converter.result.FullName()
            result_name = converter.result.name
            for regex, method_name in self.SPECIAL_CONVERTERS.items():
                if regex.match(result_fullname):
                    return method_name
            else:
                # extract the last name from the full name
                result_name = makeid(result_name)
                return 'to_' + result_name
            
        for converter in converters:
            info = self.info['operator'][converter.result.FullName()]
            # check if this operator should be excluded
            if info.exclude:
                continue
            
            special_code = HandleSpecialOperator(converter)
            if info.rename or not special_code:
                # export as method
                name = info.rename or ConverterMethodName(converter)
                pointer = converter.PointerDeclaration()
                policy_code = ''
                if info.policy:
                    policy_code = ', %s()' % info.policy.Code()
                self.Add('inside', '.def("%s", %s%s)' % (name, pointer, policy_code))
                    
            elif special_code:
                self.Add('inside', special_code)



    def ExportNestedClasses(self, exported_names):
        nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)]
        for nested_class in nested_classes:
            nested_info = self.info[nested_class.name]
            nested_info.include = self.info.include
            nested_info.name = nested_class.FullName()
            exporter = self.__class__(nested_info)
            exporter.SetDeclarations(self.declarations)
            codeunit = SingleCodeUnit(None, None)
            exporter.Export(codeunit, exported_names)
            self.nested_codeunits.append(codeunit)


    def ExportNestedEnums(self, exported_names):

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -