Revision: 1480
http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1480&view=rev
Author: roman_yakovenko
Date: 2008-12-20 21:53:34 +0000 (Sat, 20 Dec 2008)
Log Message:
-----------
adding convenience methods and some "understandings"
Modified Paths:
--------------
pyplusplus_dev/pyplusplus/cpptypes/tester.py
Modified: pyplusplus_dev/pyplusplus/cpptypes/tester.py
===================================================================
--- pyplusplus_dev/pyplusplus/cpptypes/tester.py 2008-12-20 19:23:18 UTC (rev 1479)
+++ pyplusplus_dev/pyplusplus/cpptypes/tester.py 2008-12-20 21:53:34 UTC (rev 1480)
@@ -24,9 +24,11 @@
return self.func( *args, **keywd )
class mem_fun_factory( object ):
- def __init__( self, dll, class_ ):
+ def __init__( self, dll, wrapper, class_name, namespace='' ):
self.dll = dll
- self.this_type = ctypes.POINTER( class_ )
+ self.namespace = namespace
+ self.class_name = class_name
+ self.this_type = ctypes.POINTER( wrapper )
def __call__( self, name, **keywd ):
if 'argtypes' not in keywd:
@@ -35,8 +37,58 @@
keywd['argtypes'].insert( 0, self.this_type )
return public( self.dll, name, **keywd )
+ def __get_ns_name(self):
+ if self.namespace:
+ return self.namespace + '::'
+ else:
+ return ''
-class Number(ctypes.Structure):
+ def default_constructor( self ):
+ return self( '%(ns)s%(class_name)s::%(class_name)s(void)'
+ % dict( ns=self.__get_ns_name()
+ , class_name=self.class_name ) )
+
+ def constructor( self, argtypes_str, **keywd ):
+ return self( '%(ns)s%(class_name)s::%(class_name)s(%(args)s)'
+ % dict( ns=self.__get_ns_name()
+ , class_name=self.class_name
+ , args=argtypes_str )
+ , **keywd )
+
+ def copy_constructor( self ):
+ return self( '%(ns)s%(class_name)s::%(class_name)s(%(class_name)s const &)'
+ % dict( ns=self.__get_ns_name()
+ , class_name=self.class_name )
+ , argtypes=[self.this_type] )
+
+ def destructor( self ):
+ return self( '%(ns)s%(class_name)s::~%(class_name)s(void)'
+ % dict( ns=self.__get_ns_name()
+ , class_name=self.class_name ) )
+
+ def operator_assign( self ):
+ return self( '%(ns)s%(class_name)s & %(class_name)s::operator=(%(class_name)s const &)'
+ % dict( ns=self.__get_ns_name()
+ , class_name=self.class_name )
+ , restype=self.this_type
+ , argtypes=[self.this_type] )
+
+ def method( self, name, restype_str=None, argtypes_str=None, **keywd ):
+ if None is restype_str:
+ restype_str = 'void'
+ if None is argtypes_str:
+ argtypes_str = 'void'
+
+ return self( '%(return_)s %(ns)s%(class_name)s::%(method_name)s(%(args)s)'
+ % dict( return_=restype_str
+ , ns=self.__get_ns_name()
+ , class_name=self.class_name
+ , method_name=name
+ , args=argtypes_str )
+ , **keywd )
+
+#names should be preserved
+class number_t(ctypes.Structure):
#http://www.phpcompiler.org/articles/virtualinheritance.html,
_fields_ = [("vptr", ctypes.POINTER(ctypes.c_void_p)),
("m_value", ctypes.c_int)]
@@ -50,7 +102,7 @@
self._methods_['default_constructor']( self.__this )
elif isinstance( x, int ):
self._methods_['from_int_constructor']( self.__this, x )
- elif isinstance( x, Number ):
+ elif isinstance( x, number_t ):
self._methods_['copy_constructor']( self.__this, ctypes.byref( x ) )
else:
raise RuntimeError( "Wrong argument" )
@@ -61,64 +113,117 @@
def set_value( self, *args, **keywd ):
return self._methods_['set_value']( self.__this, *args, **keywd )
+ def clone( self, *args, **keywd ):
+ return self._methods_['clone']( self.__this, *args, **keywd )
+
def print_it( self, *args, **keywd ):
return self._methods_['print_it']( self.__this, *args, **keywd )
+ def operator_assign( self, *args, **keywd ):
+ return self._methods_['operator_assign']( self.__this, *args, **keywd )
+
+ def __del__(self):
+ self._methods_['destructor']( self.__this )
+
+class auto_ptr(ctypes.Structure):
+ #http://www.phpcompiler.org/articles/virtualinheritance.html,
+ _fields_ = [("pointer", ctypes.POINTER(ctypes.c_void_p))]
+
+ _methods_ = {}
+
+ def __init__(self, x=None):
+ self.__this = ctypes.byref( self )
+ #overloading example
+ if None is x:
+ self._methods_['default_constructor']( self.__this )
+ elif isinstance( x, int ):
+ self._methods_['from_pointer_constructor']( self.__this, x )
+ elif isinstance( x, auto_ptr ):
+ self._methods_['copy_constructor']( self.__this, ctypes.byref( x ) )
+ else:
+ raise RuntimeError( "Wrong argument" )
+
+ def get( self, *args, **keywd ):
+ return self._methods_['get']( self.__this, *args, **keywd )
+
+ def release( self, *args, **keywd ):
+ return self._methods_['release']( self.__this, *args, **keywd )
+
def assign( self, *args, **keywd ):
return self._methods_['assign']( self.__this, *args, **keywd )
def __del__(self):
self._methods_['destructor']( self.__this )
+#important note: the methods of the class could only be generated after all class were defined.
+#For example: class X{ std::auto_ptr<X> clone(); };
-mem_fun = mem_fun_factory( mydll, Number )
-Number._methods_ = {
- #constructors
- 'default_constructor' : mem_fun( 'number_t::number_t(void)' )
- , 'from_int_constructor' : mem_fun( 'number_t::number_t(int)', argtypes=[ctypes.c_int] )
- , 'copy_constructor' : mem_fun( 'number_t::number_t(number_t const &)', argtypes=[ctypes.POINTER(Number)] )
- #member functions
- , 'get_value' : mem_fun( 'int number_t::get_value(void)', restype=ctypes.c_int )
- , 'set_value' : mem_fun( 'void number_t::set_value(int)', argtypes=[ctypes.c_int])
- , 'print_it' : mem_fun( 'void number_t::print_it(void)' )
- #operator=
- , 'assign' : mem_fun( "number_t & number_t::operator=(number_t const &)"
- , restype=ctypes.POINTER(Number)
- , argtypes=[ctypes.POINTER(Number)] )
- #destructor
- , 'destructor' : mem_fun( 'number_t::~number_t(void)' )
+mfcreator = mem_fun_factory( mydll, number_t, 'number_t' )
+number_t._methods_ = {
+ 'default_constructor' : mfcreator.default_constructor()
+ , 'copy_constructor' : mfcreator.copy_constructor()
+ , 'operator_assign' : mfcreator.operator_assign()
+ , 'destructor' : mfcreator.destructor()
+ , 'from_int_constructor' : mfcreator.constructor( argtypes_str='int', argtypes=[ctypes.c_int] )
+ , 'get_value' : mfcreator.method( 'get_value', restype_str='int', restype=ctypes.c_int )
+ , 'set_value' : mfcreator.method( 'set_value', argtypes_str='int', argtypes=[ctypes.c_int])
+ , 'print_it' : mfcreator.method( 'print_it' )
+ , 'clone' : mfcreator.method( 'clone', restype_str="number_t", restype=number_t )
+ , 'clone_ptr' : mfcreator.method( 'clone_ptr', restype_str="std::auto_ptr<number_t>", restype=auto_ptr )
}
-del mem_fun
+del mfcreator
+#~ mfcreator = mem_fun_factory( mydll, auto_ptr )
+#~ auto_ptr._methods_ = {
+ #~ 'default_constructor' : mfcreator.default_constructor()
+ #~ , 'operator_assign' : mfcreator.operator_assign()
+ #~ , 'destructor' : mfcreator.destructor()
+ #~ u'std::auto_ptr<number_t>::auto_ptr<number_t>(number_t *)': u'??0?$auto_ptr@Vnumber_t@@@std@@QAE@PAVnumber_t@@@Z',
+ #~ u'std::auto_ptr<number_t>::auto_ptr<number_t>(std::auto_ptr<number_t> &)': u'??0?$auto_ptr@Vnumber_t@@@std@@QAE@AAV01@@Z',
+
+
+
+ #~ u'number_t * std::auto_ptr<number_t>::get(void)': u'?get@?$auto_ptr@Vnumber_t@@@std@@QBEPAVnumber_t@@XZ',
+ #~ u'number_t * std::auto_ptr<number_t>::release(void)': u'?release@?$auto_ptr@Vnumber_t@@@std@@QAEPAVnumber_t@@XZ',
+
+
+#~ }
+#~ del mfcreator
+
class tester_t( unittest.TestCase ):
def test_constructors(self):
- obj1 = Number(32)
+ obj1 = number_t(32)
self.failUnless( obj1.m_value == 32 )
- obj2 = Number()
+ obj2 = number_t()
self.failUnless( obj2.m_value == 0 )
- obj3 = Number(obj1)
+ obj3 = number_t(obj1)
self.failUnless( obj3.m_value == obj1.m_value == 32 )
def test_get_value( self ):
- obj = Number(99)
+ obj = number_t(99)
self.failUnless( 99 == obj.get_value() )
def test_set_value( self ):
- obj = Number()
+ obj = number_t()
obj.set_value( 13 )
self.failUnless( 13 == obj.get_value() == obj.m_value )
- def test_assign( self ):
- obj1 = Number(1)
- obj2 = Number(2)
- x = obj1.assign( obj2 )
+ def test_operator_assign( self ):
+ obj1 = number_t(1)
+ obj2 = number_t(2)
+ x = obj1.operator_assign( obj2 )
#there are special cases, where ctypes could introduce "optimized" behaviour and not create new python object
self.failUnless( x is obj1 )
self.failUnless( obj1.m_value == obj2.m_value )
+ def test_clone( self ):
+ obj1 = number_t(1)
+ obj2 = obj1.clone()
+ self.fail( obj1.get_value() == obj2.get_value() )
+
def main():
- obj = Number(42)
+ obj = number_t(42)
print obj.m_value
print hex(obj.vptr[0])
obj.print_it()
@@ -133,6 +238,7 @@
# * write something very smart and bugy and let the smart people to improve it
+
"""
TODO:
@@ -151,5 +257,7 @@
The user will have to change the code to add
template class __declspec(dllexport) std::auto_ptr< number_t >;
and recompile
+ * how should we deal with namespaces?
+ * member function signatures should be generate outside of the classes.
"""
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|