[pygccxml-commit] SF.net SVN: pygccxml: [551] pyplusplus_dev/unittests
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-09-18 19:57:23
|
Revision: 551 http://svn.sourceforge.net/pygccxml/?rev=551&view=rev Author: roman_yakovenko Date: 2006-09-18 12:57:05 -0700 (Mon, 18 Sep 2006) Log Message: ----------- adding implicitly_convertible and smart_ptr tests Modified Paths: -------------- pyplusplus_dev/unittests/casting_tester.py pyplusplus_dev/unittests/custom_smart_ptr_classes_tester.py pyplusplus_dev/unittests/data/casting_to_be_exported.hpp pyplusplus_dev/unittests/data/custom_smart_ptr_classes_to_be_exported.hpp Added Paths: ----------- pyplusplus_dev/unittests/impl_conv/ pyplusplus_dev/unittests/impl_conv/ic.cpp pyplusplus_dev/unittests/impl_conv/sconstruct pyplusplus_dev/unittests/impl_conv/test.py pyplusplus_dev/unittests/smart_ptrs/ pyplusplus_dev/unittests/smart_ptrs/cspc.cpp pyplusplus_dev/unittests/smart_ptrs/expose_classes_rvalue.cpp pyplusplus_dev/unittests/smart_ptrs/sconstruct pyplusplus_dev/unittests/smart_ptrs/test.py Modified: pyplusplus_dev/unittests/casting_tester.py =================================================================== --- pyplusplus_dev/unittests/casting_tester.py 2006-09-18 13:41:16 UTC (rev 550) +++ pyplusplus_dev/unittests/casting_tester.py 2006-09-18 19:57:05 UTC (rev 551) @@ -16,6 +16,8 @@ self , tester_t.EXTENSION_NAME , *args ) + def customize( self, mb ): + mb.class_("float_vector").add_registration_code("def( bp::init< const casting::float_vector& >() )") def run_tests( self, module): x_inst = module.x() @@ -24,6 +26,11 @@ self.failUnless( 25 == module.x_value(25) ) self.failUnless( 1 == module.x_value(True) ) self.failUnless( 0 == module.x_value(False) ) + try: + fv = module.float_vector( 5.0 ) + self.fail( "TypeError exception was not raised" ) + except TypeError: + pass def create_suite(): suite = unittest.TestSuite() Modified: pyplusplus_dev/unittests/custom_smart_ptr_classes_tester.py =================================================================== --- pyplusplus_dev/unittests/custom_smart_ptr_classes_tester.py 2006-09-18 13:41:16 UTC (rev 550) +++ pyplusplus_dev/unittests/custom_smart_ptr_classes_tester.py 2006-09-18 19:57:05 UTC (rev 551) @@ -11,10 +11,14 @@ MODULE_SPTR_DECL_CODE = \ """ +# include <boost/python/converter/from_python.hpp> +# include <boost/python/converter/rvalue_from_python_data.hpp> +# include <boost/python/converter/registered.hpp> + namespace boost{ namespace python{ using namespace controllers; - + using namespace converter; controller_i* get_pointer( my_smart_ptr_t< controller_i > const& p ){ return p.get(); } @@ -35,14 +39,68 @@ }; +template <class T> +struct my_smart_ptr_from_python +{ + my_smart_ptr_from_python() + { + converter::registry::insert(&convertible, &construct, type_id<my_smart_ptr_t<T> >()); + } + + private: + static void* convertible(PyObject* p) + { + if (p == Py_None) + return p; + + return converter::get_lvalue_from_python(p, registered<T>::converters); + } + + static void construct(PyObject* source, rvalue_from_python_stage1_data* data) + { + void* const storage = ((converter::rvalue_from_python_storage<my_smart_ptr_t<T> >*)data)->storage.bytes; + // Deal with the "None" case. + if (data->convertible == source) + new (storage) my_smart_ptr_t<T>(); + else{ + std::cout << "before new (storage) my_smart_ptr_t<T>( static_cast< T* >(data->convertible) );" << std::endl; + new (storage) my_smart_ptr_t<T>( static_cast< T* >(data->convertible) ); + } + data->convertible = storage; + } +}; + + template <class T> + struct ptr_to_python { + static PyObject *convert(my_smart_ptr_t<T> const &p) { + return incref(object(my_smart_ptr_t<T>(p)).ptr()); + } + }; + + //Then you need to do this for each class you register: + //to_python_converter<ptr<T>, ptr_to_python<T> >(); + //You could automate this in a custom def visitor: + + struct smart_ptr_stuff : def_visitor<smart_ptr_stuff> { + friend class def_visitor_access; + template <typename Class> + void visit(Class &c) const { + typedef typename Class::wrapped_type T; + to_python_converter<my_smart_ptr_t<T>, ptr_to_python<T> >(); + } + }; + + }}// namespace boost::python converter """ MODULE_SPTR_REG_CODE = \ """ + boost::python::my_smart_ptr_from_python<controllers::add_x_t>(); + bp::register_ptr_to_python< my_smart_ptr_t< controllers::controller_i > >(); - bp::register_ptr_to_python< my_smart_ptr_t< controllers::add_x_t > >(); + //bp::register_ptr_to_python< my_smart_ptr_t< controllers::add_x_t > >(); bp::implicitly_convertible< my_smart_ptr_t< controllers::add_x_t >, my_smart_ptr_t< controllers::controller_i > >(); @@ -61,7 +119,14 @@ mb.classes( lambda cls: 'ptr' in cls.name).exclude() mb.add_declaration_code( MODULE_SPTR_DECL_CODE ) mb.add_registration_code( MODULE_SPTR_REG_CODE ) + add_x_t = mb.class_( 'add_x_t' ) + add_x_t.held_type = 'my_smart_ptr_t< controllers::add_x_t >' + add_x_t.add_registration_code( 'def(boost::python::smart_ptr_stuff())' ) + mb.build_code_creator( self.EXTENSION_NAME ) + mb.code_creator.add_include( 'iostream' ) + + def create_identity_value( self, module, v ): class identity_value_t( module.value_i ): def __init__( self, v ): @@ -85,10 +150,14 @@ def run_tests(self, module): add_0 = module.add_x_t( 23 ) + print '>',1 self.failUnless( 23 == add_0.get_value() ) - self.failUnless( 23 == module.ref_get_value( add_0 ) ) + print '>',2 self.failUnless( 23 == module.val_get_value( add_0 ) ) + print '>',3 self.failUnless( 23 == module.const_ref_get_value( add_0 ) ) + print '>',4 + self.failUnless( 23 == module.ref_get_value( add_0 ) ) def create_suite(): Modified: pyplusplus_dev/unittests/data/casting_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/casting_to_be_exported.hpp 2006-09-18 13:41:16 UTC (rev 550) +++ pyplusplus_dev/unittests/data/casting_to_be_exported.hpp 2006-09-18 19:57:05 UTC (rev 551) @@ -1,40 +1,57 @@ -// Copyright 2004 Roman Yakovenko. -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __casting_to_be_exported_hpp__ -#define __casting_to_be_exported_hpp__ - -namespace casting{ - -struct y{}; - -struct x{ - x() - : value(0) - {} - - explicit x( int i ) - : value( i ) - {} - - x( bool b ) - : value( b ) - {} - - operator int() const { return value; } - - operator y(){ return y(); } - - int value; -}; - - -int identity( int z ){ return z; } - -int x_value(const x& d ){ return d.value; } - -} - -#endif//__casting_to_be_exported_hpp__ +// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef __casting_to_be_exported_hpp__ +#define __casting_to_be_exported_hpp__ + +namespace casting{ + +struct y{}; + +struct x{ + x() + : value(0) + {} + + explicit x( int i ) + : value( i ) + {} + + x( bool b ) + : value( b ) + {} + + operator int() const { return value; } + + operator y(){ return y(); } + + int value; +}; + + +int identity( int z ){ return z; } + +int x_value(const x& d ){ return d.value; } + + +struct vector{ + vector(){} + vector( double ){} + vector( const vector& ){} +}; + +struct float_vector{ + float_vector(){} + float_vector( const float_vector& ){} + float_vector( const vector& ){} + float_vector( float ){} +}; + +inline void do_nothing(){ + float_vector( 5.0 ); +} +} + +#endif//__casting_to_be_exported_hpp__ \ No newline at end of file Modified: pyplusplus_dev/unittests/data/custom_smart_ptr_classes_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/custom_smart_ptr_classes_to_be_exported.hpp 2006-09-18 13:41:16 UTC (rev 550) +++ pyplusplus_dev/unittests/data/custom_smart_ptr_classes_to_be_exported.hpp 2006-09-18 19:57:05 UTC (rev 551) @@ -100,6 +100,12 @@ return a->get_value(); } +//inline int +//val_get_value( my_smart_ptr_t< controllers::add_x_t > a ){ +// return a->get_value(); +//} + + inline int val_get_value( controllers::controller_ptr_i a ){ return a->get_value(); Added: pyplusplus_dev/unittests/impl_conv/ic.cpp =================================================================== --- pyplusplus_dev/unittests/impl_conv/ic.cpp (rev 0) +++ pyplusplus_dev/unittests/impl_conv/ic.cpp 2006-09-18 19:57:05 UTC (rev 551) @@ -0,0 +1,36 @@ +#include "boost/python.hpp" + +struct vector{ + vector(){} + vector( double ){} + vector( const vector& ){} +}; + +struct float_vector{ + float_vector(){} + float_vector( const float_vector& ){} + float_vector( const vector& ){} + float_vector( float ){} +}; + +namespace bp = boost::python; + +BOOST_PYTHON_MODULE( ic_ext ){ + + bp::class_< float_vector >( "float_vector" ) + .def( bp::init< >() ) + .def( bp::init< vector const & >() ) + .def( bp::init< float >() ) + .def( bp::init< const float_vector& >() ); + + bp::implicitly_convertible< vector const &, float_vector >(); + + bp::implicitly_convertible< float, float_vector >(); + + bp::class_< vector >( "vector" ) + .def( bp::init< >() ) + .def( bp::init< double >() ); + + bp::implicitly_convertible< double, vector >(); + +} Added: pyplusplus_dev/unittests/impl_conv/sconstruct =================================================================== --- pyplusplus_dev/unittests/impl_conv/sconstruct (rev 0) +++ pyplusplus_dev/unittests/impl_conv/sconstruct 2006-09-18 19:57:05 UTC (rev 551) @@ -0,0 +1,9 @@ +SharedLibrary( target=r'ic_ext' + , source=[ r'ic.cpp' ] + , LIBS=[ r"boost_python" ] + , LIBPATH=[ r"/home/roman/boost_cvs/bin",r"" ] + , CPPPATH=[ r"/home/roman/boost_cvs",r"/usr/include/python2.4" ] + , CCFLAGS=[ '-DBOOST_PYTHON_TRACE_REGISTRY' ] + , SHLIBPREFIX='' + , SHLIBSUFFIX='.so' +) Added: pyplusplus_dev/unittests/impl_conv/test.py =================================================================== --- pyplusplus_dev/unittests/impl_conv/test.py (rev 0) +++ pyplusplus_dev/unittests/impl_conv/test.py 2006-09-18 19:57:05 UTC (rev 551) @@ -0,0 +1,3 @@ +import ic_ext + +ic_ext.float_vector( 5.0 ) Added: pyplusplus_dev/unittests/smart_ptrs/cspc.cpp =================================================================== --- pyplusplus_dev/unittests/smart_ptrs/cspc.cpp (rev 0) +++ pyplusplus_dev/unittests/smart_ptrs/cspc.cpp 2006-09-18 19:57:05 UTC (rev 551) @@ -0,0 +1,152 @@ +// This file has been generated by Py++. + +// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "boost/python.hpp" +#include <assert.h> + +//defining smart pointer class + +template<class T> class smart_ptr_t { +protected: + T* pRep; + unsigned int* pUseCount; +public: + + smart_ptr_t() + : pRep(0), pUseCount(0) + {} + + //What will happen if rep is NULL? -> bug + explicit smart_ptr_t(T* rep) + : pRep(rep), pUseCount( new unsigned int(1) ) + {} + + template<class Y> + smart_ptr_t(const smart_ptr_t<Y>& r) + : pRep(0), pUseCount(0) + { + pRep = r.get(); + pUseCount = r.useCountPointer(); + if(pUseCount){ + ++(*pUseCount); + } + } + + template< class Y> + smart_ptr_t& operator=(const smart_ptr_t<Y>& r){ + if( pRep == r.pRep ){ + return *this; + } + + release(); + + pRep = r.get(); + pUseCount = r.useCountPointer(); + if(pUseCount){ + ++(*pUseCount); + } + return *this; + } + + virtual ~smart_ptr_t() { + release(); + } + + inline T& operator*() const { + assert(pRep); return *pRep; + } + + inline T* operator->() const { + assert(pRep); return pRep; + } + + inline T* get() const { + return pRep; + } + + inline unsigned int* useCountPointer() const { + return pUseCount; + } + + inline T* getPointer() const { + return pRep; + } + +protected: + + inline void release(void){ + bool destroyThis = false; + + if( pUseCount ){ + if( --(*pUseCount) == 0){ + destroyThis = true; + } + } + if (destroyThis){ + destroy(); + } + } + + virtual void destroy(void){ + delete pRep; + delete pUseCount; + } +}; + + +//defining few classes and functions that should be exposed to Python + + +struct derived_t{ + virtual int get_value(void) const{ + return 11; + } +}; + + +int +val_get_value( smart_ptr_t<derived_t> a ){ + return a->get_value(); +} + +int +const_ref_get_value( const smart_ptr_t<derived_t>& a ){ + if( a.get() ){ + return a->get_value(); + } + else{ + return -1; + } +} + +//Expose code + +namespace bp = boost::python; + +namespace boost{ namespace python{ + + template<class T> + inline T * get_pointer(smart_ptr_t<T> const& p){ + return p.get(); + } + + template <class T> + struct pointee< smart_ptr_t<T> >{ + typedef T type; + }; + +} } + +BOOST_PYTHON_MODULE( cspc_ext ){ + + bp::class_< derived_t, smart_ptr_t<derived_t> >( "derived_t" ) + .def( "get_value", &::derived_t::get_value ); + + bp::def( "const_ref_get_value", &::const_ref_get_value ); + bp::def( "val_get_value", &::val_get_value ); + +} Added: pyplusplus_dev/unittests/smart_ptrs/expose_classes_rvalue.cpp =================================================================== --- pyplusplus_dev/unittests/smart_ptrs/expose_classes_rvalue.cpp (rev 0) +++ pyplusplus_dev/unittests/smart_ptrs/expose_classes_rvalue.cpp 2006-09-18 19:57:05 UTC (rev 551) @@ -0,0 +1,161 @@ +// This file has been generated by Py++. + +// Copyright 2004 Roman Yakovenko. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "boost/python.hpp" + +#include "classes.hpp" + +#include "iostream" + +# include <boost/python/converter/from_python.hpp> +# include <boost/python/converter/rvalue_from_python_data.hpp> +# include <boost/python/converter/registered.hpp> + +namespace bp = boost::python; +namespace bpc = boost::python::converter; + +namespace boost{ namespace python{ + + template<class T> + inline T * get_pointer(smart_ptr_t<T> const& p){ + return p.get(); + } + + template <class T> + struct pointee< smart_ptr_t<T> >{ + typedef T type; + }; + +} } + +template <typename T> +struct smart_ptr_to_python{ + + static PyObject * + convert(smart_ptr_t<T> const& s_ptr){ + if( !s_ptr.get() ){ + return bp::detail::none(); + } + else{ + return bpc::registered< smart_ptr_t<T> const&>::converters.to_python(&s_ptr); + } + } + +}; + +template <class SmartPtrInst> +struct smart_ptr_from_python { + + typedef typename boost::python::pointee<SmartPtrInst>::type Pointee; + + smart_ptr_from_python() { + bpc::registry::insert( &convertible, &construct, bp::type_id<SmartPtrInst>() ); + } + +private: + + static void* convertible(PyObject *p) { + // can always produce a pointer from None. + if (p == Py_None) + return p; + // Otherwise, we can do it if we can get the pointee out. + void *result = bpc::get_lvalue_from_python(p, bpc::registered<Pointee>::converters); + return result; + } + + static void construct(PyObject* source, bpc::rvalue_from_python_stage1_data* data){ + void* const storage = ((bpc::rvalue_from_python_storage<SmartPtrInst>*)data)->storage.bytes; + // Deal with the "None" case. + if (data->convertible == source) + new (storage) SmartPtrInst(); // Or whatever you want. + else + new (storage)SmartPtrInst(static_cast<Pointee*>(data->convertible)); + data->convertible = storage; + } +}; + + +struct base_i_wrapper : base_i, bp::wrapper< base_i > { + + base_i_wrapper() + : base_i() + , bp::wrapper< base_i >(){ + // null constructor + + } + + virtual int get_value( ) const { + bp::override func_get_value = this->get_override( "get_value" ); + return func_get_value( ); + } + +}; + +struct derived_wrapper_t : derived_t, bp::wrapper< derived_t > { + + derived_wrapper_t(derived_t const & arg ) + : derived_t( arg ) + , bp::wrapper< derived_t >(){ + // copy constructor + + } + + derived_wrapper_t(int value ) + : derived_t( value ) + , bp::wrapper< derived_t >() + { // Normal constructor + + } + + virtual int get_add_value( ) const { + if( bp::override func_get_add_value = this->get_override( "get_add_value" ) ) + return func_get_add_value( ); + else + return derived_t::get_add_value( ); + } + + + int default_get_add_value( ) const { + return derived_t::get_add_value( ); + } + + virtual int get_value( ) const { + if( bp::override func_get_value = this->get_override( "get_value" ) ) + return func_get_value( ); + else + return derived_t::get_value( ); + } + + + int default_get_value( ) const { + return derived_t::get_value( ); + } + +}; + + +BOOST_PYTHON_MODULE( custom_sptr ){ + bp::class_< base_i_wrapper, boost::noncopyable >( "base_i" ) + .def( "get_value", bp::pure_virtual( &::base_i::get_value ) ); + + bp::class_< derived_wrapper_t, bp::bases< base_i >, smart_ptr_t<derived_t> >( "derived_t", bp::init< int >(( bp::arg("value") )) ) + .def( "get_add_value", &::derived_t::get_add_value, &derived_wrapper_t::default_get_add_value ) + .def( "get_value", &::derived_t::get_value, &derived_wrapper_t::default_get_value ); + + bp::def( "const_ref_get_value", &::const_ref_get_value ); + bp::def( "ref_get_value", &::ref_get_value ); + bp::def( "val_get_value", &::val_get_value ); + + smart_ptr_from_python< smart_ptr_t< base_i> >(); + bp::to_python_converter< smart_ptr_t<base_i>, smart_ptr_to_python< base_i > >(); + + smart_ptr_from_python< smart_ptr_t< derived_t> >(); + bp::to_python_converter< smart_ptr_t<derived_t>, smart_ptr_to_python< derived_t > >(); + + bp::implicitly_convertible< smart_ptr_t< derived_t >, smart_ptr_t< base_i > >(); + +} Added: pyplusplus_dev/unittests/smart_ptrs/sconstruct =================================================================== --- pyplusplus_dev/unittests/smart_ptrs/sconstruct (rev 0) +++ pyplusplus_dev/unittests/smart_ptrs/sconstruct 2006-09-18 19:57:05 UTC (rev 551) @@ -0,0 +1,9 @@ +SharedLibrary( target=r'cspc_ext' + , source=[ r'cspc.cpp' ] + , LIBS=[ r"boost_python" ] + , LIBPATH=[ r"/home/roman/boost_cvs/bin",r"" ] + , CPPPATH=[ r"/home/roman/boost_cvs",r"/usr/include/python2.4" ] + , CCFLAGS=[ '-DBOOST_PYTHON_TRACE_REGISTRY' ] + , SHLIBPREFIX='' + , SHLIBSUFFIX='.so' +) Added: pyplusplus_dev/unittests/smart_ptrs/test.py =================================================================== --- pyplusplus_dev/unittests/smart_ptrs/test.py (rev 0) +++ pyplusplus_dev/unittests/smart_ptrs/test.py 2006-09-18 19:57:05 UTC (rev 551) @@ -0,0 +1,15 @@ +import cspc_ext + +def test_instance( inst ): + print "call val_get_value( inst ) => %d" % cspc_ext.val_get_value(inst) + try: + #this will give us Segmentation fault on Linux + #But if you comment previuos statement than all will be fine. + print "call const_ref_get_value( inst ) => %d" % cspc_ext.const_ref_get_value(inst) + except Exception, error: + print "\nUnable to call const_ref_get_value( inst ): ", str(error) + +print 'testing derived_t instance' +inst = cspc_ext.derived_t() +test_instance( inst ) +print 'testing derived_t instance - done' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |