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.
|