Trees | Indices | Help |
|
---|
|
1 # Copyright 2006 Roman Yakovenko. 2 # Distributed under the Boost Software License, Version 1.0. (See 3 # accompanying file LICENSE_1_0.txt or copy at 4 # http://www.boost.org/LICENSE_1_0.txt) 5 # 6 # Initial author: Matthias Baas 7 8 """This module contains the standard argument policy objects. 9 10 The following policies are available: 11 12 - L{output_t} 13 - L{input_t} 14 - L{inout_t} 15 - L{input_array_t} 16 - L{output_array_t} 17 - L{type_modifier_t} 18 """ 19 import os 20 import string 21 import transformer 22 import controllers 23 from pygccxml import declarations 24 from pyplusplus import code_repository 25 26 #TODO: pointers should be checked for NULL 27 30 3335 if declarations.is_pointer( type_ ): 36 return declarations.remove_pointer( type_ ) 37 elif declarations.is_reference( type_ ): 38 return declarations.remove_reference( type_ ) 39 else: 40 raise TypeError( 'Type should be reference or pointer, got %s.' % type_ )41 42 43 # output_t45 """Handles a single output variable. 46 47 The specified variable is removed from the argument list and is turned 48 into a return value. 49 50 void getValue(int& v) -> v = getValue() 51 """ 52107 108 # input_t54 transformer.transformer_t.__init__( self, function ) 55 """Constructor. 56 57 The specified argument must be a reference or a pointer. 58 59 @param arg_ref: Index of the argument that is an output value (the first arg has index 1). 60 @type arg_ref: int 61 """ 62 self.arg = self.get_argument( arg_ref ) 63 self.arg_index = self.function.arguments.index( self.arg ) 64 65 if not is_ref_or_ptr( self.arg.type ): 66 raise ValueError( '%s\nin order to use "output" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ 67 % ( function, self.arg_ref.name, arg.type)6870 return "output(%d)"%(self.arg.name)7173 """Returns list of header files that transformer generated code depends on.""" 74 return [ code_repository.convenience.file_name ]7577 #removing arg from the function wrapper definition 78 controller.remove_wrapper_arg( self.arg.name ) 79 #declaring new variable, which will keep result 80 var_name = controller.declare_variable( remove_ref_or_ptr( self.arg.type ), self.arg.name ) 81 #adding just declared variable to the original function call expression 82 controller.modify_arg_expression( self.arg_index, var_name ) 83 #adding the variable to return variables list 84 controller.return_variable( var_name )8587 self.__configure_sealed( controller )8890 controller.remove_py_arg( self.arg_index ) 91 tmpl = string.Template( 92 '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' ) 93 store_py_result_in_arg = tmpl.substitute( name=self.arg.name 94 , type=remove_ref_or_ptr( self.arg.type ).decl_string 95 , py_result=controller.py_result_variable.name ) 96 controller.add_py_post_call_code( store_py_result_in_arg )9799 self.__configure_sealed( controller )100102 self.__configure_sealed( controller )103105 self.__configure_v_mem_fun_default( controller.default_controller ) 106 self.__configure_v_mem_fun_override( controller.override_controller )110 """Change/modify type of the argument. 111 112 Right now compiler should be able to use implicit conversion 113 """ 114151 152 # input_t116 """Constructor. 117 118 modifier is callable, which take the type of the argument and should return 119 new type 120 """ 121 transformer.transformer_t.__init__( self, function ) 122 self.arg = self.get_argument( arg_ref ) 123 self.arg_index = self.function.arguments.index( self.arg ) 124 self.modifier = modifier125127 return "type_modifier(%s)" % self.arg.name128130 w_arg = controller.find_wrapper_arg( self.arg.name ) 131 w_arg.type = self.modifier( self.arg.type ) 132 if not declarations.is_convertible( w_arg.type, self.arg.type ): 133 casting_code = 'reinterpret_cast< %s >( %s )' % ( self.arg.type, w_arg.name ) 134 controller.modify_arg_expression(self.arg_index, casting_code)135137 self.__configure_sealed( controller )138140 self.__configure_sealed( controller )141143 self.__configure_sealed( controller )144 147154 """Handles a single input variable. 155 156 The reference on the specified variable is removed. 157 158 void setValue(int& v) -> setValue(v) 159 """ 160177 178 # input_t162 """Constructor. 163 164 The specified argument must be a reference or a pointer. 165 166 @param idx: Index of the argument that is an output value (the first arg has index 1). 167 @type idx: int 168 """ 169 type_modifier_t.__init__( self, function, arg_ref, remove_ref_or_ptr ) 170 171 if not is_ref_or_ptr( self.arg.type ): 172 raise ValueError( '%s\nin order to use "input" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ 173 % ( function, self.arg_ref.name, arg.type)174176 return "input(%s)"%(self.arg.name)180 """Handles a single input variable. 181 182 Replaces the actual argument type with some integral type, so you 183 can use ctypes package. 184 185 void do_smth(int** image) -> do_smth(unsigned int addressof_image) 186 187 """ 188206 207 # inout_t190 """Constructor. 191 192 The specified argument must be a reference or a pointer. 193 194 @param idx: Index of the argument that is an output value (the first arg has index 1). 195 @type idx: int 196 """ 197 modifier = lambda type_: declarations.FUNDAMENTAL_TYPES[ 'unsigned int' ] 198 type_modifier_t.__init__( self, function, arg_ref, modifier ) 199 200 if not is_ptr_or_array( self.arg.type ): 201 raise ValueError( '%s\nin order to use "from_address_t" transformation, argument %s type must be a pointer or a array (got %s).' ) \ 202 % ( function, self.arg_ref.name, arg.type)203205 return "from_address(%s)"%(self.arg.name)209 """Handles a single input/output variable. 210 211 void foo(int& v) -> v = foo(v) 212 """ 213263 264 265 _seq2arr = string.Template( os.linesep.join([ 266 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist, $array_size );' 267 , 'pyplus_conv::copy_sequence( $pylist, pyplus_conv::array_inserter( $native_array, $array_size ) );'])) 268 269 _seq2vector = string.Template( os.linesep.join([ 270 'pyplus_conv::ensure_uniform_sequence< $type >( $pylist );' 271 , 'pyplus_conv::copy_sequence( $pylist, std::back_inserter( $native_array), boost::type< $type >() );'])) 272 273 _arr2seq = string.Template( 274 'pyplus_conv::copy_container( $native_array, $native_array + $array_size, pyplus_conv::list_inserter( $pylist ) );' ) 275215 """Constructor. 216 217 The specified argument must be a reference or a pointer. 218 219 @param idx: Index of the argument that is an in/out value (the first arg has index 1). 220 @type idx: int 221 """ 222 transformer.transformer_t.__init__( self, function ) 223 self.arg = self.get_argument( arg_ref ) 224 self.arg_index = self.function.arguments.index( self.arg ) 225 226 if not is_ref_or_ptr( self.arg.type ): 227 raise ValueError( '%s\nin order to use "inout" transformation, argument %s type must be a reference or a pointer (got %s).' ) \ 228 % ( function, self.arg_ref.name, arg.type)229231 return "inout(%s)"%(self.arg.name)232234 w_arg = controller.find_wrapper_arg( self.arg.name ) 235 w_arg.type = remove_ref_or_ptr( self.arg.type ) 236 #adding the variable to return variables list 237 controller.return_variable( w_arg.name )238240 self.__configure_sealed( controller )241243 tmpl = string.Template( 244 '$name = boost::python::extract< $type >( pyplus_conv::get_out_argument( $py_result, "$name" ) );' ) 245 store_py_result_in_arg = tmpl.substitute( name=self.arg.name 246 , type=remove_ref_or_ptr( self.arg.type ).decl_string 247 , py_result=controller.py_result_variable.name ) 248 controller.add_py_post_call_code( store_py_result_in_arg )249251 self.__configure_sealed( controller )252254 self.__configure_sealed( controller )255257 self.__configure_v_mem_fun_override( controller.override_controller ) 258 self.__configure_v_mem_fun_default( controller.default_controller )259261 """Returns list of header files that transformer generated code depends on.""" 262 return [ code_repository.convenience.file_name ]277 """Handles an input array with fixed size. 278 279 void setVec3(double* v) -> setVec3(object v) 280 # v must be a sequence of 3 floats 281 """ 282350 351 352 # s - static284 """Constructor. 285 286 @param size: The fixed size of the input array 287 @type size: int 288 """ 289 transformer.transformer_t.__init__( self, function ) 290 291 self.arg = self.get_argument( arg_ref ) 292 self.arg_index = self.function.arguments.index( self.arg ) 293 294 if not is_ptr_or_array( self.arg.type ): 295 raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ 296 % ( function, self.arg.name, self.arg.type) 297 298 self.array_size = size 299 self.array_item_type = declarations.remove_const( declarations.array_item_type( self.arg.type ) )300 303305 """Returns list of header files that transformer generated code depends on.""" 306 return [ code_repository.convenience.file_name ]307309 global _seq2arr 310 w_arg = controller.find_wrapper_arg( self.arg.name ) 311 w_arg.type = declarations.dummy_type_t( "boost::python::object" ) 312 313 # Declare a variable that will hold the C array... 314 native_array = controller.declare_variable( self.array_item_type 315 , "native_" + self.arg.name 316 , '[%d]' % self.array_size ) 317 318 copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type 319 , pylist=w_arg.name 320 , array_size=self.array_size 321 , native_array=native_array ) 322 323 controller.add_pre_call_code( copy_pylist2arr ) 324 325 controller.modify_arg_expression( self.arg_index, native_array )326328 self.__configure_sealed( controller )329331 global _arr2seq 332 pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' ) 333 , 'py_' + self.arg.name ) 334 335 copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name 336 , array_size=self.array_size 337 , pylist=pylist ) 338 339 controller.add_py_pre_call_code( copy_arr2pylist )340342 self.__configure_sealed( controller )343345 self.__configure_sealed( controller )346348 self.__configure_v_mem_fun_override( controller.override_controller ) 349 self.__configure_v_mem_fun_default( controller.default_controller )354 """Handles an output array of a fixed size. 355 356 void getVec3(double* v) -> v = getVec3() 357 # v will be a list with 3 floats 358 """ 359441 442361 """Constructor. 362 363 @param idx: Index of the argument that is an output array (the first arg has index 1). 364 @type idx: int 365 @param size: The fixed size of the output array 366 @type size: int 367 """ 368 transformer.transformer_t.__init__( self, function ) 369 self.arg = self.get_argument( arg_ref ) 370 self.arg_index = self.function.arguments.index( self.arg ) 371 372 if not is_ptr_or_array( self.arg.type ): 373 raise ValueError( '%s\nin order to use "input_array" transformation, argument %s type must be a array or a pointer (got %s).' ) \ 374 % ( function, self.arg.name, self.arg.type) 375 376 self.array_size = size 377 self.array_item_type = declarations.array_item_type( self.arg.type )378 381383 """Returns list of header files that transformer generated code depends on.""" 384 return [ code_repository.convenience.file_name ]385387 global _arr2seq 388 #removing arg from the function wrapper definition 389 controller.remove_wrapper_arg( self.arg.name ) 390 391 # Declare a variable that will hold the C array... 392 native_array = controller.declare_variable( self.array_item_type 393 , "native_" + self.arg.name 394 , '[%d]' % self.array_size ) 395 396 #adding just declared variable to the original function call expression 397 controller.modify_arg_expression( self.arg_index, native_array ) 398 399 # Declare a Python list which will receive the output... 400 pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" ) 401 , 'py_' + self.arg.name ) 402 403 copy_arr2pylist = _arr2seq.substitute( native_array=native_array 404 , array_size=self.array_size 405 , pylist=pylist ) 406 407 controller.add_post_call_code( copy_arr2pylist ) 408 409 #adding the variable to return variables list 410 controller.return_variable( pylist )411413 self.__configure_sealed( controller )414416 global _seq2arr 417 seq = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::object' ) 418 , 'py_' + self.arg.name ) 419 controller.remove_py_arg( self.arg_index ) 420 tmpl = string.Template( '$seq = pyplus_conv::get_out_argument( $py_result, "$name" );' ) 421 get_ref_to_seq = tmpl.substitute( seq=seq 422 , py_result=controller.py_result_variable.name 423 , name=self.arg.name ) 424 controller.add_py_post_call_code( get_ref_to_seq ) 425 426 copy_pylist2arr = _seq2arr.substitute( type=self.array_item_type 427 , pylist=seq 428 , array_size=self.array_size 429 , native_array=self.arg.name ) 430 controller.add_py_post_call_code( copy_pylist2arr )431433 self.__configure_sealed( controller )434436 self.__configure_sealed( controller )437439 self.__configure_v_mem_fun_override( controller.override_controller ) 440 self.__configure_v_mem_fun_default( controller.default_controller )444 """Handles an input of C buffere: 445 446 void write( byte *buffer, int size ) -> void write( python sequence ) 447 """ 448533 534450 """Constructor. 451 452 @param buffer_arg_ref: "reference" to the buffer argument 453 @param buffer_arg_ref: "reference" to argument, which holds buffer size 454 """ 455 transformer.transformer_t.__init__( self, function ) 456 457 self.buffer_arg = self.get_argument( buffer_arg_ref ) 458 self.buffer_arg_index = self.function.arguments.index( self.buffer_arg ) 459 460 self.size_arg = self.get_argument( size_arg_ref ) 461 self.size_arg_index = self.function.arguments.index( self.size_arg ) 462 463 if not is_ptr_or_array( self.buffer_arg.type ): 464 raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "buffer" argument %s type must be a array or a pointer (got %s).' ) \ 465 % ( function, self.buffer_arg.name, self.buffer_arg.type) 466 467 if not declarations.is_integral( self.size_arg.type ): 468 raise ValueError( '%s\nin order to use "input_c_buffer" transformation, "size" argument %s type must be an integral type (got %s).' ) \ 469 % ( function, self.size_arg.name, self.size_arg.type) 470 471 self.buffer_item_type = declarations.remove_const( declarations.array_item_type( self.buffer_arg.type ) )472474 return "input_c_buffer(buffer arg=%s, size arg=%s)" \ 475 % ( self.buffer_arg.name, self.size_arg.name)476478 """Returns list of header files that transformer generated code depends on.""" 479 return [ code_repository.convenience.file_name, '<vector>', '<iterator>' ]480482 global _seq2arr 483 w_buffer_arg = controller.find_wrapper_arg( self.buffer_arg.name ) 484 w_buffer_arg.type = declarations.dummy_type_t( "boost::python::object" ) 485 486 controller.remove_wrapper_arg( self.size_arg.name ) 487 488 size_var = controller.declare_variable( 489 declarations.remove_const( self.size_arg.type ) 490 , self.size_arg.name 491 , ' = boost::python::len(%s)' % w_buffer_arg.name ) 492 493 # Declare a variable that will hold the C array... 494 buffer_var = controller.declare_variable( 495 declarations.dummy_type_t( "std::vector< %s >" % self.buffer_item_type.decl_string ) 496 , "native_" + self.buffer_arg.name ) 497 498 controller.add_pre_call_code( '%s.reserve( %s );' % ( buffer_var, size_var ) ) 499 500 copy_pylist2arr = _seq2vector.substitute( type=self.buffer_item_type 501 , pylist=w_buffer_arg.name 502 , native_array=buffer_var ) 503 504 controller.add_pre_call_code( copy_pylist2arr ) 505 506 controller.modify_arg_expression( self.buffer_arg_index, '&%s[0]' % buffer_var ) 507 controller.modify_arg_expression( self.size_arg_index, '%s' % size_var )508510 self.__configure_sealed( controller )511 514 #global _arr2seq 515 #pylist = controller.declare_py_variable( declarations.dummy_type_t( 'boost::python::list' ) 516 #, 'py_' + self.arg.name ) 517 518 #copy_arr2pylist = _arr2seq.substitute( native_array=self.arg.name 519 #, array_size=self.array_size 520 #, pylist=pylist ) 521 522 #controller.add_py_pre_call_code( copy_arr2pylist ) 523525 self.__configure_sealed( controller )526528 self.__configure_sealed( controller )529531 self.__configure_v_mem_fun_override( controller.override_controller ) 532 self.__configure_v_mem_fun_default( controller.default_controller )536 """see http://boost.org/libs/python/doc/v2/faq.html#ownership 537 """576539 """Constructor.""" 540 transformer.transformer_t.__init__( self, function ) 541 self.arg = self.get_argument( arg_ref ) 542 self.arg_index = self.function.arguments.index( self.arg ) 543 if not declarations.is_pointer( self.arg.type ): 544 raise ValueError( '%s\nin order to use "transfer ownership" transformation, argument %s type must be a pointer (got %s).' ) \ 545 % ( function, self.arg_ref.name, arg.type)546548 return "transfer_ownership(%s)" % self.arg.name549551 w_arg = controller.find_wrapper_arg( self.arg.name ) 552 naked_type = declarations.remove_pointer( self.arg.type ) 553 naked_type = declarations.remove_declarated( naked_type ) 554 w_arg.type = declarations.dummy_type_t( 'std::auto_ptr< %s >' % naked_type.decl_string ) 555 controller.modify_arg_expression(self.arg_index, w_arg.name + '.release()' )556558 self.__configure_sealed( controller )559561 self.__configure_sealed( controller )562564 self.__configure_sealed( controller )565 568 569 #TODO: FT for constructor 570 #~ def configure_constructor( self, controller ): 571 #~ self.__configure_sealed( controller ) 572
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Oct 20 08:51:36 2008 | http://epydoc.sourceforge.net |