[pygccxml-commit] SF.net SVN: pygccxml: [500] pyplusplus_dev/contrib/goodies
Brought to you by:
mbaas,
roman_yakovenko
From: <al...@us...> - 2006-08-31 02:21:58
|
Revision: 500 http://svn.sourceforge.net/pygccxml/?rev=500&view=rev Author: allenb Date: 2006-08-30 19:21:55 -0700 (Wed, 30 Aug 2006) Log Message: ----------- Add first pass at a more complete template helper class. This doesn't provide the full interface proposed on the wiki, but it is a start and can serve my needs for now. Modified Paths: -------------- pyplusplus_dev/contrib/goodies/__init__.py pyplusplus_dev/contrib/goodies/goodie_utils.py Modified: pyplusplus_dev/contrib/goodies/__init__.py =================================================================== --- pyplusplus_dev/contrib/goodies/__init__.py 2006-08-30 21:16:47 UTC (rev 499) +++ pyplusplus_dev/contrib/goodies/__init__.py 2006-08-31 02:21:55 UTC (rev 500) @@ -12,6 +12,7 @@ from goodie_utils import (set_recursive_default, set_allow_empty_mdecl_default, finalize, add_member_function, wrap_method, add_method, - is_const_ref, exclude_protected, wrap_const_ref_params) + is_const_ref, exclude_protected, wrap_const_ref_params, + TemplateBuilder) from dsl_interface import * Modified: pyplusplus_dev/contrib/goodies/goodie_utils.py =================================================================== --- pyplusplus_dev/contrib/goodies/goodie_utils.py 2006-08-30 21:16:47 UTC (rev 499) +++ pyplusplus_dev/contrib/goodies/goodie_utils.py 2006-08-31 02:21:55 UTC (rev 500) @@ -130,3 +130,111 @@ cls.add_wrapper_code(new_method) cls.add_code('def("%s", &%s::%s);'%(c.name, cls.wrapper_alias,new_name)) + + +class TemplateWrapper: + """ Proxy for a template instance. Returned from the TemplateBuilder + to allow access to the template at a later time. + + TODO: If used a form that allowed multiple templates to be specified + ex: TemplateWrapper("osg::vector", arguments=[["float","3"],["int","4"]] + then how would we handle naming? Automatic or must be specified? + """ + def __init__(self, templateType, finalName = None): #, arguments=None): + """ + templateType: Either a base type ("osg::vector") or a full template + type ("osg::vector<float>") + finalName: Name to rename the decl to after finding it. + """ + self.mTemplateType = templateType + self.mFinalName = finalName + if not finalName: + self.mTypedefName = self.cleanTemplateName(self.mTemplateType) + else: + self.mTypedefName = "alias_%s"%self.mFinalName + self.mDecl = None + + # Properties + decl = property(lambda x: x.mDecl) + + def process(self, templateBuilder): + """ Process the wrapper to make it ready for usage by user. + templateBuilder - The module builder used to parse the template. + """ + # Look up the decl from the alias db + # XXX: I don't know if this is the best way to look up the decl, but it seems to work + self.mDecl = templateBuilder.mAliasDB[self.mTypedefName].declaration.type.declaration + # Another method + # decl_name = templateBuilder.mAliasDB[self.mTypedefName].declaration.name + # decl = ns.decl(decl_name) + + if self.mFinalName: + self.mDecl.rename(self.mFinalName) + + + def cleanTemplateName(self, templateName): + """ Build a clean template name. """ + clean_re = re.compile('[:<>\s,]') + return clean_re.sub('_', templateName) + + +class TemplateBuilder: + """ Template builder helper class. + This class is meant to simplify the use of templates with py++. + + Usage: + + tb = TemplateBuilder() + vec3f_t = tb.Template("osg::vector<float,3>") + + # Add autogen code to a header that is included + mb = moduble_builder_t([myheaders]) + tb.process(mb) + + vec3f = vec3f_t.decl + vec3f.method("getSize").exclude() + + mb.create() + """ + + def __init__(self): + """ Initialize template builder. """ + # List of tuples: (templateTypename, typedefName) + # ex: ("MyClass<float>","myclass_float") + self.mTemplates = [] + + def Template(self, *args, **kw): + """Create and add a template wrapper. + """ + temp_wrapper = TemplateWrapper(*args, **kw) + self.mTemplates.append(temp_wrapper) + return temp_wrapper + + def processTemplates(self, mbuilder): + self.mAliasDB = {} + global_typedefs = mbuilder.global_ns.typedefs() + for td in global_typedefs: + self.mAliasDB[td.name] = td.type + + for t in self.mTemplates: + t.process(self) + + + def buildAutogenContents(self): + """ Build up the contents of a file to instantiate the needed templates. """ + if len(self.mTemplates) == 0: + return None + + content = "/** Autogenerated temporary file for template instantiation. */\n" + for t in self.mTemplates: + template_type = t.mTemplateType + typedef_name = t.mTypedefName + content += """ + typedef %(template_type)s %(typedef_name)s; + inline void __instantiate_%(typedef_name)s() + { sizeof(%(typedef_name)s); } + """ % vars() + + return content + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |