[pygccxml-commit] SF.net SVN: pygccxml: [911] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2007-02-17 11:54:13
|
Revision: 911 http://svn.sourceforge.net/pygccxml/?rev=911&view=rev Author: roman_yakovenko Date: 2007-02-17 03:54:13 -0800 (Sat, 17 Feb 2007) Log Message: ----------- adding return_range call policy Modified Paths: -------------- pyplusplus_dev/pyplusplus/code_repository/call_policies.py pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py pyplusplus_dev/pyplusplus/module_builder/call_policies.py pyplusplus_dev/unittests/call_policies_tester.py pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp Modified: pyplusplus_dev/pyplusplus/code_repository/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2007-02-17 11:53:00 UTC (rev 910) +++ pyplusplus_dev/pyplusplus/code_repository/call_policies.py 2007-02-17 11:54:13 UTC (rev 911) @@ -26,7 +26,7 @@ #include "boost/function.hpp" #include "boost/python/suite/indexing/iterator_range.hpp" #include "boost/python/object/class_detail.hpp" - +#include "boost/type_traits/is_same.hpp" namespace pyplusplus{ namespace call_policies{ namespace bpl = boost::python; @@ -169,33 +169,41 @@ } //detail -template < typename ValueType, typename SizeGetter, typename GetItemCallPolicies=bpl::default_call_policies > -struct return_range : bpl::default_call_policies -{ - typedef return_range< ValueType, SizeGetter, GetItemCallPolicies > this_type; +template < typename TGetSize, typename TValueType, typename TValuePolicies=bpl::default_call_policies > +struct return_range : bpl::default_call_policies{ + + typedef return_range< TGetSize, TValueType, TValuePolicies > this_type; + public: - //result converter generator should return PyCObject instance - //postcall will destruct it + typedef typename detail::return_raw_data_ref result_converter; - typedef GetItemCallPolicies get_item_call_policies; - typedef ValueType value_type; + + typedef TValueType value_type; + typedef TGetSize get_size_type; + typedef TValuePolicies value_policies_type; + typedef bpl::indexing::iterator_range<value_type*> range_type; static void register_range_class_on_demand(){ - - // Check the registry. If one is already registered, return it. + //Check the registry. If the class doesn't exist, register it. bpl::handle<> class_obj( bpl::objects::registered_class_object(bpl::type_id<range_type>())); if (class_obj.get() == 0){ - bpl::class_<range_type>( "_range_iterator_", bpl::init<value_type*, value_type*>() ) - .def(bpl::indexing::container_suite<range_type>() ); + bpl::class_<range_type> registrator( "_impl_details_range_iterator_", bpl::init<value_type*, value_type*>() ); + if( boost::is_same< bpl::default_call_policies, value_policies_type>::value ){ + registrator.def(bpl::indexing::container_suite<range_type>() ); + } + else{ + //I need to find out why this code does not compiles + //typedef bpl::indexing::iterator_range_suite< range_type > suite_type; + //registrator.def(suite_type::with_policies( value_policies_type() ) ); + } } } template <class ArgumentPackage> - static PyObject* postcall(ArgumentPackage const& args, PyObject* result) - { + static PyObject* postcall(ArgumentPackage const& args, PyObject* result){ if( result == bpl::detail::none() ){ return result; } @@ -210,9 +218,9 @@ register_range_class_on_demand(); - SizeGetter get_size; - ssize_t size = get_size( self ); - range_type the_range( raw_data, raw_data+size ); + get_size_type get_size; + range_type the_range( raw_data, raw_data + get_size( self ) ); + bpl::object range_obj( the_range ); return bpl::incref( range_obj.ptr() ); Modified: pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2007-02-17 11:53:00 UTC (rev 910) +++ pyplusplus_dev/pyplusplus/decl_wrappers/__init__.py 2007-02-17 11:54:13 UTC (rev 911) @@ -90,6 +90,8 @@ from call_policies import convert_array_to_tuple_t from call_policies import convert_array_to_tuple from call_policies import memory_managers +from call_policies import return_range +from call_policies import return_range_t from decl_wrapper_printer import decl_wrapper_printer_t from decl_wrapper_printer import print_declarations Modified: pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2007-02-17 11:53:00 UTC (rev 910) +++ pyplusplus_dev/pyplusplus/decl_wrappers/call_policies.py 2007-02-17 11:54:13 UTC (rev 911) @@ -11,8 +11,9 @@ convinience function. """ +import algorithm +import python_traits from pygccxml import declarations -import algorithm class CREATION_POLICY: """Implementation details""" @@ -24,9 +25,6 @@ def __init__(self): object.__init__(self) - def create_type(self): - return self.create( None, CREATION_POLICY.AS_TEMPLATE_ARGUMENT ) - def create(self, function_creator, creation_policy=CREATION_POLICY.AS_INSTANCE): """Creates code from the call policies class instance. @param function_creator: parent code creator @@ -41,6 +39,9 @@ code = code + '()' return code + def create_type(self): + return self.create( None, CREATION_POLICY.AS_TEMPLATE_ARGUMENT ) + def create_template_arg( self, function_creator ): return self.create( function_creator, CREATION_POLICY.AS_TEMPLATE_ARGUMENT ) @@ -305,4 +306,51 @@ return [ declarations.templates.join( as_tuple, as_tuple_args ) ] def convert_array_to_tuple( array_size, memory_manager, make_object_call_policies=None, base=None ): - return convert_array_to_tuple_t( array_size, memory_manager, make_object_call_policies, base ) \ No newline at end of file + return convert_array_to_tuple_t( array_size, memory_manager, make_object_call_policies, base ) + +class return_range_t( call_policy_t ): + def __init__( self, get_size_class, value_type, value_policies): + call_policy_t.__init__( self ) + self._value_type = value_type + self._get_size_class = get_size_class + self._value_policies = value_policies + + def _get_get_size_class( self ): + return self._get_size_class + def _set_get_size_class( self, new_get_size_class): + self._get_size_class = new_get_size_class + get_size_class = property( _get_get_size_class, _set_get_size_class ) + + def _get_value_type( self ): + return self._value_type + def _set_value_type( self, new_value_type): + self._value_type = new_value_type + value_type = property( _get_value_type, _set_value_type ) + + def _get_value_policies( self ): + return self._value_policies + def _set_value_policies( self, new_value_policies): + self._value_policies = new_value_policies + value_policies = property( _get_value_policies, _set_value_policies ) + + def _create_impl(self, function_creator ): + name = algorithm.create_identifier( function_creator, '::pyplusplus::call_policies::return_range' ) + args = [ self.get_size_class, self.value_type.decl_string ] + if not self.value_policies.is_default(): + args.append( self.value_policies.create_type() ) + return declarations.templates.join( name, args ) + +def return_range( function, get_size_class, value_policies=None ): + r_type = function.return_type + if not declarations.is_pointer( r_type ): + raise TypeError( 'Function "%s" return type should be pointer, got "%s"' + % r_type.decl_string ) + + value_type = declarations.remove_pointer( r_type ) + if None is value_policies: + if python_traits.is_immutable( value_type ): + value_policies = default_call_policies() + else: + raise RuntimeError( "return_range call policies requieres specification of value_policies" ) + return return_range_t( get_size_class, value_type, value_policies ) + Modified: pyplusplus_dev/pyplusplus/module_builder/call_policies.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2007-02-17 11:53:00 UTC (rev 910) +++ pyplusplus_dev/pyplusplus/module_builder/call_policies.py 2007-02-17 11:54:13 UTC (rev 911) @@ -21,3 +21,5 @@ from pyplusplus.decl_wrappers import custom_call_policies from pyplusplus.decl_wrappers import convert_array_to_tuple from pyplusplus.decl_wrappers import memory_managers +from pyplusplus.decl_wrappers import return_range +from pyplusplus.decl_wrappers import return_range_t Modified: pyplusplus_dev/unittests/call_policies_tester.py =================================================================== --- pyplusplus_dev/unittests/call_policies_tester.py 2007-02-17 11:53:00 UTC (rev 910) +++ pyplusplus_dev/unittests/call_policies_tester.py 2007-02-17 11:54:13 UTC (rev 911) @@ -9,6 +9,27 @@ import fundamental_tester_base from pyplusplus.module_builder import call_policies +get_size_code = """ +struct raw_data_size_t{ + ssize_t + operator()( boost::python::object self ){ + boost::python::object raw_data = self.attr( "raw_data" ); + return boost::python::len( raw_data ); + } +}; +""" + +get_size_code = """ +struct raw_data_size_t{ + ssize_t + operator()( boost::python::object self ){ + call_policies::return_range_image_t& image + = boost::python::extract<call_policies::return_range_image_t&>( self ); + return image.raw_data.size(); + } +}; +""" + class tester_t(fundamental_tester_base.fundamental_tester_base_t): EXTENSION_NAME = 'call_policies' @@ -36,6 +57,17 @@ mb.calldef( 'create_arr_3' ).call_policies \ = call_policies.convert_array_to_tuple( 3, call_policies.memory_managers.delete_ ) + image = mb.class_('return_range_image_t') + #image.exclude() + image.add_declaration_code( get_size_code ) + get_raw_data = image.mem_fun( 'get_raw_data' ) + get_raw_data.call_policies \ + = call_policies.return_range( get_raw_data, 'raw_data_size_t' ) + get_raw_data_const = image.mem_fun( 'get_raw_data_const' ) + get_raw_data_const.call_policies \ + = call_policies.return_range( get_raw_data_const, 'raw_data_size_t' ) + + def run_tests(self, module): self.failUnless( module.compare( module.my_address() ) ) @@ -64,6 +96,12 @@ for i in range( 4 ): arr3 = x.create_arr_3() self.failUnless( arr3 == (0,1,2) ) + + image = module.return_range_image_t() + raw_data = image.get_raw_data() + self.failUnless( ['1', '\0', '2']==list( raw_data ) ) + raw_data[1] = 'x' + self.failUnless( raw_data[1] == image.raw_data[1] ) def create_suite(): suite = unittest.TestSuite() Modified: pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp =================================================================== --- pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp 2007-02-17 11:53:00 UTC (rev 910) +++ pyplusplus_dev/unittests/data/call_policies_to_be_exported.hpp 2007-02-17 11:54:13 UTC (rev 911) @@ -6,6 +6,8 @@ #ifndef __call_policies_to_be_exported_hpp__ #define __call_policies_to_be_exported_hpp__ +#include <string> + namespace call_policies{ struct dummy{ @@ -84,6 +86,27 @@ } }; +struct return_range_image_t{ + return_range_image_t() + : raw_data( "" ) + { + raw_data += '1'; + raw_data += '\0'; + raw_data += '2'; + } + + std::string raw_data; + + const char* get_raw_data_const() const{ + return raw_data.c_str(); + } + + char* get_raw_data(){ + return &raw_data.at(0); + } + +}; + } #endif//__call_policies_to_be_exported_hpp__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |