From 17e32cb8b8d1007ebb62bbdfccf03a528ba3e8f4 Mon Sep 17 00:00:00 2001 From: nobody Date: Wed, 12 Mar 2003 13:51:18 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'merged_to_RC_1_28_2'. [SVN r17842] --- build/Attic/python_v1.zip | Bin 236665 -> 0 bytes build/Jamfile | 84 - build/Jamfile.v2 | 85 - build/VisualStudio/boost_python.dsp | 882 ---------- build/VisualStudio/boost_python.dsw | 29 - build/python_v1.zip | Bin 236665 -> 0 bytes doc/PyConDC_2003/bpl.txt | 853 ---------- doc/PyConDC_2003/bpl_mods.txt | 908 ----------- doc/PyConDC_2003/default.css | 188 --- doc/PyConDC_2003/python_cpp_mix.png | Bin 6293 -> 0 bytes doc/boost.css | 59 - doc/building.html | 402 ----- doc/index.html | 108 -- doc/new-conversions.html | 328 ---- doc/new-conversions.txt | 111 -- doc/news.html | 109 -- doc/polymorphism.txt | 217 --- doc/projects.html | 223 --- doc/support.html | 68 - doc/tutorial/doc/auto_overloading.html | 112 -- doc/tutorial/doc/basic_interface.html | 77 - doc/tutorial/doc/building_hello_world.html | 191 --- doc/tutorial/doc/call_policies.html | 169 -- doc/tutorial/doc/class_data_members.html | 78 - .../class_operators_special_functions.html | 109 -- doc/tutorial/doc/class_properties.html | 81 - doc/tutorial/doc/class_virtual_functions.html | 129 -- doc/tutorial/doc/constructors.html | 102 -- doc/tutorial/doc/default_arguments.html | 158 -- doc/tutorial/doc/derived_object_types.html | 117 -- doc/tutorial/doc/deriving_a_python_class.html | 83 - doc/tutorial/doc/embedding.html | 97 -- doc/tutorial/doc/enums.html | 95 -- doc/tutorial/doc/exception_translation.html | 60 - doc/tutorial/doc/exposing_classes.html | 79 - doc/tutorial/doc/extracting_c___objects.html | 79 - doc/tutorial/doc/functions.html | 73 - doc/tutorial/doc/inheritance.html | 98 -- doc/tutorial/doc/iterators.html | 101 -- doc/tutorial/doc/object_interface.html | 54 - doc/tutorial/doc/overloading.html | 88 - doc/tutorial/doc/quickstart.html | 79 - doc/tutorial/doc/quickstart.txt | 1426 ----------------- doc/tutorial/doc/theme/alert.gif | Bin 577 -> 0 bytes doc/tutorial/doc/theme/arrow.gif | Bin 70 -> 0 bytes doc/tutorial/doc/theme/bkd.gif | Bin 1317 -> 0 bytes doc/tutorial/doc/theme/bkd2.gif | Bin 2543 -> 0 bytes doc/tutorial/doc/theme/bulb.gif | Bin 944 -> 0 bytes doc/tutorial/doc/theme/bullet.gif | Bin 152 -> 0 bytes doc/tutorial/doc/theme/c++boost.gif | Bin 8819 -> 0 bytes doc/tutorial/doc/theme/jam.png | Bin 3884 -> 0 bytes doc/tutorial/doc/theme/l_arr.gif | Bin 147 -> 0 bytes doc/tutorial/doc/theme/l_arr_disabled.gif | Bin 91 -> 0 bytes doc/tutorial/doc/theme/lens.gif | Bin 897 -> 0 bytes doc/tutorial/doc/theme/note.gif | Bin 151 -> 0 bytes doc/tutorial/doc/theme/python.png | Bin 14699 -> 0 bytes doc/tutorial/doc/theme/r_arr.gif | Bin 147 -> 0 bytes doc/tutorial/doc/theme/r_arr_disabled.gif | Bin 91 -> 0 bytes doc/tutorial/doc/theme/smiley.gif | Bin 879 -> 0 bytes doc/tutorial/doc/theme/style.css | 170 -- doc/tutorial/doc/theme/u_arr.gif | Bin 170 -> 0 bytes doc/tutorial/doc/using_the_interpreter.html | 236 --- ...unctions_with_default_implementations.html | 122 -- doc/tutorial/index.html | 156 -- doc/v2/Apr2002.html | 163 -- doc/v2/CallPolicies.html | 153 -- doc/v2/Dereferenceable.html | 81 - doc/v2/Extractor.html | 93 -- doc/v2/HolderGenerator.html | 71 - doc/v2/Jun2002.html | 226 --- doc/v2/Mar2002.html | 234 --- doc/v2/May2002.html | 309 ---- doc/v2/ObjectWrapper.html | 156 -- doc/v2/ResultConverter.html | 110 -- doc/v2/args.html | 103 -- doc/v2/bibliography.html | 32 - doc/v2/call.html | 82 - doc/v2/call_method.html | 159 -- doc/v2/callbacks.html | 252 --- doc/v2/callbacks.txt | 88 - doc/v2/class.html | 726 --------- doc/v2/configuration.html | 153 -- doc/v2/copy_const_reference.html | 147 -- doc/v2/copy_non_const_reference.html | 147 -- doc/v2/data_members.html | 167 -- doc/v2/def.html | 189 --- doc/v2/default_call_policies.html | 170 -- doc/v2/definitions.html | 100 -- doc/v2/dict.html | 150 -- doc/v2/enum.html | 232 --- doc/v2/errors.html | 287 ---- doc/v2/exception_translator.html | 148 -- doc/v2/extract.html | 230 --- doc/v2/faq.html | 504 ------ doc/v2/feb2002.html | 366 ----- doc/v2/from_python.html | 166 -- doc/v2/handle.html | 333 ---- doc/v2/has_back_reference.html | 214 --- doc/v2/header.html | 288 ---- doc/v2/implicit.html | 161 -- doc/v2/index.html | 17 - doc/v2/init.html | 249 --- doc/v2/instance_holder.html | 209 --- doc/v2/iterator.html | 397 ----- doc/v2/list.html | 140 -- doc/v2/long.html | 117 -- doc/v2/lvalue_from_pytype.html | 299 ---- doc/v2/make_function.html | 182 --- doc/v2/manage_new_object.html | 143 -- doc/v2/module.html | 108 -- doc/v2/numeric.html | 268 ---- doc/v2/object.html | 931 ----------- doc/v2/operators.html | 888 ---------- doc/v2/overloads.html | 225 --- doc/v2/overview.html | 48 - doc/v2/pickle.html | 293 ---- doc/v2/platforms.html | 133 -- doc/v2/pointee.html | 116 -- doc/v2/progress_reports.html | 44 - doc/v2/ptr.html | 263 --- doc/v2/python.html | 108 -- doc/v2/rationale.html | 48 - doc/v2/raw_function.html | 116 -- doc/v2/reference_existing_object.html | 178 -- doc/v2/return_by_value.html | 147 -- doc/v2/return_internal_reference.html | 227 --- doc/v2/return_value_policy.html | 165 -- doc/v2/scope.html | 170 -- doc/v2/str.html | 230 --- doc/v2/to_python_converter.html | 204 --- doc/v2/to_python_indirect.html | 194 --- doc/v2/to_python_value.html | 101 -- doc/v2/tuple.html | 137 -- doc/v2/type_id.html | 219 --- doc/v2/with_custodian_and_ward.html | 367 ----- example/Attic/project.zip | Bin 1469 -> 0 bytes example/Jamfile | 61 - example/Jamfile.v2 | 12 - example/README | 6 - example/getting_started1.cpp | 23 - example/getting_started2.cpp | 40 - example/project.zip | Bin 1469 -> 0 bytes example/tutorial/Jamfile | 15 - example/tutorial/hello.cpp | 17 - include/boost/python/arg_from_python.hpp | 84 - include/boost/python/args.hpp | 112 -- include/boost/python/args_fwd.hpp | 47 - include/boost/python/back_reference.hpp | 101 -- include/boost/python/base_type_traits.hpp | 36 - include/boost/python/bases.hpp | 67 - include/boost/python/borrowed.hpp | 20 - include/boost/python/call.hpp | 66 - include/boost/python/call_method.hpp | 66 - include/boost/python/cast.hpp | 106 -- include/boost/python/class.hpp | 548 ------- include/boost/python/class_fwd.hpp | 23 - .../python/converter/arg_from_python.hpp | 341 ---- .../boost/python/converter/arg_to_python.hpp | 262 --- .../python/converter/arg_to_python_base.hpp | 34 - .../converter/as_to_python_function.hpp | 50 - .../python/converter/builtin_converters.hpp | 132 -- .../python/converter/constructor_function.hpp | 18 - .../python/converter/convertible_function.hpp | 15 - .../boost/python/converter/from_python.hpp | 43 - include/boost/python/converter/implicit.hpp | 43 - .../converter/obj_mgr_arg_from_python.hpp | 122 -- .../boost/python/converter/object_manager.hpp | 231 --- .../python/converter/pointer_type_id.hpp | 69 - .../python/converter/pyobject_traits.hpp | 42 - .../boost/python/converter/pyobject_type.hpp | 37 - .../converter/pytype_arg_from_python.hpp | 99 -- .../converter/pytype_object_mgr_traits.hpp | 43 - include/boost/python/converter/registered.hpp | 54 - .../python/converter/registered_pointee.hpp | 63 - .../boost/python/converter/registrations.hpp | 85 - include/boost/python/converter/registry.hpp | 52 - .../python/converter/return_from_python.hpp | 161 -- .../converter/rvalue_from_python_data.hpp | 141 -- .../python/converter/shared_ptr_deleter.hpp | 23 - .../converter/shared_ptr_from_python.hpp | 53 - .../python/converter/shared_ptr_to_python.hpp | 26 - .../converter/to_python_function_type.hpp | 20 - include/boost/python/copy_const_reference.hpp | 42 - .../boost/python/copy_non_const_reference.hpp | 42 - include/boost/python/data_members.hpp | 144 -- include/boost/python/def.hpp | 113 -- .../boost/python/default_call_policies.hpp | 78 - .../boost/python/detail/aix_init_module.hpp | 27 - .../boost/python/detail/api_placeholder.hpp | 19 - include/boost/python/detail/borrowed_ptr.hpp | 112 -- include/boost/python/detail/caller.hpp | 175 -- include/boost/python/detail/char_array.hpp | 23 - include/boost/python/detail/config.hpp | 111 -- include/boost/python/detail/construct.hpp | 43 - include/boost/python/detail/convertible.hpp | 39 - .../python/detail/copy_ctor_mutates_rhs.hpp | 22 - include/boost/python/detail/cv_category.hpp | 34 - .../boost/python/detail/decorated_type_id.hpp | 77 - include/boost/python/detail/decref_guard.hpp | 22 - include/boost/python/detail/def_helper.hpp | 212 --- include/boost/python/detail/defaults_def.hpp | 280 ---- include/boost/python/detail/defaults_gen.hpp | 388 ----- include/boost/python/detail/dependent.hpp | 28 - include/boost/python/detail/destroy.hpp | 83 - .../boost/python/detail/exception_handler.hpp | 49 - .../boost/python/detail/force_instantiate.hpp | 33 - include/boost/python/detail/if_else.hpp | 117 -- .../boost/python/detail/indirect_traits.hpp | 483 ------ include/boost/python/detail/invoke.hpp | 105 -- include/boost/python/detail/is_auto_ptr.hpp | 31 - .../python/detail/is_function_ref_tester.hpp | 136 -- include/boost/python/detail/is_shared_ptr.hpp | 18 - include/boost/python/detail/is_xxx.hpp | 60 - .../python/detail/make_keyword_range_fn.hpp | 55 - include/boost/python/detail/make_tuple.hpp | 33 - include/boost/python/detail/map_entry.hpp | 44 - .../python/detail/member_function_cast.hpp | 118 -- include/boost/python/detail/mpl_lambda.hpp | 13 - include/boost/python/detail/msvc_typeinfo.hpp | 69 - include/boost/python/detail/none.hpp | 21 - include/boost/python/detail/not_specified.hpp | 15 - include/boost/python/detail/operator_id.hpp | 55 - include/boost/python/detail/overloads_fwd.hpp | 19 - include/boost/python/detail/pointee.hpp | 36 - include/boost/python/detail/preprocessor.hpp | 67 - include/boost/python/detail/python22_fixed.h | 150 -- include/boost/python/detail/raw_pyobject.hpp | 33 - .../boost/python/detail/referent_storage.hpp | 75 - include/boost/python/detail/result.hpp | 126 -- include/boost/python/detail/scope.hpp | 17 - .../boost/python/detail/string_literal.hpp | 88 - include/boost/python/detail/target.hpp | 77 - .../python/detail/translate_exception.hpp | 48 - include/boost/python/detail/type_list.hpp | 40 - .../boost/python/detail/type_list_impl.hpp | 58 - .../python/detail/type_list_impl_no_pts.hpp | 108 -- include/boost/python/detail/unwind_type.hpp | 151 -- .../python/detail/value_is_shared_ptr.hpp | 18 - include/boost/python/detail/value_is_xxx.hpp | 63 - include/boost/python/detail/void_ptr.hpp | 34 - include/boost/python/detail/void_return.hpp | 43 - include/boost/python/detail/wrap_python.hpp | 157 -- include/boost/python/dict.hpp | 151 -- include/boost/python/enum.hpp | 101 -- include/boost/python/errors.hpp | 55 - include/boost/python/exception_translator.hpp | 26 - include/boost/python/extract.hpp | 246 --- include/boost/python/handle.hpp | 249 --- include/boost/python/handle_fwd.hpp | 17 - include/boost/python/has_back_reference.hpp | 22 - include/boost/python/implicit.hpp | 28 - include/boost/python/init.hpp | 446 ------ include/boost/python/instance_holder.hpp | 57 - include/boost/python/iterator.hpp | 115 -- include/boost/python/list.hpp | 140 -- include/boost/python/long.hpp | 67 - include/boost/python/lvalue_from_pytype.hpp | 104 -- include/boost/python/make_function.hpp | 103 -- include/boost/python/manage_new_object.hpp | 40 - include/boost/python/module.hpp | 12 - include/boost/python/module_init.hpp | 61 - include/boost/python/numeric.hpp | 231 --- include/boost/python/object.hpp | 23 - .../boost/python/object/add_to_namespace.hpp | 25 - include/boost/python/object/class.hpp | 61 - .../boost/python/object/class_converters.hpp | 85 - include/boost/python/object/class_detail.hpp | 20 - include/boost/python/object/class_wrapper.hpp | 43 - include/boost/python/object/enum_base.hpp | 35 - include/boost/python/object/find_instance.hpp | 19 - include/boost/python/object/forward.hpp | 112 -- include/boost/python/object/function.hpp | 80 - .../boost/python/object/function_handle.hpp | 44 - .../boost/python/object/function_object.hpp | 43 - include/boost/python/object/inheritance.hpp | 154 -- include/boost/python/object/instance.hpp | 51 - include/boost/python/object/iterator.hpp | 226 --- include/boost/python/object/iterator_core.hpp | 19 - include/boost/python/object/life_support.hpp | 17 - include/boost/python/object/make_holder.hpp | 94 -- include/boost/python/object/make_instance.hpp | 71 - .../boost/python/object/make_ptr_instance.hpp | 66 - .../boost/python/object/pickle_support.hpp | 125 -- .../boost/python/object/pointer_holder.hpp | 176 -- include/boost/python/object/py_function.hpp | 22 - include/boost/python/object/select_holder.hpp | 236 --- include/boost/python/object/value_holder.hpp | 137 -- .../boost/python/object/value_holder_fwd.hpp | 17 - include/boost/python/object_attributes.hpp | 67 - include/boost/python/object_call.hpp | 24 - include/boost/python/object_core.hpp | 386 ----- include/boost/python/object_fwd.hpp | 17 - include/boost/python/object_items.hpp | 88 - include/boost/python/object_operators.hpp | 94 -- include/boost/python/object_protocol.hpp | 80 - include/boost/python/object_protocol_core.hpp | 53 - include/boost/python/object_slices.hpp | 125 -- include/boost/python/operators.hpp | 332 ---- include/boost/python/other.hpp | 113 -- include/boost/python/overloads.hpp | 12 - include/boost/python/pointee.hpp | 40 - include/boost/python/proxy.hpp | 101 -- include/boost/python/ptr.hpp | 127 -- include/boost/python/raw_function.hpp | 47 - include/boost/python/refcount.hpp | 42 - .../python/reference_existing_object.hpp | 45 - include/boost/python/return_by_value.hpp | 30 - .../python/return_internal_reference.hpp | 42 - include/boost/python/return_value_policy.hpp | 20 - include/boost/python/scope.hpp | 76 - include/boost/python/self.hpp | 36 - include/boost/python/signature.hpp | 119 -- include/boost/python/slice_nil.hpp | 41 - include/boost/python/str.hpp | 400 ----- include/boost/python/tag.hpp | 17 - include/boost/python/to_python_converter.hpp | 39 - include/boost/python/to_python_indirect.hpp | 114 -- include/boost/python/to_python_value.hpp | 123 -- include/boost/python/tuple.hpp | 69 - include/boost/python/type_id.hpp | 134 -- .../boost/python/with_custodian_and_ward.hpp | 78 - index.html | 9 - pyste/README | 31 - ...orting_all_declarations_from_a_header.html | 76 - pyste/doc/introduction.html | 74 - pyste/doc/policies.html | 79 - pyste/doc/pyste.txt | 370 ----- pyste/doc/renaming_and_excluding.html | 68 - pyste/doc/running_pyste.html | 110 -- pyste/doc/templates.html | 103 -- pyste/doc/the_interface_files.html | 81 - pyste/doc/theme/alert.gif | Bin 577 -> 0 bytes pyste/doc/theme/arrow.gif | Bin 70 -> 0 bytes pyste/doc/theme/bkd.gif | Bin 1317 -> 0 bytes pyste/doc/theme/bkd2.gif | Bin 2543 -> 0 bytes pyste/doc/theme/bulb.gif | Bin 944 -> 0 bytes pyste/doc/theme/bullet.gif | Bin 152 -> 0 bytes pyste/doc/theme/c++boost.gif | Bin 8819 -> 0 bytes pyste/doc/theme/l_arr.gif | Bin 147 -> 0 bytes pyste/doc/theme/l_arr_disabled.gif | Bin 91 -> 0 bytes pyste/doc/theme/note.gif | Bin 151 -> 0 bytes pyste/doc/theme/r_arr.gif | Bin 147 -> 0 bytes pyste/doc/theme/r_arr_disabled.gif | Bin 91 -> 0 bytes pyste/doc/theme/smiley.gif | Bin 879 -> 0 bytes pyste/doc/theme/style.css | 170 -- pyste/doc/theme/u_arr.gif | Bin 170 -> 0 bytes pyste/doc/wrappers.html | 108 -- pyste/example/README | 5 - pyste/example/basic.h | 21 - pyste/example/basic.pyste | 2 - pyste/example/enums.h | 18 - pyste/example/enums.pyste | 8 - pyste/example/header_test.h | 23 - pyste/example/header_test.pyste | 1 - pyste/example/nested.h | 21 - pyste/example/nested.pyste | 1 - pyste/example/operator.h | 47 - pyste/example/operator.pyste | 12 - pyste/example/templates.h | 8 - pyste/example/templates.pyste | 8 - pyste/example/wrappertest.h | 35 - pyste/example/wrappertest.pyste | 15 - pyste/example/wrappertest_wrappers.h | 26 - pyste/index.html | 71 - pyste/src/.cvsignore | 1 - pyste/src/ClassExporter.py | 726 --------- pyste/src/CodeUnit.py | 78 - pyste/src/CppParser.py | 94 -- pyste/src/EnumExporter.py | 30 - pyste/src/Exporter.py | 69 - pyste/src/FunctionExporter.py | 85 - pyste/src/GCCXMLParser.py | 395 ----- pyste/src/HeaderExporter.py | 67 - pyste/src/IncludeExporter.py | 19 - pyste/src/declarations.py | 452 ------ pyste/src/enumerate.py | 7 - pyste/src/exporters.py | 3 - pyste/src/exporterutils.py | 26 - pyste/src/infos.py | 187 --- pyste/src/policies.py | 75 - pyste/src/pyste-profile.py | 17 - pyste/src/pyste.py | 154 -- pyste/src/settings.py | 12 - pyste/tests/GCCXMLParserUT.py | 338 ---- pyste/tests/infosUT.py | 50 - pyste/tests/policiesUT.py | 59 - pyste/tests/runtests.py | 14 - release_notes.txt | 217 --- src/aix_init_module.cpp | 142 -- src/converter/arg_to_python_base.cpp | 29 - src/converter/builtin_converters.cpp | 373 ----- src/converter/from_python.cpp | 294 ---- src/converter/registry.cpp | 187 --- src/converter/type_id.cpp | 36 - src/dict.cpp | 171 -- src/errors.cpp | 113 -- src/list.cpp | 135 -- src/long.cpp | 40 - src/module.cpp | 52 - src/numeric.cpp | 313 ---- src/object/class.cpp | 514 ------ src/object/enum.cpp | 225 --- src/object/function.cpp | 527 ------ src/object/inheritance.cpp | 496 ------ src/object/iterator.cpp | 31 - src/object/life_support.cpp | 113 -- src/object/pickle_support.cpp | 63 - src/object_operators.cpp | 57 - src/object_protocol.cpp | 191 --- src/str.cpp | 324 ---- src/tuple.cpp | 20 - test/args.cpp | 92 -- test/args.py | 169 -- test/as_to_python_function.cpp | 14 - test/auto_ptr.cpp | 91 -- test/auto_ptr.py | 77 - test/back_reference.cpp | 111 -- test/back_reference.py | 29 - test/bases.cpp | 63 - test/ben_scott1.cpp | 51 - test/ben_scott1.py | 14 - test/bienstman1.cpp | 37 - test/bienstman1.py | 18 - test/bienstman2.cpp | 25 - test/bienstman2.py | 15 - test/bienstman3.cpp | 22 - test/bienstman3.py | 25 - test/bienstman4.cpp | 40 - test/bienstman4.py | 18 - test/bienstman5.cpp | 24 - test/bienstman5.py | 16 - test/borrowed.cpp | 34 - test/callbacks.cpp | 148 -- test/callbacks.py | 133 -- test/cltree.cpp | 70 - test/complicated.hpp | 39 - test/copy_ctor_mutates_rhs.cpp | 24 - test/data_members.cpp | 80 - test/data_members.py | 55 - test/defaults.cpp | 173 -- test/defaults.py | 174 -- test/destroy_test.cpp | 81 - test/dict.cpp | 82 - test/dict.py | 41 - test/docstring.cpp | 60 - test/docstring.py | 54 - test/embedding.cpp | 122 -- test/enum.cpp | 48 - test/enum.py | 59 - test/exception_translator.cpp | 25 - test/exception_translator.py | 22 - test/extract.cpp | 140 -- test/extract.py | 102 -- test/if_else.cpp | 45 - test/implicit.cpp | 48 - test/implicit.py | 26 - test/indirect_traits_test.cpp | 105 -- test/input_iterator.cpp | 49 - test/iterator.cpp | 138 -- test/iterator.py | 72 - test/list.cpp | 145 -- test/list.py | 113 -- test/long.cpp | 51 - test/long.py | 26 - test/m1.cpp | 276 ---- test/m2.cpp | 99 -- test/member_function_cast.cpp | 55 - test/minimal.cpp | 17 - test/minimal.py | 4 - test/module_tail.cpp | 42 - test/multi_arg_constructor.cpp | 24 - test/multi_arg_constructor.py | 16 - test/nested.cpp | 52 - test/nested.py | 35 - test/newtest.py | 199 --- test/numpy.cpp | 105 -- test/numpy.py | 175 -- test/object.cpp | 318 ---- test/object.py | 126 -- test/object_fail1.cpp | 12 - test/object_manager.cpp | 34 - test/operators.cpp | 94 -- test/operators.py | 89 - test/pickle1.cpp | 55 - test/pickle1.py | 31 - test/pickle2.cpp | 99 -- test/pickle2.py | 45 - test/pickle3.cpp | 107 -- test/pickle3.py | 40 - test/pointee.cpp | 35 - test/pointer_type_id_test.cpp | 39 - test/polymorphism.cpp | 101 -- test/polymorphism.py | 52 - test/raw_pyobject_fail1.cpp | 12 - test/raw_pyobject_fail2.cpp | 14 - test/result.cpp | 112 -- test/select_arg_to_python_test.cpp | 65 - test/select_from_python_test.cpp | 157 -- test/select_holder.cpp | 85 - test/shared_ptr.cpp | 137 -- test/shared_ptr.py | 109 -- test/simple_type.hpp | 14 - test/staticmethod.cpp | 46 - test/staticmethod.py | 52 - test/str.cpp | 67 - test/str.py | 52 - test/string_literal.cpp | 38 - test/submod_subclass_api.cpp | 231 --- test/test_builtin_converters.cpp | 124 -- test/test_builtin_converters.py | 238 --- test/test_class.hpp | 33 - test/test_cltree.py | 40 - test/test_pointer_adoption.cpp | 126 -- test/test_pointer_adoption.py | 88 - test/tuple.cpp | 29 - test/tuple.py | 32 - test/upcast.cpp | 19 - test/virtual_functions.cpp | 113 -- test/virtual_functions.py | 102 -- todo.txt | 24 - 520 files changed, 57325 deletions(-) delete mode 100644 build/Attic/python_v1.zip delete mode 100644 build/Jamfile delete mode 100644 build/Jamfile.v2 delete mode 100644 build/VisualStudio/boost_python.dsp delete mode 100644 build/VisualStudio/boost_python.dsw delete mode 100644 build/python_v1.zip delete mode 100644 doc/PyConDC_2003/bpl.txt delete mode 100644 doc/PyConDC_2003/bpl_mods.txt delete mode 100644 doc/PyConDC_2003/default.css delete mode 100755 doc/PyConDC_2003/python_cpp_mix.png delete mode 100644 doc/boost.css delete mode 100644 doc/building.html delete mode 100644 doc/index.html delete mode 100644 doc/new-conversions.html delete mode 100644 doc/new-conversions.txt delete mode 100644 doc/news.html delete mode 100644 doc/polymorphism.txt delete mode 100644 doc/projects.html delete mode 100644 doc/support.html delete mode 100644 doc/tutorial/doc/auto_overloading.html delete mode 100644 doc/tutorial/doc/basic_interface.html delete mode 100644 doc/tutorial/doc/building_hello_world.html delete mode 100644 doc/tutorial/doc/call_policies.html delete mode 100644 doc/tutorial/doc/class_data_members.html delete mode 100644 doc/tutorial/doc/class_operators_special_functions.html delete mode 100644 doc/tutorial/doc/class_properties.html delete mode 100644 doc/tutorial/doc/class_virtual_functions.html delete mode 100644 doc/tutorial/doc/constructors.html delete mode 100644 doc/tutorial/doc/default_arguments.html delete mode 100644 doc/tutorial/doc/derived_object_types.html delete mode 100644 doc/tutorial/doc/deriving_a_python_class.html delete mode 100644 doc/tutorial/doc/embedding.html delete mode 100644 doc/tutorial/doc/enums.html delete mode 100644 doc/tutorial/doc/exception_translation.html delete mode 100644 doc/tutorial/doc/exposing_classes.html delete mode 100644 doc/tutorial/doc/extracting_c___objects.html delete mode 100644 doc/tutorial/doc/functions.html delete mode 100644 doc/tutorial/doc/inheritance.html delete mode 100644 doc/tutorial/doc/iterators.html delete mode 100644 doc/tutorial/doc/object_interface.html delete mode 100644 doc/tutorial/doc/overloading.html delete mode 100644 doc/tutorial/doc/quickstart.html delete mode 100644 doc/tutorial/doc/quickstart.txt delete mode 100644 doc/tutorial/doc/theme/alert.gif delete mode 100644 doc/tutorial/doc/theme/arrow.gif delete mode 100644 doc/tutorial/doc/theme/bkd.gif delete mode 100644 doc/tutorial/doc/theme/bkd2.gif delete mode 100644 doc/tutorial/doc/theme/bulb.gif delete mode 100644 doc/tutorial/doc/theme/bullet.gif delete mode 100644 doc/tutorial/doc/theme/c++boost.gif delete mode 100644 doc/tutorial/doc/theme/jam.png delete mode 100644 doc/tutorial/doc/theme/l_arr.gif delete mode 100644 doc/tutorial/doc/theme/l_arr_disabled.gif delete mode 100644 doc/tutorial/doc/theme/lens.gif delete mode 100644 doc/tutorial/doc/theme/note.gif delete mode 100644 doc/tutorial/doc/theme/python.png delete mode 100644 doc/tutorial/doc/theme/r_arr.gif delete mode 100644 doc/tutorial/doc/theme/r_arr_disabled.gif delete mode 100644 doc/tutorial/doc/theme/smiley.gif delete mode 100644 doc/tutorial/doc/theme/style.css delete mode 100644 doc/tutorial/doc/theme/u_arr.gif delete mode 100644 doc/tutorial/doc/using_the_interpreter.html delete mode 100644 doc/tutorial/doc/virtual_functions_with_default_implementations.html delete mode 100644 doc/tutorial/index.html delete mode 100644 doc/v2/Apr2002.html delete mode 100644 doc/v2/CallPolicies.html delete mode 100644 doc/v2/Dereferenceable.html delete mode 100755 doc/v2/Extractor.html delete mode 100755 doc/v2/HolderGenerator.html delete mode 100644 doc/v2/Jun2002.html delete mode 100644 doc/v2/Mar2002.html delete mode 100644 doc/v2/May2002.html delete mode 100644 doc/v2/ObjectWrapper.html delete mode 100644 doc/v2/ResultConverter.html delete mode 100644 doc/v2/args.html delete mode 100644 doc/v2/bibliography.html delete mode 100644 doc/v2/call.html delete mode 100644 doc/v2/call_method.html delete mode 100644 doc/v2/callbacks.html delete mode 100644 doc/v2/callbacks.txt delete mode 100644 doc/v2/class.html delete mode 100644 doc/v2/configuration.html delete mode 100644 doc/v2/copy_const_reference.html delete mode 100644 doc/v2/copy_non_const_reference.html delete mode 100644 doc/v2/data_members.html delete mode 100644 doc/v2/def.html delete mode 100644 doc/v2/default_call_policies.html delete mode 100644 doc/v2/definitions.html delete mode 100644 doc/v2/dict.html delete mode 100644 doc/v2/enum.html delete mode 100644 doc/v2/errors.html delete mode 100644 doc/v2/exception_translator.html delete mode 100644 doc/v2/extract.html delete mode 100644 doc/v2/faq.html delete mode 100644 doc/v2/feb2002.html delete mode 100644 doc/v2/from_python.html delete mode 100644 doc/v2/handle.html delete mode 100644 doc/v2/has_back_reference.html delete mode 100644 doc/v2/header.html delete mode 100644 doc/v2/implicit.html delete mode 100644 doc/v2/index.html delete mode 100644 doc/v2/init.html delete mode 100755 doc/v2/instance_holder.html delete mode 100644 doc/v2/iterator.html delete mode 100644 doc/v2/list.html delete mode 100644 doc/v2/long.html delete mode 100755 doc/v2/lvalue_from_pytype.html delete mode 100644 doc/v2/make_function.html delete mode 100644 doc/v2/manage_new_object.html delete mode 100644 doc/v2/module.html delete mode 100644 doc/v2/numeric.html delete mode 100644 doc/v2/object.html delete mode 100755 doc/v2/operators.html delete mode 100644 doc/v2/overloads.html delete mode 100644 doc/v2/overview.html delete mode 100644 doc/v2/pickle.html delete mode 100644 doc/v2/platforms.html delete mode 100644 doc/v2/pointee.html delete mode 100644 doc/v2/progress_reports.html delete mode 100644 doc/v2/ptr.html delete mode 100644 doc/v2/python.html delete mode 100644 doc/v2/rationale.html delete mode 100755 doc/v2/raw_function.html delete mode 100644 doc/v2/reference_existing_object.html delete mode 100644 doc/v2/return_by_value.html delete mode 100644 doc/v2/return_internal_reference.html delete mode 100644 doc/v2/return_value_policy.html delete mode 100644 doc/v2/scope.html delete mode 100644 doc/v2/str.html delete mode 100644 doc/v2/to_python_converter.html delete mode 100644 doc/v2/to_python_indirect.html delete mode 100644 doc/v2/to_python_value.html delete mode 100644 doc/v2/tuple.html delete mode 100755 doc/v2/type_id.html delete mode 100644 doc/v2/with_custodian_and_ward.html delete mode 100644 example/Attic/project.zip delete mode 100644 example/Jamfile delete mode 100644 example/Jamfile.v2 delete mode 100644 example/README delete mode 100644 example/getting_started1.cpp delete mode 100644 example/getting_started2.cpp delete mode 100644 example/project.zip delete mode 100644 example/tutorial/Jamfile delete mode 100644 example/tutorial/hello.cpp delete mode 100755 include/boost/python/arg_from_python.hpp delete mode 100644 include/boost/python/args.hpp delete mode 100644 include/boost/python/args_fwd.hpp delete mode 100644 include/boost/python/back_reference.hpp delete mode 100755 include/boost/python/base_type_traits.hpp delete mode 100644 include/boost/python/bases.hpp delete mode 100755 include/boost/python/borrowed.hpp delete mode 100644 include/boost/python/call.hpp delete mode 100644 include/boost/python/call_method.hpp delete mode 100755 include/boost/python/cast.hpp delete mode 100644 include/boost/python/class.hpp delete mode 100644 include/boost/python/class_fwd.hpp delete mode 100755 include/boost/python/converter/arg_from_python.hpp delete mode 100755 include/boost/python/converter/arg_to_python.hpp delete mode 100755 include/boost/python/converter/arg_to_python_base.hpp delete mode 100644 include/boost/python/converter/as_to_python_function.hpp delete mode 100644 include/boost/python/converter/builtin_converters.hpp delete mode 100644 include/boost/python/converter/constructor_function.hpp delete mode 100644 include/boost/python/converter/convertible_function.hpp delete mode 100644 include/boost/python/converter/from_python.hpp delete mode 100644 include/boost/python/converter/implicit.hpp delete mode 100644 include/boost/python/converter/obj_mgr_arg_from_python.hpp delete mode 100755 include/boost/python/converter/object_manager.hpp delete mode 100644 include/boost/python/converter/pointer_type_id.hpp delete mode 100644 include/boost/python/converter/pyobject_traits.hpp delete mode 100644 include/boost/python/converter/pyobject_type.hpp delete mode 100644 include/boost/python/converter/pytype_arg_from_python.hpp delete mode 100644 include/boost/python/converter/pytype_object_mgr_traits.hpp delete mode 100644 include/boost/python/converter/registered.hpp delete mode 100644 include/boost/python/converter/registered_pointee.hpp delete mode 100644 include/boost/python/converter/registrations.hpp delete mode 100644 include/boost/python/converter/registry.hpp delete mode 100755 include/boost/python/converter/return_from_python.hpp delete mode 100644 include/boost/python/converter/rvalue_from_python_data.hpp delete mode 100644 include/boost/python/converter/shared_ptr_deleter.hpp delete mode 100644 include/boost/python/converter/shared_ptr_from_python.hpp delete mode 100644 include/boost/python/converter/shared_ptr_to_python.hpp delete mode 100644 include/boost/python/converter/to_python_function_type.hpp delete mode 100644 include/boost/python/copy_const_reference.hpp delete mode 100644 include/boost/python/copy_non_const_reference.hpp delete mode 100644 include/boost/python/data_members.hpp delete mode 100644 include/boost/python/def.hpp delete mode 100644 include/boost/python/default_call_policies.hpp delete mode 100644 include/boost/python/detail/aix_init_module.hpp delete mode 100644 include/boost/python/detail/api_placeholder.hpp delete mode 100755 include/boost/python/detail/borrowed_ptr.hpp delete mode 100644 include/boost/python/detail/caller.hpp delete mode 100644 include/boost/python/detail/char_array.hpp delete mode 100644 include/boost/python/detail/config.hpp delete mode 100644 include/boost/python/detail/construct.hpp delete mode 100755 include/boost/python/detail/convertible.hpp delete mode 100755 include/boost/python/detail/copy_ctor_mutates_rhs.hpp delete mode 100644 include/boost/python/detail/cv_category.hpp delete mode 100755 include/boost/python/detail/decorated_type_id.hpp delete mode 100644 include/boost/python/detail/decref_guard.hpp delete mode 100644 include/boost/python/detail/def_helper.hpp delete mode 100644 include/boost/python/detail/defaults_def.hpp delete mode 100644 include/boost/python/detail/defaults_gen.hpp delete mode 100644 include/boost/python/detail/dependent.hpp delete mode 100644 include/boost/python/detail/destroy.hpp delete mode 100644 include/boost/python/detail/exception_handler.hpp delete mode 100755 include/boost/python/detail/force_instantiate.hpp delete mode 100644 include/boost/python/detail/if_else.hpp delete mode 100644 include/boost/python/detail/indirect_traits.hpp delete mode 100644 include/boost/python/detail/invoke.hpp delete mode 100644 include/boost/python/detail/is_auto_ptr.hpp delete mode 100644 include/boost/python/detail/is_function_ref_tester.hpp delete mode 100755 include/boost/python/detail/is_shared_ptr.hpp delete mode 100644 include/boost/python/detail/is_xxx.hpp delete mode 100644 include/boost/python/detail/make_keyword_range_fn.hpp delete mode 100644 include/boost/python/detail/make_tuple.hpp delete mode 100644 include/boost/python/detail/map_entry.hpp delete mode 100644 include/boost/python/detail/member_function_cast.hpp delete mode 100644 include/boost/python/detail/mpl_lambda.hpp delete mode 100644 include/boost/python/detail/msvc_typeinfo.hpp delete mode 100644 include/boost/python/detail/none.hpp delete mode 100644 include/boost/python/detail/not_specified.hpp delete mode 100755 include/boost/python/detail/operator_id.hpp delete mode 100644 include/boost/python/detail/overloads_fwd.hpp delete mode 100644 include/boost/python/detail/pointee.hpp delete mode 100644 include/boost/python/detail/preprocessor.hpp delete mode 100644 include/boost/python/detail/python22_fixed.h delete mode 100644 include/boost/python/detail/raw_pyobject.hpp delete mode 100644 include/boost/python/detail/referent_storage.hpp delete mode 100755 include/boost/python/detail/result.hpp delete mode 100644 include/boost/python/detail/scope.hpp delete mode 100644 include/boost/python/detail/string_literal.hpp delete mode 100644 include/boost/python/detail/target.hpp delete mode 100644 include/boost/python/detail/translate_exception.hpp delete mode 100644 include/boost/python/detail/type_list.hpp delete mode 100644 include/boost/python/detail/type_list_impl.hpp delete mode 100644 include/boost/python/detail/type_list_impl_no_pts.hpp delete mode 100644 include/boost/python/detail/unwind_type.hpp delete mode 100644 include/boost/python/detail/value_is_shared_ptr.hpp delete mode 100644 include/boost/python/detail/value_is_xxx.hpp delete mode 100644 include/boost/python/detail/void_ptr.hpp delete mode 100644 include/boost/python/detail/void_return.hpp delete mode 100644 include/boost/python/detail/wrap_python.hpp delete mode 100644 include/boost/python/dict.hpp delete mode 100644 include/boost/python/enum.hpp delete mode 100644 include/boost/python/errors.hpp delete mode 100644 include/boost/python/exception_translator.hpp delete mode 100644 include/boost/python/extract.hpp delete mode 100755 include/boost/python/handle.hpp delete mode 100755 include/boost/python/handle_fwd.hpp delete mode 100644 include/boost/python/has_back_reference.hpp delete mode 100644 include/boost/python/implicit.hpp delete mode 100644 include/boost/python/init.hpp delete mode 100755 include/boost/python/instance_holder.hpp delete mode 100644 include/boost/python/iterator.hpp delete mode 100644 include/boost/python/list.hpp delete mode 100644 include/boost/python/long.hpp delete mode 100755 include/boost/python/lvalue_from_pytype.hpp delete mode 100644 include/boost/python/make_function.hpp delete mode 100644 include/boost/python/manage_new_object.hpp delete mode 100644 include/boost/python/module.hpp delete mode 100644 include/boost/python/module_init.hpp delete mode 100644 include/boost/python/numeric.hpp delete mode 100755 include/boost/python/object.hpp delete mode 100644 include/boost/python/object/add_to_namespace.hpp delete mode 100644 include/boost/python/object/class.hpp delete mode 100644 include/boost/python/object/class_converters.hpp delete mode 100644 include/boost/python/object/class_detail.hpp delete mode 100644 include/boost/python/object/class_wrapper.hpp delete mode 100644 include/boost/python/object/enum_base.hpp delete mode 100644 include/boost/python/object/find_instance.hpp delete mode 100644 include/boost/python/object/forward.hpp delete mode 100644 include/boost/python/object/function.hpp delete mode 100644 include/boost/python/object/function_handle.hpp delete mode 100644 include/boost/python/object/function_object.hpp delete mode 100644 include/boost/python/object/inheritance.hpp delete mode 100644 include/boost/python/object/instance.hpp delete mode 100644 include/boost/python/object/iterator.hpp delete mode 100644 include/boost/python/object/iterator_core.hpp delete mode 100644 include/boost/python/object/life_support.hpp delete mode 100644 include/boost/python/object/make_holder.hpp delete mode 100644 include/boost/python/object/make_instance.hpp delete mode 100644 include/boost/python/object/make_ptr_instance.hpp delete mode 100644 include/boost/python/object/pickle_support.hpp delete mode 100644 include/boost/python/object/pointer_holder.hpp delete mode 100644 include/boost/python/object/py_function.hpp delete mode 100644 include/boost/python/object/select_holder.hpp delete mode 100644 include/boost/python/object/value_holder.hpp delete mode 100644 include/boost/python/object/value_holder_fwd.hpp delete mode 100755 include/boost/python/object_attributes.hpp delete mode 100644 include/boost/python/object_call.hpp delete mode 100755 include/boost/python/object_core.hpp delete mode 100644 include/boost/python/object_fwd.hpp delete mode 100755 include/boost/python/object_items.hpp delete mode 100644 include/boost/python/object_operators.hpp delete mode 100755 include/boost/python/object_protocol.hpp delete mode 100755 include/boost/python/object_protocol_core.hpp delete mode 100644 include/boost/python/object_slices.hpp delete mode 100644 include/boost/python/operators.hpp delete mode 100755 include/boost/python/other.hpp delete mode 100644 include/boost/python/overloads.hpp delete mode 100644 include/boost/python/pointee.hpp delete mode 100755 include/boost/python/proxy.hpp delete mode 100644 include/boost/python/ptr.hpp delete mode 100755 include/boost/python/raw_function.hpp delete mode 100755 include/boost/python/refcount.hpp delete mode 100644 include/boost/python/reference_existing_object.hpp delete mode 100644 include/boost/python/return_by_value.hpp delete mode 100644 include/boost/python/return_internal_reference.hpp delete mode 100644 include/boost/python/return_value_policy.hpp delete mode 100644 include/boost/python/scope.hpp delete mode 100755 include/boost/python/self.hpp delete mode 100644 include/boost/python/signature.hpp delete mode 100644 include/boost/python/slice_nil.hpp delete mode 100644 include/boost/python/str.hpp delete mode 100644 include/boost/python/tag.hpp delete mode 100644 include/boost/python/to_python_converter.hpp delete mode 100644 include/boost/python/to_python_indirect.hpp delete mode 100644 include/boost/python/to_python_value.hpp delete mode 100644 include/boost/python/tuple.hpp delete mode 100755 include/boost/python/type_id.hpp delete mode 100644 include/boost/python/with_custodian_and_ward.hpp delete mode 100644 index.html delete mode 100644 pyste/README delete mode 100644 pyste/doc/exporting_all_declarations_from_a_header.html delete mode 100644 pyste/doc/introduction.html delete mode 100644 pyste/doc/policies.html delete mode 100644 pyste/doc/pyste.txt delete mode 100644 pyste/doc/renaming_and_excluding.html delete mode 100644 pyste/doc/running_pyste.html delete mode 100644 pyste/doc/templates.html delete mode 100644 pyste/doc/the_interface_files.html delete mode 100644 pyste/doc/theme/alert.gif delete mode 100644 pyste/doc/theme/arrow.gif delete mode 100644 pyste/doc/theme/bkd.gif delete mode 100644 pyste/doc/theme/bkd2.gif delete mode 100644 pyste/doc/theme/bulb.gif delete mode 100644 pyste/doc/theme/bullet.gif delete mode 100644 pyste/doc/theme/c++boost.gif delete mode 100644 pyste/doc/theme/l_arr.gif delete mode 100644 pyste/doc/theme/l_arr_disabled.gif delete mode 100644 pyste/doc/theme/note.gif delete mode 100644 pyste/doc/theme/r_arr.gif delete mode 100644 pyste/doc/theme/r_arr_disabled.gif delete mode 100644 pyste/doc/theme/smiley.gif delete mode 100644 pyste/doc/theme/style.css delete mode 100644 pyste/doc/theme/u_arr.gif delete mode 100644 pyste/doc/wrappers.html delete mode 100644 pyste/example/README delete mode 100644 pyste/example/basic.h delete mode 100644 pyste/example/basic.pyste delete mode 100644 pyste/example/enums.h delete mode 100644 pyste/example/enums.pyste delete mode 100644 pyste/example/header_test.h delete mode 100644 pyste/example/header_test.pyste delete mode 100644 pyste/example/nested.h delete mode 100644 pyste/example/nested.pyste delete mode 100644 pyste/example/operator.h delete mode 100644 pyste/example/operator.pyste delete mode 100644 pyste/example/templates.h delete mode 100644 pyste/example/templates.pyste delete mode 100644 pyste/example/wrappertest.h delete mode 100644 pyste/example/wrappertest.pyste delete mode 100644 pyste/example/wrappertest_wrappers.h delete mode 100644 pyste/index.html delete mode 100644 pyste/src/.cvsignore delete mode 100644 pyste/src/ClassExporter.py delete mode 100644 pyste/src/CodeUnit.py delete mode 100644 pyste/src/CppParser.py delete mode 100644 pyste/src/EnumExporter.py delete mode 100644 pyste/src/Exporter.py delete mode 100644 pyste/src/FunctionExporter.py delete mode 100644 pyste/src/GCCXMLParser.py delete mode 100644 pyste/src/HeaderExporter.py delete mode 100644 pyste/src/IncludeExporter.py delete mode 100644 pyste/src/declarations.py delete mode 100644 pyste/src/enumerate.py delete mode 100644 pyste/src/exporters.py delete mode 100644 pyste/src/exporterutils.py delete mode 100644 pyste/src/infos.py delete mode 100644 pyste/src/policies.py delete mode 100644 pyste/src/pyste-profile.py delete mode 100644 pyste/src/pyste.py delete mode 100644 pyste/src/settings.py delete mode 100644 pyste/tests/GCCXMLParserUT.py delete mode 100644 pyste/tests/infosUT.py delete mode 100644 pyste/tests/policiesUT.py delete mode 100644 pyste/tests/runtests.py delete mode 100644 release_notes.txt delete mode 100644 src/aix_init_module.cpp delete mode 100644 src/converter/arg_to_python_base.cpp delete mode 100644 src/converter/builtin_converters.cpp delete mode 100644 src/converter/from_python.cpp delete mode 100644 src/converter/registry.cpp delete mode 100644 src/converter/type_id.cpp delete mode 100644 src/dict.cpp delete mode 100644 src/errors.cpp delete mode 100644 src/list.cpp delete mode 100644 src/long.cpp delete mode 100644 src/module.cpp delete mode 100644 src/numeric.cpp delete mode 100644 src/object/class.cpp delete mode 100644 src/object/enum.cpp delete mode 100644 src/object/function.cpp delete mode 100644 src/object/inheritance.cpp delete mode 100644 src/object/iterator.cpp delete mode 100644 src/object/life_support.cpp delete mode 100644 src/object/pickle_support.cpp delete mode 100644 src/object_operators.cpp delete mode 100755 src/object_protocol.cpp delete mode 100644 src/str.cpp delete mode 100644 src/tuple.cpp delete mode 100644 test/args.cpp delete mode 100644 test/args.py delete mode 100644 test/as_to_python_function.cpp delete mode 100644 test/auto_ptr.cpp delete mode 100644 test/auto_ptr.py delete mode 100644 test/back_reference.cpp delete mode 100644 test/back_reference.py delete mode 100644 test/bases.cpp delete mode 100644 test/ben_scott1.cpp delete mode 100644 test/ben_scott1.py delete mode 100644 test/bienstman1.cpp delete mode 100644 test/bienstman1.py delete mode 100644 test/bienstman2.cpp delete mode 100644 test/bienstman2.py delete mode 100644 test/bienstman3.cpp delete mode 100644 test/bienstman3.py delete mode 100644 test/bienstman4.cpp delete mode 100644 test/bienstman4.py delete mode 100644 test/bienstman5.cpp delete mode 100644 test/bienstman5.py delete mode 100755 test/borrowed.cpp delete mode 100644 test/callbacks.cpp delete mode 100644 test/callbacks.py delete mode 100755 test/cltree.cpp delete mode 100644 test/complicated.hpp delete mode 100755 test/copy_ctor_mutates_rhs.cpp delete mode 100644 test/data_members.cpp delete mode 100644 test/data_members.py delete mode 100644 test/defaults.cpp delete mode 100644 test/defaults.py delete mode 100644 test/destroy_test.cpp delete mode 100644 test/dict.cpp delete mode 100644 test/dict.py delete mode 100644 test/docstring.cpp delete mode 100644 test/docstring.py delete mode 100644 test/embedding.cpp delete mode 100644 test/enum.cpp delete mode 100644 test/enum.py delete mode 100644 test/exception_translator.cpp delete mode 100644 test/exception_translator.py delete mode 100644 test/extract.cpp delete mode 100644 test/extract.py delete mode 100644 test/if_else.cpp delete mode 100644 test/implicit.cpp delete mode 100644 test/implicit.py delete mode 100644 test/indirect_traits_test.cpp delete mode 100644 test/input_iterator.cpp delete mode 100644 test/iterator.cpp delete mode 100644 test/iterator.py delete mode 100644 test/list.cpp delete mode 100644 test/list.py delete mode 100644 test/long.cpp delete mode 100644 test/long.py delete mode 100644 test/m1.cpp delete mode 100644 test/m2.cpp delete mode 100644 test/member_function_cast.cpp delete mode 100644 test/minimal.cpp delete mode 100644 test/minimal.py delete mode 100644 test/module_tail.cpp delete mode 100644 test/multi_arg_constructor.cpp delete mode 100644 test/multi_arg_constructor.py delete mode 100644 test/nested.cpp delete mode 100644 test/nested.py delete mode 100644 test/newtest.py delete mode 100644 test/numpy.cpp delete mode 100644 test/numpy.py delete mode 100755 test/object.cpp delete mode 100644 test/object.py delete mode 100755 test/object_fail1.cpp delete mode 100755 test/object_manager.cpp delete mode 100755 test/operators.cpp delete mode 100644 test/operators.py delete mode 100644 test/pickle1.cpp delete mode 100644 test/pickle1.py delete mode 100644 test/pickle2.cpp delete mode 100644 test/pickle2.py delete mode 100644 test/pickle3.cpp delete mode 100644 test/pickle3.py delete mode 100644 test/pointee.cpp delete mode 100644 test/pointer_type_id_test.cpp delete mode 100644 test/polymorphism.cpp delete mode 100644 test/polymorphism.py delete mode 100755 test/raw_pyobject_fail1.cpp delete mode 100755 test/raw_pyobject_fail2.cpp delete mode 100755 test/result.cpp delete mode 100644 test/select_arg_to_python_test.cpp delete mode 100644 test/select_from_python_test.cpp delete mode 100644 test/select_holder.cpp delete mode 100644 test/shared_ptr.cpp delete mode 100644 test/shared_ptr.py delete mode 100644 test/simple_type.hpp delete mode 100644 test/staticmethod.cpp delete mode 100644 test/staticmethod.py delete mode 100644 test/str.cpp delete mode 100644 test/str.py delete mode 100644 test/string_literal.cpp delete mode 100644 test/submod_subclass_api.cpp delete mode 100644 test/test_builtin_converters.cpp delete mode 100644 test/test_builtin_converters.py delete mode 100644 test/test_class.hpp delete mode 100644 test/test_cltree.py delete mode 100644 test/test_pointer_adoption.cpp delete mode 100644 test/test_pointer_adoption.py delete mode 100644 test/tuple.cpp delete mode 100644 test/tuple.py delete mode 100755 test/upcast.cpp delete mode 100644 test/virtual_functions.cpp delete mode 100644 test/virtual_functions.py delete mode 100644 todo.txt diff --git a/build/Attic/python_v1.zip b/build/Attic/python_v1.zip deleted file mode 100644 index 0377a07bb35337fd47e14de78bc55819015567fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236665 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 ! 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 diff --git a/build/Jamfile b/build/Jamfile deleted file mode 100644 index b58c22dc..00000000 --- a/build/Jamfile +++ /dev/null @@ -1,84 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# Boost.Python library Jamfile - - -# declare the location of this subproject relative to the root -subproject libs/python/build ; - -# bring in the rules for python -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -if [ check-python-config ] -{ - - local bpl-linkflags ; - - if $(UNIX) && ( $(OS) = AIX ) - { - bpl-linkflags = "-e initlibboost_python" ; - } - - # Enabling intrinsics (/0i) or maximize speed (/02) seem to cause - # internal compiler errors with this toolset. - local msvc-stlport-workarounds - = off "-Ogty -O1 -Gs" ; - - local sources = - numeric.cpp - list.cpp - long.cpp - dict.cpp - tuple.cpp - str.cpp - - aix_init_module.cpp - converter/from_python.cpp - converter/registry.cpp - converter/type_id.cpp - object/enum.cpp - object/class.cpp - object/function.cpp - object/inheritance.cpp - object/life_support.cpp - object/pickle_support.cpp - errors.cpp - module.cpp - converter/builtin_converters.cpp - converter/arg_to_python_base.cpp - object/iterator.cpp - object_protocol.cpp - object_operators.cpp - ; - - dll boost_python - : ../src/$(sources) - : $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - $(bpl-linkflags) - $(msvc-stlport-workarounds) - ; - - lib boost_python - : # sources - ../src/$(sources) - - : # requirements - $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - BOOST_STATIC_LIB - $(bpl-linkflags) - $(msvc-stlport-workarounds) - ; - - stage bin-stage : boost_python boost_python - : "_debug" - "_pydebug" - : - debug release - ; -} \ No newline at end of file diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 deleted file mode 100644 index 7b9e21f1..00000000 --- a/build/Jamfile.v2 +++ /dev/null @@ -1,85 +0,0 @@ -import os ; - -# Use a very crude way to sense there python is locatted - -local PYTHON_PATH ; - -if [ GLOB /usr/local/include/python2.2 : * ] -{ - PYTHON_PATH = /usr/local ; -} -else if [ GLOB /usr/include/python2.2 : * ] -{ - PYTHON_PATH = /usr ; -} - -if [ os.name ] in CYGWIN NT -{ - lib_condition = shared: ; - defines = USE_DL_IMPORT ; - - # Declare a target for the python interpreter library - lib python : : python2.2.dll ; - PYTHON_LIB = python ; -} -else -{ - lib python : : python2.2 ; - PYTHON_LIB = python ; -} - - - -if $(PYTHON_PATH) { - - -project boost/python - : source-location ../src - : requirements $(PYTHON_PATH)/include/python2.2 - $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config - shared:$(PYTHON_LIB) - $(defines) - : usage-requirements # requirement that will be propageted to *users* of this library - $(PYTHON_PATH)/include/python2.2 - -# We have a bug which causes us to conclude that conditionalized -# properties in this section are not free. -# $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config -# true:$(PYTHON_LIB) - - $(PYTHON_PATH)/lib/python2.2/config - $(PYTHON_LIB) - ; - -lib boost_python - : - numeric.cpp - - list.cpp - long.cpp - dict.cpp - tuple.cpp - str.cpp - - aix_init_module.cpp - converter/from_python.cpp - converter/registry.cpp - converter/type_id.cpp - object/enum.cpp - object/class.cpp - object/function.cpp - object/inheritance.cpp - object/life_support.cpp - object/pickle_support.cpp - errors.cpp - module.cpp - converter/builtin_converters.cpp - converter/arg_to_python_base.cpp - object/iterator.cpp - object_protocol.cpp - object_operators.cpp - : static:BOOST_PYTHON_STATIC_LIB - BOOST_PYTHON_SOURCE - : shared - ; -} diff --git a/build/VisualStudio/boost_python.dsp b/build/VisualStudio/boost_python.dsp deleted file mode 100644 index 1e4c5358..00000000 --- a/build/VisualStudio/boost_python.dsp +++ /dev/null @@ -1,882 +0,0 @@ -# Microsoft Developer Studio Project File - Name="boost_python" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=BOOST_PYTHON - WIN32 RELEASE -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "boost_python.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "boost_python.mak" CFG="BOOST_PYTHON - WIN32 RELEASE" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "boost_python - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "boost_python - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "boost_python - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "../bin-stage" -# PROP Intermediate_Dir "release-obj" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -F90=df.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /c -# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1409 /d "NDEBUG" -# ADD RSC /l 0x1409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386 - -!ELSEIF "$(CFG)" == "boost_python - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "../bin-stage" -# PROP Intermediate_Dir "debug-obj" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -F90=df.exe -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /GZ /c -# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "../../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /Zm800 /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1409 /d "_DEBUG" -# ADD RSC /l 0x1409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"../bin-stage/boost_python_debug.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "boost_python - Win32 Release" -# Name "boost_python - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\aix_init_module.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\arg_to_python_base.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\builtin_converters.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\class.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\dict.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\enum.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\errors.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\from_python.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\function.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\inheritance.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\iterator.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\life_support.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\list.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\long.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\module.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\numeric.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object_operators.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object_protocol.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\object\pickle_support.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\registry.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\str.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\tuple.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\converter\type_id.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Group "detail" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\aix_init_module.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\api_placeholder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\arg_tuple_size.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\borrowed_ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\call_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\caller.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\char_array.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\config.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\construct.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\convertible.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\cv_category.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\decorated_type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\def_helper.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\defaults_def.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\defaults_gen.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\dependent.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\destroy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\exception_handler.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\force_instantiate.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\if_else.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\indirect_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\make_keyword_range_fn.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\make_tuple.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\map_entry.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\member_function_cast.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\module_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\module_init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\msvc_typeinfo.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\none.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\not_specified.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\operator_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\overloads_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\preprocessor.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\python22_fixed.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\raw_pyobject.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\referent_storage.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\result.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\returning.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\scope.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\string_literal.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\target.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\translate_exception.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_impl.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_impl_no_pts.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\type_list_utils.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\unwind_type.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\void_ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\void_return.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\detail\wrap_python.hpp -# End Source File -# End Group -# Begin Group "converter" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_to_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\arg_to_python_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\builtin_converters.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\constructor_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\convertible_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\implicit.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\obj_mgr_arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\object_manager.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pointer_type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pyobject_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pyobject_type.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pytype_arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\pytype_object_mgr_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registered.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registered_pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registrations.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\registry.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\return_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\rvalue_from_python_data.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\converter\to_python_function_type.hpp -# End Source File -# End Group -# Begin Group "object" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\add_to_namespace.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_converters.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_detail.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\class_wrapper.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\construct.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\enum_base.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\find_instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\forward.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function_handle.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\function_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\inheritance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\iterator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\iterator_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\life_support.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\make_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\make_instance.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\pickle_support.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\pointer_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\py_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\select_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\value_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object\value_holder_fwd.hpp -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\..\..\boost\python\arg_from_python.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\args.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\args_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\back_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\base_type_traits.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\bases.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\borrowed.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\call.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\call_method.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\cast.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\class.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\class_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\copy_const_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\copy_non_const_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\data_members.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\def.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\default_call_policies.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\dict.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\enum.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\errors.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\exception_translator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\extract.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\handle.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\handle_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\has_back_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\implicit.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\instance_holder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\iterator.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\list.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\long.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\lvalue_from_pytype.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\make_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\manage_new_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\module.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\module_init.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\numeric.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_attributes.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_call.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_fwd.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_items.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_operators.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_protocol.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_protocol_core.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\object_slices.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\operators.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\operators2.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\other.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\overloads.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\pointee.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\proxy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\ptr.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\refcount.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\reference_existing_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\return_internal_reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\return_value_policy.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\scope.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\self.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\signature.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\slice_nil.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\str.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\tag.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_converter.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_indirect.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\to_python_value.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\tuple.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\type_id.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\boost\python\with_custodian_and_ward.hpp -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/VisualStudio/boost_python.dsw b/build/VisualStudio/boost_python.dsw deleted file mode 100644 index 574c3bf8..00000000 --- a/build/VisualStudio/boost_python.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "boost_python"=".\boost_python.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/build/python_v1.zip b/build/python_v1.zip deleted file mode 100644 index 0377a07bb35337fd47e14de78bc55819015567fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236665 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 ! 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 diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt deleted file mode 100644 index 8113f50e..00000000 --- a/doc/PyConDC_2003/bpl.txt +++ /dev/null @@ -1,853 +0,0 @@ -+++++++++++++++++++++++++++++++++++++++++++ - Building Hybrid Systems with Boost.Python -+++++++++++++++++++++++++++++++++++++++++++ - -:Author: David Abrahams -:Contact: dave@boost-consulting.com -:organization: `Boost Consulting`_ -:date: $Date$ - -:Author: Ralf W. Grosse-Kunstleve - -:status: Draft -:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved - -.. contents:: Table of Contents - - -.. _`Boost Consulting`: http://www.boost-consulting.com - -========== - Abstract -========== - -Boost.Python is an open source C++ library which provides a concise -IDL-like interface for binding C++ classes and functions to -Python. Leveraging the full power of C++ compile-time introspection -and of recently developed metaprogramming techniques, this is achieved -entirely in pure C++, without introducing a new syntax. -Boost.Python's rich set of features and high-level interface make it -possible to engineer packages from the ground up as hybrid systems, -giving programmers easy and coherent access to both the efficient -compile-time polymorphism of C++ and the extremely convenient run-time -polymorphism of Python. - -============== - Introduction -============== - -Python and C++ are in many ways as different as two languages could -be: while C++ is usually compiled to machine-code, Python is -interpreted. Python's dynamic type system is often cited as the -foundation of its flexibility, while in C++ static typing is the -cornerstone of its efficiency. C++ has an intricate and difficult -compile-time meta-language, while in Python, practically everything -happens at runtime. - -Yet for many programmers, these very differences mean that Python and -C++ complement one another perfectly. Performance bottlenecks in -Python programs can be rewritten in C++ for maximal speed, and -authors of powerful C++ libraries choose Python as a middleware -language for its flexible system integration capabilities. -Furthermore, the surface differences mask some strong similarities: - -* 'C'-family control structures (if, while, for...) - -* Support for object-orientation, functional programming, and generic - programming (these are both *multi-paradigm* programming languages.) - -* Comprehensive operator overloading facilities, recognizing the - importance of syntactic variability for readability and - expressivity. - -* High-level concepts such as collections and iterators. - -* High-level encapsulation facilities (C++: namespaces, Python: modules) - to support the design of re-usable libraries. - -* Exception-handling for effective management of error conditions. - -* C++ idioms in common use, such as handle/body classes and - reference-counted smart pointers mirror Python reference semantics. - -Given Python's rich 'C' interoperability API, it should in principle -be possible to expose C++ type and function interfaces to Python with -an analogous interface to their C++ counterparts. However, the -facilities provided by Python alone for integration with C++ are -relatively meager. Compared to C++ and Python, 'C' has only very -rudimentary abstraction facilities, and support for exception-handling -is completely missing. 'C' extension module writers are required to -manually manage Python reference counts, which is both annoyingly -tedious and extremely error-prone. Traditional extension modules also -tend to contain a great deal of boilerplate code repetition which -makes them difficult to maintain, especially when wrapping an evolving -API. - -These limitations have lead to the development of a variety of wrapping -systems. SWIG_ is probably the most popular package for the -integration of C/C++ and Python. A more recent development is SIP_, -which was specifically designed for interfacing Python with the Qt_ -graphical user interface library. Both SWIG and SIP introduce their -own specialized languages for customizing inter-language bindings. -This has certain advantages, but having to deal with three different -languages (Python, C/C++ and the interface language) also introduces -practical and mental difficulties. The CXX_ package demonstrates an -interesting alternative. It shows that at least some parts of -Python's 'C' API can be wrapped and presented through a much more -user-friendly C++ interface. However, unlike SWIG and SIP, CXX does -not include support for wrapping C++ classes as new Python types. - -The features and goals of Boost.Python_ overlap significantly with -many of these other systems. That said, Boost.Python attempts to -maximize convenience and flexibility without introducing a separate -wrapping language. Instead, it presents the user with a high-level -C++ interface for wrapping C++ classes and functions, managing much of -the complexity behind-the-scenes with static metaprogramming. -Boost.Python also goes beyond the scope of earlier systems by -providing: - -* Support for C++ virtual functions that can be overridden in Python. - -* Comprehensive lifetime management facilities for low-level C++ - pointers and references. - -* Support for organizing extensions as Python packages, - with a central registry for inter-language type conversions. - -* A safe and convenient mechanism for tying into Python's powerful - serialization engine (pickle). - -* Coherence with the rules for handling C++ lvalues and rvalues that - can only come from a deep understanding of both the Python and C++ - type systems. - -The key insight that sparked the development of Boost.Python is that -much of the boilerplate code in traditional extension modules could be -eliminated using C++ compile-time introspection. Each argument of a -wrapped C++ function must be extracted from a Python object using a -procedure that depends on the argument type. Similarly the function's -return type determines how the return value will be converted from C++ -to Python. Of course argument and return types are part of each -function's type, and this is exactly the source from which -Boost.Python deduces most of the information required. - -This approach leads to *user guided wrapping*: as much information is -extracted directly from the source code to be wrapped as is possible -within the framework of pure C++, and some additional information is -supplied explicitly by the user. Mostly the guidance is mechanical -and little real intervention is required. Because the interface -specification is written in the same full-featured language as the -code being exposed, the user has unprecedented power available when -she does need to take control. - -.. _Python: http://www.python.org/ -.. _SWIG: http://www.swig.org/ -.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php -.. _Qt: http://www.trolltech.com/ -.. _CXX: http://cxx.sourceforge.net/ -.. _Boost.Python: http://www.boost.org/libs/python/doc - -=========================== - Boost.Python Design Goals -=========================== - -The primary goal of Boost.Python is to allow users to expose C++ -classes and functions to Python using nothing more than a C++ -compiler. In broad strokes, the user experience should be one of -directly manipulating C++ objects from Python. - -However, it's also important not to translate all interfaces *too* -literally: the idioms of each language must be respected. For -example, though C++ and Python both have an iterator concept, they are -expressed very differently. Boost.Python has to be able to bridge the -interface gap. - -It must be possible to insulate Python users from crashes resulting -from trivial misuses of C++ interfaces, such as accessing -already-deleted objects. By the same token the library should -insulate C++ users from low-level Python 'C' API, replacing -error-prone 'C' interfaces like manual reference-count management and -raw ``PyObject`` pointers with more-robust alternatives. - -Support for component-based development is crucial, so that C++ types -exposed in one extension module can be passed to functions exposed in -another without loss of crucial information like C++ inheritance -relationships. - -Finally, all wrapping must be *non-intrusive*, without modifying or -even seeing the original C++ source code. Existing C++ libraries have -to be wrappable by third parties who only have access to header files -and binaries. - -========================== - Hello Boost.Python World -========================== - -And now for a preview of Boost.Python, and how it improves on the raw -facilities offered by Python. Here's a function we might want to -expose:: - - char const* greet(unsigned x) - { - static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; - - if (x > 2) - throw std::range_error("greet: index out of range"); - - return msgs[x]; - } - -To wrap this function in standard C++ using the Python 'C' API, we'd -need something like this:: - - extern "C" // all Python interactions use 'C' linkage and calling convention - { - // Wrapper to handle argument/result conversion and checking - PyObject* greet_wrap(PyObject* args, PyObject * keywords) - { - int x; - if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments - { - char const* result = greet(x); // invoke wrapped function - return PyString_FromString(result); // convert result to Python - } - return 0; // error occurred - } - - // Table of wrapped functions to be exposed by the module - static PyMethodDef methods[] = { - { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" } - , { NULL, NULL, 0, NULL } // sentinel - }; - - // module initialization function - DL_EXPORT init_hello() - { - (void) Py_InitModule("hello", methods); // add the methods to the module - } - } - -Now here's the wrapping code we'd use to expose it with Boost.Python:: - - #include - using namespace boost::python; - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet, "return one of 3 parts of a greeting"); - } - -and here it is in action:: - - >>> import hello - >>> for x in range(3): - ... print hello.greet(x) - ... - hello - Boost.Python - world! - -Aside from the fact that the 'C' API version is much more verbose, -it's worth noting a few things that it doesn't handle correctly: - -* The original function accepts an unsigned integer, and the Python - 'C' API only gives us a way of extracting signed integers. The - Boost.Python version will raise a Python exception if we try to pass - a negative number to ``hello.greet``, but the other one will proceed - to do whatever the C++ implementation does when converting an - negative integer to unsigned (usually wrapping to some very large - number), and pass the incorrect translation on to the wrapped - function. - -* That brings us to the second problem: if the C++ ``greet()`` - function is called with a number greater than 2, it will throw an - exception. Typically, if a C++ exception propagates across the - boundary with code generated by a 'C' compiler, it will cause a - crash. As you can see in the first version, there's no C++ - scaffolding there to prevent this from happening. Functions wrapped - by Boost.Python automatically include an exception-handling layer - which protects Python users by translating unhandled C++ exceptions - into a corresponding Python exception. - -* A slightly more-subtle limitation is that the argument conversion - used in the Python 'C' API case can only get that integer ``x`` in - *one way*. PyArg_ParseTuple can't convert Python ``long`` objects - (arbitrary-precision integers) which happen to fit in an ``unsigned - int`` but not in a ``signed long``, nor will it ever handle a - wrapped C++ class with a user-defined implicit ``operator unsigned - int()`` conversion. Boost.Python's dynamic type conversion - registry allows users to add arbitrary conversion methods. - -================== - Library Overview -================== - -This section outlines some of the library's major features. Except as -neccessary to avoid confusion, details of library implementation are -omitted. - ------------------- - Exposing Classes ------------------- - -C++ classes and structs are exposed with a similarly-terse interface. -Given:: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -The following code will expose it in our extension module:: - - #include - BOOST_PYTHON_MODULE(hello) - { - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -Although this code has a certain pythonic familiarity, people -sometimes find the syntax bit confusing because it doesn't look like -most of the C++ code they're used to. All the same, this is just -standard C++. Because of their flexible syntax and operator -overloading, C++ and Python are great for defining domain-specific -(sub)languages -(DSLs), and that's what we've done in Boost.Python. To break it down:: - - class_("World") - -constructs an unnamed object of type ``class_`` and passes -``"World"`` to its constructor. This creates a new-style Python class -called ``World`` in the extension module, and associates it with the -C++ type ``World`` in the Boost.Python type conversion registry. We -might have also written:: - - class_ w("World"); - -but that would've been more verbose, since we'd have to name ``w`` -again to invoke its ``def()`` member function:: - - w.def("greet", &World::greet) - -There's nothing special about the location of the dot for member -access in the original example: C++ allows any amount of whitespace on -either side of a token, and placing the dot at the beginning of each -line allows us to chain as many successive calls to member functions -as we like with a uniform syntax. The other key fact that allows -chaining is that ``class_<>`` member functions all return a reference -to ``*this``. - -So the example is equivalent to:: - - class_ w("World"); - w.def("greet", &World::greet); - w.def("set", &World::set); - -It's occasionally useful to be able to break down the components of a -Boost.Python class wrapper in this way, but the rest of this article -will stick to the terse syntax. - -For completeness, here's the wrapped class in use: :: - - >>> import hello - >>> planet = hello.World() - >>> planet.set('howdy') - >>> planet.greet() - 'howdy' - -Constructors -============ - -Since our ``World`` class is just a plain ``struct``, it has an -implicit no-argument (nullary) constructor. Boost.Python exposes the -nullary constructor by default, which is why we were able to write: :: - - >>> planet = hello.World() - -However, well-designed classes in any language may require constructor -arguments in order to establish their invariants. Unlike Python, -where ``__init__`` is just a specially-named method, In C++ -constructors cannot be handled like ordinary member functions. In -particular, we can't take their address: ``&World::World`` is an -error. The library provides a different interface for specifying -constructors. Given:: - - struct World - { - World(std::string msg); // added constructor - ... - -we can modify our wrapping code as follows:: - - class_("World", init()) - ... - -of course, a C++ class may have additional constructors, and we can -expose those as well by passing more instances of ``init<...>`` to -``def()``:: - - class_("World", init()) - .def(init()) - ... - -Boost.Python allows wrapped functions, member functions, and -constructors to be overloaded to mirror C++ overloading. - -Data Members and Properties -=========================== - -Any publicly-accessible data members in a C++ class can be easily -exposed as either ``readonly`` or ``readwrite`` attributes:: - - class_("World", init()) - .def_readonly("msg", &World::msg) - ... - -and can be used directly in Python: :: - - >>> planet = hello.World('howdy') - >>> planet.msg - 'howdy' - -This does *not* result in adding attributes to the ``World`` instance -``__dict__``, which can result in substantial memory savings when -wrapping large data structures. In fact, no instance ``__dict__`` -will be created at all unless attributes are explicitly added from -Python. Boost.Python owes this capability to the new Python 2.2 type -system, in particular the descriptor interface and ``property`` type. - -In C++, publicly-accessible data members are considered a sign of poor -design because they break encapsulation, and style guides usually -dictate the use of "getter" and "setter" functions instead. In -Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, -``property`` mean that attribute access is just one more -well-encapsulated syntactic tool at the programmer's disposal. -Boost.Python bridges this idiomatic gap by making Python ``property`` -creation directly available to users. If ``msg`` were private, we -could still expose it as attribute in Python as follows:: - - class_("World", init()) - .add_property("msg", &World::greet, &World::set) - ... - -The example above mirrors the familiar usage of properties in Python -2.2+: :: - - >>> class World(object): - ... __init__(self, msg): - ... self.__msg = msg - ... def greet(self): - ... return self.__msg - ... def set(self, msg): - ... self.__msg = msg - ... msg = property(greet, set) - -Operator Overloading -==================== - -The ability to write arithmetic operators for user-defined types has -been a major factor in the success of both languages for numerical -computation, and the success of packages like NumPy_ attests to the -power of exposing operators in extension modules. Boost.Python -provides a concise mechanism for wrapping operator overloads. The -example below shows a fragment from a wrapper for the Boost rational -number library:: - - class_ >("rational_int") - .def(init()) // constructor, e.g. rational_int(3,4) - .def("numerator", &rational::numerator) - .def("denominator", &rational::denominator) - .def(-self) // __neg__ (unary minus) - .def(self + self) // __add__ (homogeneous) - .def(self * self) // __mul__ - .def(self + int()) // __add__ (heterogenous) - .def(int() + self) // __radd__ - ... - -The magic is performed using a simplified application of "expression -templates" [VELD1995]_, a technique originally developed for -optimization of high-performance matrix algebra expressions. The -essence is that instead of performing the computation immediately, -operators are overloaded to construct a type *representing* the -computation. In matrix algebra, dramatic optimizations are often -available when the structure of an entire expression can be taken into -account, rather than evaluating each operation "greedily". -Boost.Python uses the same technique to build an appropriate Python -method object based on expressions involving ``self``. - -.. _NumPy: http://www.pfdubois.com/numpy/ - -Inheritance -=========== - -C++ inheritance relationships can be represented to Boost.Python by adding -an optional ``bases<...>`` argument to the ``class_<...>`` template -parameter list as follows:: - - class_ >("Derived") - ... - -This has two effects: - -1. When the ``class_<...>`` is created, Python type objects - corresponding to ``Base1`` and ``Base2`` are looked up in - Boost.Python's registry, and are used as bases for the new Python - ``Derived`` type object, so methods exposed for the Python ``Base1`` - and ``Base2`` types are automatically members of the ``Derived`` - type. Because the registry is global, this works correctly even if - ``Derived`` is exposed in a different module from either of its - bases. - -2. C++ conversions from ``Derived`` to its bases are added to the - Boost.Python registry. Thus wrapped C++ methods expecting (a - pointer or reference to) an object of either base type can be - called with an object wrapping a ``Derived`` instance. Wrapped - member functions of class ``T`` are treated as though they have an - implicit first argument of ``T&``, so these conversions are - neccessary to allow the base class methods to be called for derived - objects. - -Of course it's possible to derive new Python classes from wrapped C++ -class instances. Because Boost.Python uses the new-style class -system, that works very much as for the Python built-in types. There -is one significant detail in which it differs: the built-in types -generally establish their invariants in their ``__new__`` function, so -that derived classes do not need to call ``__init__`` on the base -class before invoking its methods : :: - - >>> class L(list): - ... def __init__(self): - ... pass - ... - >>> L().reverse() - >>> - -Because C++ object construction is a one-step operation, C++ instance -data cannot be constructed until the arguments are available, in the -``__init__`` function: :: - - >>> class D(SomeBoostPythonClass): - ... def __init__(self): - ... pass - ... - >>> D().some_boost_python_method() - Traceback (most recent call last): - File "", line 1, in ? - TypeError: bad argument type for built-in operation - -This happened because Boost.Python couldn't find instance data of type -``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__`` -function masked construction of the base class. It could be corrected -by either removing ``D``'s ``__init__`` function or having it call -``SomeBoostPythonClass.__init__(...)`` explicitly. - -Virtual Functions -================= - -Deriving new types in Python from extension classes is not very -interesting unless they can be used polymorphically from C++. In -other words, Python method implementations should appear to override -the implementation of C++ virtual functions when called *through base -class pointers/references from C++*. Since the only way to alter the -behavior of a virtual function is to override it in a derived class, -the user must build a special derived class to dispatch a polymorphic -class' virtual functions:: - - // - // interface to wrap: - // - class Base - { - public: - virtual int f(std::string x) { return 42; } - virtual ~Base(); - }; - - int calls_f(Base const& b, std::string x) { return b.f(x); } - - // - // Wrapping Code - // - - // Dispatcher class - struct BaseWrap : Base - { - // Store a pointer to the Python object - BaseWrap(PyObject* self_) : self(self_) {} - PyObject* self; - - // Default implementation, for when f is not overridden - int f_default(std::string x) { return this->Base::f(x); } - // Dispatch implementation - int f(std::string x) { return call_method(self, "f", x); } - }; - - ... - def("calls_f", calls_f); - class_("Base") - .def("f", &Base::f, &BaseWrap::f_default) - ; - -Now here's some Python code which demonstrates: :: - - >>> class Derived(Base): - ... def f(self, s): - ... return len(s) - ... - >>> calls_f(Base(), 'foo') - 42 - >>> calls_f(Derived(), 'forty-two') - 9 - -Things to notice about the dispatcher class: - -* The key element which allows overriding in Python is the - ``call_method`` invocation, which uses the same global type - conversion registry as the C++ function wrapping does to convert its - arguments from C++ to Python and its return type from Python to C++. - -* Any constructor signatures you wish to wrap must be replicated with - an initial ``PyObject*`` argument - -* The dispatcher must store this argument so that it can be used to - invoke ``call_method`` - -* The ``f_default`` member function is needed when the function being - exposed is not pure virtual; there's no other way ``Base::f`` can be - called on an object of type ``BaseWrap``, since it overrides ``f``. - -Deeper Reflection on the Horizon? -================================= - -Admittedly, this formula is tedious to repeat, especially on a project -with many polymorphic classes. That it is neccessary reflects some -limitations in C++'s compile-time introspection capabilities: there's -no way to enumerate the members of a class and find out which are -virtual functions. At least one very promising project has been -started to write a front-end which can generate these dispatchers (and -other wrapping code) automatically from C++ headers. - -Pyste builds on GCC_XML_, which generates an XML version of GCC's -internal program representation. Since GCC is a highly-conformant C++ -compiler, this ensures correct handling of the most-sophisticated -template code and full access to the underlying type system. In -keeping with the Boost.Python philosophy, a Pyste interface -description is neither intrusive on the code being wrapped, nor -expressed in some unfamiliar language: instead it is a 100% pure -Python script. If Pyste is successful it will mark a move away from -wrapping everything directly in C++ for many of our users. We expect -that soon, not only our users but the Boost.Python developers -themselves will be "thinking hybrid" about their own code. - -.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html - ---------------- - Serialization ---------------- - -*Serialization* is the process of converting objects in memory to a -form that can be stored on disk or sent over a network connection. The -serialized object (most often a plain string) can be retrieved and -converted back to the original object. A good serialization system will -automatically convert entire object hierarchies. Python's standard -``pickle`` module is just such a system. It leverages the language's strong -runtime introspection facilities for serializing practically arbitrary -user-defined objects. With a few simple and unintrusive provisions this -powerful machinery can be extended to also work for wrapped C++ objects. -Here is an example:: - - #include - - struct World - { - World(std::string a_msg) : msg(a_msg) {} - std::string greet() const { return msg; } - std::string msg; - }; - - #include - using namespace boost::python; - - struct World_picklers : pickle_suite - { - static tuple - getinitargs(World const& w) { return make_tuple(w.greet()); } - }; - - BOOST_PYTHON_MODULE(hello) - { - class_("World", init()) - .def("greet", &World::greet) - .def_pickle(World_picklers()) - ; - } - -Now let's create a ``World`` object and put it to rest on disk:: - - >>> import hello - >>> import pickle - >>> a_world = hello.World("howdy") - >>> pickle.dump(a_world, open("my_world", "w")) - -In a potentially *different script* on a potentially *different -computer* with a potentially *different operating system*:: - - >>> import pickle - >>> resurrected_world = pickle.load(open("my_world", "r")) - >>> resurrected_world.greet() - 'howdy' - -Of course the ``cPickle`` module can also be used for faster -processing. - -Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol -defined in the standard Python documentation. Like a __getinitargs__ -function in Python, the pickle_suite's getinitargs() is responsible for -creating the argument tuple that will be use to reconstruct the pickled -object. The other elements of the Python pickling protocol, -__getstate__ and __setstate__ can be optionally provided via C++ -getstate and setstate functions. C++'s static type system allows the -library to ensure at compile-time that nonsensical combinations of -functions (e.g. getstate without setstate) are not used. - -Enabling serialization of more complex C++ objects requires a little -more work than is shown in the example above. Fortunately the -``object`` interface (see next section) greatly helps in keeping the -code manageable. - ------------------- - Object interface ------------------- - -Experienced 'C' language extension module authors will be familiar -with the ubiquitous ``PyObject*``, manual reference-counting, and the -need to remember which API calls return "new" (owned) references or -"borrowed" (raw) references. These constraints are not just -cumbersome but also a major source of errors, especially in the -presence of exceptions. - -Boost.Python provides a class ``object`` which automates reference -counting and provides conversion to Python from C++ objects of -arbitrary type. This significantly reduces the learning effort for -prospective extension module writers. - -Creating an ``object`` from any other type is extremely simple:: - - object s("hello, world"); // s manages a Python string - -``object`` has templated interactions with all other types, with -automatic to-python conversions. It happens so naturally that it's -easily overlooked:: - - object ten_Os = 10 * s[4]; // -> "oooooooooo" - -In the example above, ``4`` and ``10`` are converted to Python objects -before the indexing and multiplication operations are invoked. - -The ``extract`` class template can be used to convert Python objects -to C++ types:: - - double x = extract(o); - -If a conversion in either direction cannot be performed, an -appropriate exception is thrown at runtime. - -The ``object`` type is accompanied by a set of derived types -that mirror the Python built-in types such as ``list``, ``dict``, -``tuple``, etc. as much as possible. This enables convenient -manipulation of these high-level types from C++:: - - dict d; - d["some"] = "thing"; - d["lucky_number"] = 13; - list l = d.keys(); - -This almost looks and works like regular Python code, but it is pure -C++. Of course we can wrap C++ functions which accept or return -``object`` instances. - -.. ===================== - Development history - ===================== - - XXX Outline of development history to illustrate that the - library is mature. XXX - - This can be postponed for the PyConDC paper - -================= - Thinking hybrid -================= - -Because of the practical and mental difficulties of combining -programming languages, it is common to settle a single language at the -outset of any development effort. For many applications, performance -considerations dictate the use of a compiled language for the core -algorithms. Unfortunately, due to the complexity of the static type -system, the price we pay for runtime performance is often a -significant increase in development time. Experience shows that -writing maintainable C++ code usually takes longer and requires *far* -more hard-earned working experience than developing comparable Python -code. Even when developers are comfortable working exclusively in -compiled languages, they often augment their systems by some type of -ad hoc scripting layer for the benefit of their users without ever -availing themselves of the same advantages. - -Boost.Python enables us to *think hybrid*. Python can be used for -rapidly prototyping a new application; its ease of use and the large -pool of standard libraries give us a head start on the way to a -working system. If necessary, the working code can be used to -discover rate-limiting hotspots. To maximize performance these can -be reimplemented in C++, together with the Boost.Python bindings -needed to tie them back into the existing higher-level procedure. - -Of course, this *top-down* approach is less attractive if it is clear -from the start that many algorithms will eventually have to be -implemented in C++. Fortunately Boost.Python also enables us to -pursue a *bottom-up* approach. We have used this approach very -successfully in the development of a toolbox for scientific -applications. The toolbox started out mainly as a library of C++ -classes with Boost.Python bindings, and for a while the growth was -mainly concentrated on the C++ parts. However, as the toolbox is -becoming more complete, more and more newly added functionality can be -implemented in Python. - -.. image:: python_cpp_mix.png - -This figure shows the estimated ratio of newly added C++ and Python -code over time as new algorithms are implemented. We expect this -ratio to level out near 70% Python. Being able to solve new problems -mostly in Python rather than a more difficult statically typed -language is the return on our investment in Boost.Python. The ability -to access all of our code from Python allows a broader group of -developers to use it in the rapid development of new applications. - -============= - Conclusions -============= - -Boost.Python achieves seamless interoperability between two rich and -complimentary language environments. Because it leverages template -metaprogramming to introspect about types and functions, the user -never has to learn a third syntax: the interface definitions are -written in concise and maintainable C++. Also, the wrapping system -doesn't have to parse C++ headers or represent the type system: the -compiler does that work for us. - -Computationally intensive tasks play to the strengths of C++ and are -often impossible to implement efficiently in pure Python, while jobs -like serialization that are trivial in Python can be very difficult in -pure C++. Given the luxury of building a hybrid software system from -the ground up, we can approach design with new confidence and power. - -=========== - Citations -=========== - -.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report, - Vol. 7 No. 5 June 1995, pp. 26-31. - http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html diff --git a/doc/PyConDC_2003/bpl_mods.txt b/doc/PyConDC_2003/bpl_mods.txt deleted file mode 100644 index e243cda9..00000000 --- a/doc/PyConDC_2003/bpl_mods.txt +++ /dev/null @@ -1,908 +0,0 @@ -.. This is a comment. Note how any initial comments are moved by - transforms to after the document title, subtitle, and docinfo. - -.. Need intro and conclusion -.. Exposing classes - .. Constructors - .. Overloading - .. Properties and data members - .. Inheritance - .. Operators and Special Functions - .. Virtual Functions -.. Call Policies - -++++++++++++++++++++++++++++++++++++++++++++++ - Introducing Boost.Python (Extended Abstract) -++++++++++++++++++++++++++++++++++++++++++++++ - - -.. bibliographic fields (which also require a transform): - -:Author: David Abrahams -:Address: 45 Walnut Street - Somerville, MA 02143 -:Contact: dave@boost-consulting.com -:organization: `Boost Consulting`_ -:date: $Date$ -:status: This is a "work in progress" -:version: 1 -:copyright: Copyright David Abrahams 2002. All rights reserved - -:Dedication: - - For my girlfriend, wife, and partner Luann - -:abstract: - - This paper describes the Boost.Python library, a system for - C++/Python interoperability. - -.. meta:: - :keywords: Boost,python,Boost.Python,C++ - :description lang=en: C++/Python interoperability with Boost.Python - -.. contents:: Table of Contents -.. section-numbering:: - - -.. _`Boost Consulting`: http://www.boost-consulting.com - -============== - Introduction -============== - -Python and C++ are in many ways as different as two languages could -be: while C++ is usually compiled to machine-code, Python is -interpreted. Python's dynamic type system is often cited as the -foundation of its flexibility, while in C++ static typing is the -cornerstone of its efficiency. C++ has an intricate and difficult -meta-language to support compile-time polymorphism, while Python is -a uniform language with convenient runtime polymorphism. - -Yet for many programmers, these very differences mean that Python and -C++ complement one another perfectly. Performance bottlenecks in -Python programs can be rewritten in C++ for maximal speed, and -authors of powerful C++ libraries choose Python as a middleware -language for its flexible system integration capabilities. -Furthermore, the surface differences mask some strong similarities: - -* 'C'-family control structures (if, while, for...) - -* Support for object-orientation, functional programming, and generic - programming (these are both *multi-paradigm* programming languages.) - -* Comprehensive operator overloading facilities, recognizing the - importance of syntactic variability for readability and - expressivity. - -* High-level concepts such as collections and iterators. - -* High-level encapsulation facilities (C++: namespaces, Python: modules) - to support the design of re-usable libraries. - -* Exception-handling for effective management of error conditions. - -* C++ idioms in common use, such as handle/body classes and - reference-counted smart pointers mirror Python reference semantics. - -Python provides a rich 'C' API for writers of 'C' extension modules. -Unfortunately, using this API directly for exposing C++ type and -function interfaces to Python is much more tedious than it should be. -This is mainly due to the limitations of the 'C' language. Compared to -C++ and Python, 'C' has only very rudimentary abstraction facilities. -Support for exception-handling is completely missing. One important -undesirable consequence is that 'C' extension module writers are -required to manually manage Python reference counts. Another unpleasant -consequence is a very high degree of repetition of similar code in 'C' -extension modules. Of course highly redundant code does not only cause -frustration for the module writer, but is also very difficult to -maintain. - -The limitations of the 'C' API have lead to the development of a -variety of wrapping systems. SWIG_ is probably the most popular package -for the integration of C/C++ and Python. A more recent development is -the SIP_ package, which is specifically designed for interfacing Python -with the Qt_ graphical user interface library. Both SWIG and SIP -introduce a new specialized language for defining the inter-language -bindings. Of course being able to use a specialized language has -advantages, but having to deal with three different languages (Python, -C/C++ and the interface language) also introduces practical and mental -difficulties. The CXX_ package demonstrates an interesting alternative. -It shows that at least some parts of Python's 'C' API can be wrapped -and presented through a much more user-friendly C++ interface. However, -unlike SWIG and SIP, CXX does not include support for wrapping C++ -classes as new Python types. CXX is also no longer actively developed. - -In some respects Boost.Python combines ideas from SWIG and SIP with -ideas from CXX. Like SWIG and SIP, Boost.Python is a system for -wrapping C++ classes as new Python "built-in" types, and C/C++ -functions as Python functions. Like CXX, Boost.Python presents Python's -'C' API through a C++ interface. Boost.Python goes beyond the scope of -other systems with the unique support for C++ virtual functions that -are overrideable in Python, support for organizing extensions as Python -packages with a central registry for inter-language type conversions, -and a convenient mechanism for tying into Python's serialization engine -(pickle). Importantly, all this is achieved without introducing a new -syntax. Boost.Python leverages the power of C++ meta-programming -techniques to introspect about the C++ type system, and presents a -simple, IDL-like C++ interface for exposing C/C++ code in extension -modules. Boost.Python is a pure C++ library, the inter-language -bindings are defined in pure C++, and other than a C++ compiler only -Python itself is required to get started with Boost.Python. Last but -not least, Boost.Python is an unrestricted open source library. There -are no strings attached even for commercial applications. - -.. _SWIG: http://www.swig.org/ -.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php -.. _Qt: http://www.trolltech.com/ -.. _CXX: http://cxx.sourceforge.net/ - -=========================== - Boost.Python Design Goals -=========================== - -The primary goal of Boost.Python is to allow users to expose C++ -classes and functions to Python using nothing more than a C++ -compiler. In broad strokes, the user experience should be one of -directly manipulating C++ objects from Python. - -However, it's also important not to translate all interfaces *too* -literally: the idioms of each language must be respected. For -example, though C++ and Python both have an iterator concept, they are -expressed very differently. Boost.Python has to be able to bridge the -interface gap. - -It must be possible to insulate Python users from crashes resulting -from trivial misuses of C++ interfaces, such as accessing -already-deleted objects. By the same token the library should -insulate C++ users from low-level Python 'C' API, replacing -error-prone 'C' interfaces like manual reference-count management and -raw ``PyObject`` pointers with more-robust alternatives. - -Support for component-based development is crucial, so that C++ types -exposed in one extension module can be passed to functions exposed in -another without loss of crucial information like C++ inheritance -relationships. - -Finally, all wrapping must be *non-intrusive*, without modifying or -even seeing the original C++ source code. Existing C++ libraries have -to be wrappable by third parties who only have access to header files -and binaries. - -========================== - Hello Boost.Python World -========================== - -And now for a preview of Boost.Python, and how it improves on the raw -facilities offered by Python. Here's a function we might want to -expose:: - - char const* greet(unsigned x) - { - static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; - - if (x > 2) - throw std::range_error("greet: index out of range"); - - return msgs[x]; - } - -To wrap this function in standard C++ using the Python 'C' API, we'd -need something like this:: - - extern "C" // all Python interactions use 'C' linkage and calling convention - { - // Wrapper to handle argument/result conversion and checking - PyObject* greet_wrap(PyObject* args, PyObject * keywords) - { - int x; - if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments - { - char const* result = greet(x); // invoke wrapped function - return PyString_FromString(result); // convert result to Python - } - return 0; // error occurred - } - - // Table of wrapped functions to be exposed by the module - static PyMethodDef methods[] = { - { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" } - , { NULL, NULL, 0, NULL } // sentinel - }; - - // module initialization function - DL_EXPORT init_hello() - { - (void) Py_InitModule("hello", methods); // add the methods to the module - } - } - -Now here's the wrapping code we'd use to expose it with Boost.Python:: - - #include - using namespace boost::python; - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet, "return one of 3 parts of a greeting"); - } - -and here it is in action:: - - >>> import hello - >>> for x in range(3): - ... print hello.greet(x) - ... - hello - Boost.Python - world! - -Aside from the fact that the 'C' API version is much more verbose than -the BPL one, it's worth noting that it doesn't handle a few things -correctly: - -* The original function accepts an unsigned integer, and the Python - 'C' API only gives us a way of extracting signed integers. The - Boost.Python version will raise a Python exception if we try to pass - a negative number to ``hello.greet``, but the other one will proceed - to do whatever the C++ implementation does when converting an - negative integer to unsigned (usually wrapping to some very large - number), and pass the incorrect translation on to the wrapped - function. - -* That brings us to the second problem: if the C++ ``greet()`` - function is called with a number greater than 2, it will throw an - exception. Typically, if a C++ exception propagates across the - boundary with code generated by a 'C' compiler, it will cause a - crash. As you can see in the first version, there's no C++ - scaffolding there to prevent this from happening. Functions wrapped - by Boost.Python automatically include an exception-handling layer - which protects Python users by translating unhandled C++ exceptions - into a corresponding Python exception. - -* A slightly more-subtle limitation is that the argument conversion - used in the Python 'C' API case can only get that integer ``x`` in - *one way*. PyArg_ParseTuple can't convert Python ``long`` objects - (arbitrary-precision integers) which happen to fit in an ``unsigned - int`` but not in a ``signed long``, nor will it ever handle a - wrapped C++ class with a user-defined implicit ``operator unsigned - int()`` conversion. The BPL's dynamic type conversion registry - allows users to add arbitrary conversion methods. - -================== - Library Overview -================== - -This section outlines some of the library's major features. Except as -neccessary to avoid confusion, details of library implementation are -omitted. - -------------------------------------------- - The fundamental type-conversion mechanism -------------------------------------------- - -XXX This needs to be rewritten. - -Every argument of every wrapped function requires some kind of -extraction code to convert it from Python to C++. Likewise, the -function return value has to be converted from C++ to Python. -Appropriate Python exceptions must be raised if the conversion fails. -Argument and return types are part of the function's type, and much of -this tedium can be relieved if the wrapping system can extract that -information through introspection. - -Passing a wrapped C++ derived class instance to a C++ function -accepting a pointer or reference to a base class requires knowledge of -the inheritance relationship and how to translate the address of a base -class into that of a derived class. - ------------------- - Exposing Classes ------------------- - -C++ classes and structs are exposed with a similarly-terse interface. -Given:: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -The following code will expose it in our extension module:: - - #include - BOOST_PYTHON_MODULE(hello) - { - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -Although this code has a certain pythonic familiarity, people -sometimes find the syntax bit confusing because it doesn't look like -most of the C++ code they're used to. All the same, this is just -standard C++. Because of their flexible syntax and operator -overloading, C++ and Python are great for defining domain-specific -(sub)languages -(DSLs), and that's what we've done in BPL. To break it down:: - - class_("World") - -constructs an unnamed object of type ``class_`` and passes -``"World"`` to its constructor. This creates a new-style Python class -called ``World`` in the extension module, and associates it with the -C++ type ``World`` in the BPL type conversion registry. We might have -also written:: - - class_ w("World"); - -but that would've been more verbose, since we'd have to name ``w`` -again to invoke its ``def()`` member function:: - - w.def("greet", &World::greet) - -There's nothing special about the location of the dot for member -access in the original example: C++ allows any amount of whitespace on -either side of a token, and placing the dot at the beginning of each -line allows us to chain as many successive calls to member functions -as we like with a uniform syntax. The other key fact that allows -chaining is that ``class_<>`` member functions all return a reference -to ``*this``. - -So the example is equivalent to:: - - class_ w("World"); - w.def("greet", &World::greet); - w.def("set", &World::set); - -It's occasionally useful to be able to break down the components of a -Boost.Python class wrapper in this way, but the rest of this paper -will tend to stick to the terse syntax. - -For completeness, here's the wrapped class in use: - ->>> import hello ->>> planet = hello.World() ->>> planet.set('howdy') ->>> planet.greet() -'howdy' - -Constructors -============ - -Since our ``World`` class is just a plain ``struct``, it has an -implicit no-argument (nullary) constructor. Boost.Python exposes the -nullary constructor by default, which is why we were able to write: - ->>> planet = hello.World() - -However, well-designed classes in any language may require constructor -arguments in order to establish their invariants. Unlike Python, -where ``__init__`` is just a specially-named method, In C++ -constructors cannot be handled like ordinary member functions. In -particular, we can't take their address: ``&World::World`` is an -error. The library provides a different interface for specifying -constructors. Given:: - - struct World - { - World(std::string msg); // added constructor - ... - -we can modify our wrapping code as follows:: - - class_("World", init()) - ... - -of course, a C++ class may have additional constructors, and we can -expose those as well by passing more instances of ``init<...>`` to -``def()``:: - - class_("World", init()) - .def(init()) - ... - -Boost.Python allows wrapped functions, member functions, and -constructors to be overloaded to mirror C++ overloading. - -Data Members and Properties -=========================== - -Any publicly-accessible data members in a C++ class can be easily -exposed as either ``readonly`` or ``readwrite`` attributes:: - - class_("World", init()) - .def_readonly("msg", &World::msg) - ... - -and can be used directly in Python: - ->>> planet = hello.World('howdy') ->>> planet.msg -'howdy' - -This does *not* result in adding attributes to the ``World`` instance -``__dict__``, which can result in substantial memory savings when -wrapping large data structures. In fact, no instance ``__dict__`` -will be created at all unless attributes are explicitly added from -Python. BPL owes this capability to the new Python 2.2 type system, -in particular the descriptor interface and ``property`` type. - -In C++, publicly-accessible data members are considered a sign of poor -design because they break encapsulation, and style guides usually -dictate the use of "getter" and "setter" functions instead. In -Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, -``property`` mean that attribute access is just one more -well-encapsulated syntactic tool at the programmer's disposal. BPL -bridges this idiomatic gap by making Python ``property`` creation -directly available to users. So if ``msg`` were private, we could -still expose it as attribute in Python as follows:: - - class_("World", init()) - .add_property("msg", &World::greet, &World::set) - ... - -The example above mirrors the familiar usage of properties in Python -2.2+: - ->>> class World(object): -... __init__(self, msg): -... self.__msg = msg -... def greet(self): -... return self.__msg -... def set(self, msg): -... self.__msg = msg -... msg = property(greet, set) - -Operators and Special Functions -=============================== - -The ability to write arithmetic operators for user-defined types that -C++ and Python both allow the definition of has been a major factor in -the popularity of both languages for scientific computing. The -success of packages like NumPy attests to the power of exposing -operators in extension modules. In this example we'll wrap a class -representing a position in a large file:: - - class FilePos { /*...*/ }; - - // Linear offset - FilePos operator+(FilePos, int); - FilePos operator+(int, FilePos); - FilePos operator-(FilePos, int); - - // Distance between two FilePos objects - int operator-(FilePos, FilePos); - - // Offset with assignment - FilePos& operator+=(FilePos&, int); - FilePos& operator-=(FilePos&, int); - - // Comparison - bool operator<(FilePos, FilePos); - -The wrapping code looks like this:: - - class_("FilePos") - .def(self + int()) // __add__ - .def(int() + self) // __radd__ - .def(self - int()) // __sub__ - - .def(self - self) // __sub__ - - .def(self += int()) // __iadd__ - .def(self -= int()) // __isub__ - - .def(self < self); // __lt__ - ; - -The magic is performed using a simplified application of "expression -templates" [VELD1995]_, a technique originally developed by for -optimization of high-performance matrix algebra expressions. The -essence is that instead of performing the computation immediately, -operators are overloaded to construct a type *representing* the -computation. In matrix algebra, dramatic optimizations are often -available when the structure of an entire expression can be taken into -account, rather than processing each operation "greedily". -Boost.Python uses the same technique to build an appropriate Python -callable object based on an expression involving ``self``, which is -then added to the class. - -Inheritance -=========== - -C++ inheritance relationships can be represented to Boost.Python by adding -an optional ``bases<...>`` argument to the ``class_<...>`` template -parameter list as follows:: - - class_ >("Derived") - ... - -This has two effects: - -1. When the ``class_<...>`` is created, Python type objects - corresponding to ``Base1`` and ``Base2`` are looked up in the BPL - registry, and are used as bases for the new Python ``Derived`` type - object [#mi]_, so methods exposed for the Python ``Base1`` and - ``Base2`` types are automatically members of the ``Derived`` type. - Because the registry is global, this works correctly even if - ``Derived`` is exposed in a different module from either of its - bases. - -2. C++ conversions from ``Derived`` to its bases are added to the - Boost.Python registry. Thus wrapped C++ methods expecting (a - pointer or reference to) an object of either base type can be - called with an object wrapping a ``Derived`` instance. Wrapped - member functions of class ``T`` are treated as though they have an - implicit first argument of ``T&``, so these conversions are - neccessary to allow the base class methods to be called for derived - objects. - -Of course it's possible to derive new Python classes from wrapped C++ -class instances. Because Boost.Python uses the new-style class -system, that works very much as for the Python built-in types. There -is one significant detail in which it differs: the built-in types -generally establish their invariants in their ``__new__`` function, so -that derived classes do not need to call ``__init__`` on the base -class before invoking its methods : - ->>> class L(list): -... def __init__(self): -... pass -... ->>> L().reverse() ->>> - -Because C++ object construction is a one-step operation, C++ instance -data cannot be constructed until the arguments are available, in the -``__init__`` function: - ->>> class D(SomeBPLClass): -... def __init__(self): -... pass -... ->>> D().some_bpl_method() -Traceback (most recent call last): - File "", line 1, in ? -TypeError: bad argument type for built-in operation - -This happened because Boost.Python couldn't find instance data of type -``SomeBPLClass`` within the ``D`` instance; ``D``'s ``__init__`` -function masked construction of the base class. It could be corrected -by either removing ``D``'s ``__init__`` function or having it call -``SomeBPLClass.__init__(...)`` explicitly. - -Virtual Functions -================= - -Deriving new types in Python from extension classes is not very -interesting unless they can be used polymorphically from C++. In -other words, Python method implementations should appear to override -the implementation of C++ virtual functions when called *through base -class pointers/references from C++*. Since the only way to alter the -behavior of a virtual function is to override it in a derived class, -the user must build a special derived class to dispatch a polymorphic -class' virtual functions:: - - // - // interface to wrap: - // - class Base - { - public: - virtual int f(std::string x) { return 42; } - virtual ~Base(); - }; - - int calls_f(Base const& b, std::string x) { return b.f(x); } - - // - // Wrapping Code - // - - // Dispatcher class - struct BaseWrap : Base - { - // Store a pointer to the Python object - BaseWrap(PyObject* self_) : self(self_) {} - PyObject* self; - - // Default implementation, for when f is not overridden - int f_default(std::string x) { return this->Base::f(x); } - // Dispatch implementation - int f(std::string x) { return call_method(self, "f", x); } - }; - - ... - def("calls_f", calls_f); - class_("Base") - .def("f", &Base::f, &BaseWrap::f_default) - ; - -Now here's some Python code which demonstrates: - ->>> class Derived(Base): -... def f(self, s): -... return len(s) -... ->>> calls_f(Base(), 'foo') -42 ->>> calls_f(Derived(), 'forty-two') -9 - -Things to notice about the dispatcher class: - -* The key element which allows overriding in Python is the - ``call_method`` invocation, which uses the same global type - conversion registry as the C++ function wrapping does to convert its - arguments from C++ to Python and its return type from Python to C++. - -* Any constructor signatures you wish to wrap must be replicated with - an initial ``PyObject*`` argument - -* The dispatcher must store this argument so that it can be used to - invoke ``call_method`` - -* The ``f_default`` member function is needed when the function being - exposed is not pure virtual; there's no other way ``Base::f`` can be - called on an object of type ``BaseWrap``, since it overrides ``f``. - -Admittedly, this formula is tedious to repeat, especially on a project -with many polymorphic classes; that it is neccessary reflects -limitations in C++'s compile-time reflection capabilities. Several -efforts are underway to write front-ends for Boost.Python which can -generate these dispatchers (and other wrapping code) automatically. -If these are successful it will mark a move away from wrapping -everything directly in pure C++ for many of our users. - ---------------- - Serialization ---------------- - -*Serialization* is the process of converting objects in memory to a -form that can be stored on disk or sent over a network connection. The -serialized object (most often a plain string) can be retrieved and -converted back to the original object. A good serialization system will -automatically convert entire object hierarchies. Python's standard -``pickle`` module is such a system. It leverages the language's strong -runtime introspection facilities for serializing practically arbitrary -user-defined objects. With a few simple and unintrusive provisions this -powerful machinery can be extended to also work for wrapped C++ objects. -Here is an example:: - - #include - - struct World - { - World(std::string a_msg) : msg(a_msg) {} - std::string greet() const { return msg; } - std::string msg; - }; - - #include - using namespace boost::python; - - struct World_picklers : pickle_suite - { - static tuple - getinitargs(World const& w) { return make_tuple(w.greet()); } - }; - - BOOST_PYTHON_MODULE(hello) - { - class_("World", init()) - .def("greet", &World::greet) - .def_pickle(World_picklers()) - ; - } - -Now let's create a ``World`` object and put it to rest on disk:: - - >>> import hello - >>> import pickle - >>> a_world = hello.World("howdy") - >>> pickle.dump(a_world, open("my_world", "w")) - -In a potentially *different script* on a potentially *different -computer* with a potentially *different operating system*:: - - >>> import pickle - >>> resurrected_world = pickle.load(open("my_world", "r")) - >>> resurrected_world.greet() - 'howdy' - -Of course the ``cPickle`` module can also be used for faster -processing. - -Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol -defined in the standard Python documentation. There is a one-to-one -correspondence between the standard pickling methods (``__getinitargs__``, -``__getstate__``, ``__setstate__``) and the functions defined by the -user in the class derived from ``pickle_suite`` (``getinitargs``, -``getstate``, ``setstate``). The ``class_::def_pickle()`` member function -is used to establish the Python bindings for all user-defined functions -simultaneously. Correct signatures for these functions are enforced at -compile time. Non-sensical combinations of the three pickle functions -are also rejected at compile time. These measures are designed to -help the user in avoiding obvious errors. - -Enabling serialization of more complex C++ objects requires a little -more work than is shown in the example above. Fortunately the -``object`` interface (see next section) greatly helps in keeping the -code manageable. - ------------------- - Object interface ------------------- - -Experienced extension module authors will be familiar with the 'C' view -of Python objects, the ubiquitous ``PyObject*``. Most if not all Python -'C' API functions involve ``PyObject*`` as arguments or return type. A -major complication is the raw reference counting interface presented to -the 'C' programmer. E.g. some API functions return *new references* and -others return *borrowed references*. It is up to the extension module -writer to properly increment and decrement reference counts. This -quickly becomes cumbersome and error prone, especially if there are -multiple execution paths. - -Boost.Python provides a type ``object`` which is essentially a high -level wrapper around ``PyObject*``. ``object`` automates reference -counting as much as possible. It also provides the facilities for -converting arbitrary C++ types to Python objects and vice versa. -This significantly reduces the learning effort for prospective -extension module writers. - -Creating an ``object`` from any other type is extremely simple:: - - object o(3); - -``object`` has templated interactions with all other types, with -automatic to-python conversions. It happens so naturally that it's -easily overlooked. - -The ``extract`` class template can be used to convert Python objects -to C++ types:: - - double x = extract(o); - -All registered user-defined conversions are automatically accessible -through the ``object`` interface. With reference to the ``World`` class -defined in previous examples:: - - object as_python_object(World("howdy")); - World back_as_c_plus_plus_object = extract(as_python_object); - -If a C++ type cannot be converted to a Python object an appropriate -exception is thrown at runtime. Similarly, an appropriate exception is -thrown if a C++ type cannot be extracted from a Python object. -``extract`` provides facilities for avoiding exceptions if this is -desired. - -The ``object::attr()`` member function is available for accessing -and manipulating attributes of Python objects. For example:: - - object planet(World()); - planet.attr("set")("howdy"); - -``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is -converted to a Python string object which is then passed as an argument -to the ``set`` method. - -The ``object`` type is accompanied by a set of derived types -that mirror the Python built-in types such as ``list``, ``dict``, -``tuple``, etc. as much as possible. This enables convenient -manipulation of these high-level types from C++:: - - dict d; - d["some"] = "thing"; - d["lucky_number"] = 13; - list l = d.keys(); - -This almost looks and works like regular Python code, but it is pure C++. - -================= - Thinking hybrid -================= - -For many applications runtime performance considerations are very -important. This is particularly true for most scientific applications. -Often the performance considerations dictate the use of a compiled -language for the core algorithms. Traditionally the decision to use a -particular programming language is an exclusive one. Because of the -practical and mental difficulties of combining different languages many -systems are written in just one language. This is quite unfortunate -because the price payed for runtime performance is typically a -significant overhead due to static typing. For example, our experience -shows that developing maintainable C++ code is typically much more -time-consuming and requires much more hard-earned working experience -than developing useful Python code. A related observation is that many -compiled packages are augmented by some type of rudimentary scripting -layer. These ad hoc solutions clearly show that many times a compiled -language alone does not get the job done. On the other hand it is also -clear that a pure Python implementation is too slow for numerically -intensive production code. - -Boost.Python enables us to *think hybrid* when developing new -applications. Python can be used for rapidly prototyping a -new application. Python's ease of use and the large pool of standard -libraries give us a head start on the way to a first working system. If -necessary, the working procedure can be used to discover the -rate-limiting algorithms. To maximize performance these can be -reimplemented in C++, together with the Boost.Python bindings needed to -tie them back into the existing higher-level procedure. - -Of course, this *top-down* approach is less attractive if it is clear -from the start that many algorithms will eventually have to be -implemented in a compiled language. Fortunately Boost.Python also -enables us to pursue a *bottom-up* approach. We have used this approach -very successfully in the development of a toolbox for scientific -applications (scitbx) that we will describe elsewhere. The toolbox -started out mainly as a library of C++ classes with Boost.Python -bindings, and for a while the growth was mainly concentrated on the C++ -parts. However, as the toolbox is becoming more complete, more and more -newly added functionality can be implemented in Python. We expect this -trend to continue, as illustrated qualitatively in this figure: - -.. image:: python_cpp_mix.png - -This figure shows the ratio of newly added C++ and Python code over -time as new algorithms are implemented. We expect this ratio to level -out near 70% Python. The increasing ability to solve new problems -mostly with the easy-to-use Python language rather than a necessarily -more arcane statically typed language is the return on the investment -of learning how to use Boost.Python. The ability to solve some problems -entirely using only Python will enable a larger group of people to -participate in the rapid development of new applications. - -============= - Conclusions -============= - -The examples in this paper illustrate that Boost.Python enables -seamless interoperability between C++ and Python. Importantly, this is -achieved without introducing a third syntax: the Python/C++ interface -definitions are written in pure C++. This avoids any problems with -parsing the C++ code to be interfaced to Python, yet the interface -definitions are concise and maintainable. Freed from most of the -development-time penalties of crossing a language boundary, software -designers can take full advantage of two rich and complimentary -language environments. In practice it turns out that some things are -very difficult to do with pure Python/C (e.g. an efficient array -library with an intuitive interface in the compiled language) and -others are very difficult to do with pure C++ (e.g. serialization). -If one has the luxury of being able to design a software system as a -hybrid system from the ground up there are many new ways of avoiding -road blocks in one language or the other. - -.. I'm not ready to give up on all of this quite yet - -.. Perhaps one day we'll have a language with the simplicity and - expressive power of Python and the compile-time muscle of C++. Being - able to take advantage of all of these facilities without paying the - mental and development-time penalties of crossing a language barrier - would bring enormous benefits. Until then, interoperability tools - like Boost.Python can help lower the barrier and make the benefits of - both languages more accessible to both communities. - -=========== - Footnotes -=========== - -.. [#mi] For hard-core new-style class/extension module writers it is - worth noting that the normal requirement that all extension classes - with data form a layout-compatible single-inheritance chain is - lifted for Boost.Python extension classes. Clearly, either - ``Base1`` or ``Base2`` has to occupy a different offset in the - ``Derived`` class instance. This is possible because the wrapped - part of BPL extension class instances is never assumed to have a - fixed offset within the wrapper. - -=========== - Citations -=========== - -.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report, - Vol. 7 No. 5 June 1995, pp. 26-31. - http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html diff --git a/doc/PyConDC_2003/default.css b/doc/PyConDC_2003/default.css deleted file mode 100644 index 2e1fddb9..00000000 --- a/doc/PyConDC_2003/default.css +++ /dev/null @@ -1,188 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:date: $Date$ -:version: $Revision$ -:copyright: This stylesheet has been placed in the public domain. - -Default cascading style sheet for the HTML output of Docutils. -*/ - -.first { - margin-top: 0 } - -.last { - margin-bottom: 0 } - -a.toc-backref { - text-decoration: none ; - color: black } - -dd { - margin-bottom: 0.5em } - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { - margin: 2em ; - border: medium outset ; - padding: 1em } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif } - -div.hint p.admonition-title, div.important p.admonition-title, -div.note p.admonition-title, div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif } - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - font-size: smaller } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1.title { - text-align: center } - -h2.subtitle { - text-align: center } - -hr { - width: 75% } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.label { - white-space: nowrap } - -p.topic-title { - font-weight: bold } - -pre.address { - margin-bottom: 0 ; - margin-top: 0 ; - font-family: serif ; - font-size: 100% } - -pre.line-block { - font-family: serif ; - font-size: 100% } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #eeeeee } - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.interpreted { - font-family: sans-serif } - -span.option-argument { - font-style: italic } - -span.pre { - white-space: pre } - -span.problematic { - color: red } - -table { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.citation { - border-left: solid thin gray ; - padding-left: 0.5ex } - -table.docinfo { - margin: 2em 4em } - -table.footnote { - border-left: solid thin black ; - padding-left: 0.5ex } - -td, th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: top } - -th.docinfo-name, th.field-name { - font-weight: bold ; - text-align: left ; - white-space: nowrap } - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - font-size: 100% } - -tt { - background-color: #eeeeee } - -ul.auto-toc { - list-style-type: none } diff --git a/doc/PyConDC_2003/python_cpp_mix.png b/doc/PyConDC_2003/python_cpp_mix.png deleted file mode 100755 index fd74cbb2247835aa8b49e91642f29713e366195b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6293 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 Y!@fNJ(%=4NW}qnoPgg&ebxsLQ00Quv$N&HU diff --git a/doc/boost.css b/doc/boost.css deleted file mode 100644 index cf5c8a97..00000000 --- a/doc/boost.css +++ /dev/null @@ -1,59 +0,0 @@ -H1 -{ - FONT-SIZE: 200% - COLOR: #00007f -} -H2 -{ - FONT-SIZE: 150%; -} -H3 -{ - FONT-SIZE: 125%; -} -H4 -{ - FONT-SIZE: 108%; -} -BODY -{ - FONT-SIZE: 100%; - BACKGROUND-COLOR: #ffffff -} -PRE -{ - MARGIN-LEFT: 2pc; - FONT-SIZE: 80%; - BACKGROUND-COLOR: #dfffff -} -CODE -{ - FONT-SIZE: 95%; - white-space: pre -} -.index -{ - TEXT-ALIGN: left -} -.page-index -{ - TEXT-ALIGN: left -} -.definition -{ - TEXT-ALIGN: left -} -.footnote -{ - FONT-SIZE: 66%; - VERTICAL-ALIGN: super; - TEXT-DECORATION: none -} -.function-semantics -{ - CLEAR: left -} -.metafunction-semantics -{ - CLEAR: left -} diff --git a/doc/building.html b/doc/building.html deleted file mode 100644 index 2a65a6db..00000000 --- a/doc/building.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - - - - Boost.Python - Building and Testing - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Building and Testing

-
-
- -

Contents

- -
-
Requirements
- -
Building Boost.Python
- -
-
-
Configuration
- -
Results
- -
Notes for Cygwin GCC Users
- -
Testing
-
-
- -
Building your Extension Module
- -
-
-
The Easy Way
- -
Building your module outside the Boost - project tree
-
-
- -
Build Variants
- -
Building Using the Microsoft Visual Studio - IDE
-
-
- -

Requirements

- Boost.Python version 2 requires Python 2.2 or newer. An unsupported archive of - Boost.Python version 1, which works with versions of Python since 1.5.2, - is available here. - -

Building Boost.Python

- -

Normally, Boost.Python extension modules must be linked with the - boost_python shared library. In special circumstances you - may want to link to a static version of the boost_python - library, but if multiple Boost.Pythone extension modules are used - together, it will prevent sharing of types across extension modules, and - consume extra code space. To build boost_python, use Boost.Build in the usual way - from the libs/python/build subdirectory of your boost - installation (if you have already built boost from the top level this may - have no effect, since the work is already done).

- -

Configuration

- You may need to configure the following variables to point Boost.Build at - your Python installation: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variable NameSemanticsDefaultNotes
PYTHON_ROOTThe root directory of your Python installationWindows: c:/tools/python - Unix: /usr/localOn Unix, this is the --with-prefix= directory used - to configure Python
PYTHON_VERSIONThe The 2-part python Major.Minor version number2.2Be sure not to include a third number, e.g. not - "2.2.1", even if that's the version you have.
PYTHON_INCLUDESpath to Python #include directoriesAutoconfigured from PYTHON_ROOT
PYTHON_LIB_PATHpath to Python library object.Autoconfigured from PYTHON_ROOT
CYGWIN_PYTHON_[DEBUG_]VERSIONThe version of python being used under Cygwin. $(PYTHON_VERSION) - - Use only when building with Cygwin GCC. This and the following - settings are useful when building with multiple toolsets on - Windows, since Cygwin GCC requires a different build of - Python.
CYGWIN_PYTHON_[DEBUG_]ROOTunix-style path containing the include/ - directory containing - python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h. $(PYTHON_ROOT) - - Use only when building with Cygwin GCC.
CYGWIN_PYTHON_[DEBUG_]LIB_PATHpath containing the user's Cygwin Python import lib - libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.aAutoconfigured from CYGWIN_PYTHON_ROOTUse only when building with Cygwin GCC.
CYGWIN_PYTHON_[DEBUG_]DLL_PATHpath containing the user's Cygwin Python dll - (libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll)/binUse only when building with Cygwin GCC.
- -

Notes for Cygwin GCC Users

- -

If you are using Cygwin GCC to build extension modules, you must use a - Cygwin build of Python. The regular Win32 Python installation that you - can download from python.org will not - work with your compiler because the dynamic linking conventions are - different (you can use MinGW GCC if - you want to build extension modules which are compatible with a stock - Win32 Python). The Cygwin installer may be able to install an appropriate - version of Python, or you can follow the traditional Unix installation - process to build Python from source.

- -

The special build configuration variables listed above as "Cygwin - only" make it possible to use a regular Win32 build of bjam to build and - test Boost.Python and Boost.Python extensions using Cygwin GCC and - targeting a Cygwin build of Python.

- -

Results

- -

The build process will create a - libs/python/build/bin-stage subdirectory of the boost root - (or of $(ALL_LOCATE_TARGET), if you have set that variable), - containing the built libraries. The libraries are actually built to - unique directories for each toolset and variant elsewhere in the - filesystem, and copied to the bin-stage directory as a - convenience, so if you build with multiple toolsets at once, the product - of later toolsets will overwrite that of earlier toolsets in - bin-stage.

- -

Testing

- -

To build and test Boost.Python, start from the - libs/python/test directory and invoke

- -
-
-bjam -sTOOLS=toolset test
-
-
- This will update all of the Boost.Python v1 test and example targets. The - tests are relatively quiet by default. To get more-verbose output, you - might try - -
-
-bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS=-v test
-
-
- which will print each test's Python code with the expected output as it - passes. - -

Building your Extension Module

- Though there are other approaches, the best way to build an extension - module using Boost.Python is with Boost.Build. If you have to use another - build system, you should use Boost.Build at least once with the - "-n" option so you can see the command-lines it uses, - and replicate them. You are likely to run into compilation or linking - problems otherwise. - -

The Easy Way

- Until Boost.Build v2 is released, cross-project build dependencies are - not supported, so it works most smoothly if you add a new subproject to - your boost installation. The libs/python/example - subdirectory of your boost installation contains a minimal example (along - with many extra sources). To copy the example subproject: - -
    -
  1. Create a new subdirectory in, libs/python, say - libs/python/my_project.
  2. - -
  3. Copy libs/python/example/Jamfile to your new - directory.
  4. - -
  5. Edit the Jamfile as appropriate for your project. You'll want to - change the "subproject" rule invocation at the top, and - the names of some of the source files and/or targets.
  6. -
- The instructions above for testing Boost.Python - apply equally to your new extension modules in this subproject. - -

Building your module outside the Boost project - tree

- If you can't (or don't wish to) modify your boost installation, the - alternative is to create your own Boost.Build project. A similar example - you can use as a starting point is available in this archive. You'll need to edit the - Jamfile and Jamrules files, depending on the relative location of your - Boost installation and the new project. Note that automatic testing of - extension modules is not available in this configuration. - -

Build Variants

- Three variant - configurations of all python-related targets are supported, and can be - selected by setting the BUILD - variable: - -
    -
  • release (optimization, -DNDEBUG)
  • - -
  • debug (no optimization -D_DEBUG)
  • - -
  • debug-python (no optimization, -D_DEBUG - -DBOOST_DEBUG_PYTHON)
  • -
- -

The first two variants of the boost_python library are - built by default, and are compatible with the default Python - distribution. The debug-python variant corresponds to a - specially-built debugging version of Python. On Unix platforms, this - python is built by adding --with-pydebug when configuring - the Python build. On Windows, the debugging version of Python is - generated by the "Win32 Debug" target of the PCBuild.dsw - Visual C++ 6.0 project in the PCBuild subdirectory of your - Python distribution. Extension modules built with Python debugging - enabled are not link-compatible with a non-debug build of Python. - Since few people actually have a debug build of Python (it doesn't come - with the standard distribution), the normal debug variant - builds modules which are compatible with ordinary Python.

- -

On many windows compilers, when extension modules are built with - -D_DEBUG, Python defaults to force linking with a special - debugging version of the Python DLL. Since this debug DLL isn't supplied - with the default Python installation for Windows, Boost.Python uses - boost/python/detail/wrap_python.hpp - to temporarily undefine _DEBUG when Python.h is - #included - unless BOOST_DEBUG_PYTHON is - defined.

- -

If you want the extra runtime checks available with the debugging - version of the library, #define BOOST_DEBUG_PYTHON to re-enable - python debuggin, and link with the debug-python variant of - boost_python.

- -

If you do not #define BOOST_DEBUG_PYTHON, be sure that any - source files in your extension module #include <boost/python/detail/wrap_python.hpp> - instead of the usual Python.h, or you will have link - incompatibilities.
-

- -

Building Using the Microsoft Visual Studio - IDE

- -

For the those of you who feel more comfortable in the IDE world, a - workspace and project file have been included in the libs/python/build/VisualStudio subdirectory. - It builds release and debug versions of the Boost.Python libraries and - places them and the same directory as Jamfile build does, though the - intermediate object files are placed in a different directory. The files - have been created using Microsoft Visual C++ version 6, but they should - work for later versions as well. You will need to tell the IDE where to - find the Python Include/ and Libs/ directories. - Under Tools>Options>Directories, add an entry for the Python - include dir (i.e. c:/Python22/Include), and one for the Lib - (i.e. c:/Python/Libs. Make sure it is Libs with - an "s" and not just Lib).

- -

Using the IDE for you own projects

- -

Building your own projects using the IDE is slightly more complicated. - Firstly, you need to make sure that the project you create as the right - kind. It should be a "Win32 Dynamic-Link Library". The default one that - Visual Studio 6 creates needs some modifications: turn on RTTI, and - change the debug and release builds to use the respective debug and - release Multithreaded DLL versions. You should probably turn off - incremental linking too -- I believe it a bit flaky. If you do this, then - change the "Debug Info" to "Program Database" to get rid of the Edit and - Continue warning.

- -

You'll need to add the Boost root directory under - Tools>Options>Directories to get your code compiling. To - make it link, add the above boost_python.dsp file to your - workspace, and make your project depend upon it (under - Project>Dependencies). You should be able to build now.

- -

Lastly, go to the Project Settings>Debug Page and add the - Python.exe as the executable for the project. Set a startup - directory, and make sure that your current project's output dll, the - boost_python.dll and the python22.dll are on - the current PATH. If you have a python script that tests - your dll, then add it in the "Program Arguments". Now, if all went well, - you should be able to hit the Run (F5) button, and debug your code.

- -
- The Visual Studio project files are graciously contributed and - maintained by Brett - Calcott. -
-
- -

© Copyright David Abrahams 2002. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as is'' without - express or implied warranty, and with no claim as to its suitability for - any purpose.

- -

Updated: 29 December, 2002 (David Abrahams)

- - - diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 6e585a44..00000000 --- a/doc/index.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - Boost.Python - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Index

-
-
- -

Synopsis

- Welcome to version 2 of Boost.Python, a C++ library which enables - seamless interoperability between C++ and the Python programming language. The new version - has been rewritten from the ground up, with a more convenient and - flexible interface, and many new capabilities, including support for: - -
    -
  • References and Pointers
  • - -
  • Globally Registered Type Coercions
  • - -
  • Automatic Cross-Module Type Conversions
  • - -
  • Efficient Function Overloading
  • - -
  • C++ to Python Exception Translation
  • - -
  • Default Arguments
  • - -
  • Keyword Arguments
  • - -
  • Manipulating Python objects in C++
  • - -
  • Exporting C++ Iterators as Python Iterators
  • - -
  • Documentation Strings
  • -
- The development of these features was funded in part by grants to Boost Consulting from the Lawrence Livermore National Laboratories - and by the Computational Crystallography - Initiative at Lawrence Berkeley National Laboratories. -
- -

Contents

- -
-
Tutorial Introduction
- -
Building and Testing
- -
Reference Manual
- -
Configuration Information
- -
Known Working Platforms and - Compilers
- -
Definitions
- -
Projects using Boost.Python
- -
Support Resources
- -
Frequently Asked Questions (FAQs)
- -
Pyste (Boost.Python code generator)
- -
News/Change Log
- -
LLNL Progress Reports
- -
Acknowledgments
-
-
- -

Revised - - 17 November, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/new-conversions.html b/doc/new-conversions.html deleted file mode 100644 index a5fe0c73..00000000 --- a/doc/new-conversions.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - -A New Type Conversion Mechanism for Boost.Python - - - - -

- -

A New Type Conversion Mechanism for Boost.Python

- -

By David Abrahams. - -

Introduction

- -This document describes a redesign of the mechanism for automatically -converting objects between C++ and Python. The current implementation -uses two functions for any type T: - -
-U from_python(PyObject*, type<T>);
-void to_python(V);
-
- -where U is convertible to T and T is convertible to V. These functions -are at the heart of C++/Python interoperability in Boost.Python, so -why would we want to change them? There are many reasons: - -

Bugs

-

Firstly, the current mechanism relies on a common C++ compiler -bug. This is not just embarrassing: as compilers get to be more -conformant, the library stops working. The issue, in detail, is the -use of inline friend functions in templates to generate -conversions. It is a very powerful, and legal technique as long as -it's used correctly: - -

-template <class Derived>
-struct add_some_functions
-{
-     friend return-type some_function1(..., Derived cv-*-&-opt, ...);
-     friend return-type some_function2(..., Derived cv-*-&-opt, ...);
-};
-
-template <class T>
-struct some_template : add_some_functions<some_template<T> >
-{
-};
-
- -The add_some_functions template generates free functions -which operate on Derived, or on related types. Strictly -speaking the related types are not just cv-qualified Derived -values, pointers and/or references. Section 3.4.2 in the standard -describes exactly which types you must use as parameters to these -functions if you want the functions to be found -(there is also a less-technical description in section 11.5.1 of -C++PL3 [1]). Suffice it to say that -with the current design, the from_python and -to_python functions are not supposed to be callable under any -conditions! - -

Compilation and Linking Time

- -The conversion functions generated for each wrapped class using the -above technique are not function templates, but regular functions. The -upshot is that they must all be generated regardless of whether -they are actually used. Generating all of those functions can slow -down module compilation, and resolving the references can slow down -linking. - -

Efficiency

- -The conversion functions are primarily used in (member) function -wrappers to convert the arguments and return values. Being functions, -converters have no interface which allows us to ask "will the -conversion succeed?" without calling the function. Since the -return value of the function must be the object to be passed as an -argument, Boost.Python currently uses C++ exception-handling to detect -an unsuccessful conversion. It's not a particularly good use of -exception-handling, since the failure is not handled very far from -where it occurred. More importantly, it means that C++ exceptions are -thrown during overload resolution as we seek an overload that matches -the arguments passed. Depending on the implementation, this approach -can result in significant slowdowns. - -

It is also unclear that the current library generates a minimal -amount of code for any type conversion. Many of the conversion -functions are nontrivial, and partly because of compiler limitations, -they are declared inline. Also, we could have done a better -job separating the type-specific conversion code from the code which -is type-independent. - -

Cross-module Support

- -The current strategy requires every module to contain the definition -of conversions it uses. In general, a new module can never supply -conversion code which is used by another module. Ralf Grosse-Kunstleve -designed a clever system which imports conversions directly from one -library into another using some explicit declarations, but it has some -disadvantages also: - -
    -
  1. The system Ullrich Koethe designed for implicit conversion between -wrapped classes related through inheritance does not currently work if -the classes are defined in separate modules. - -
  2. The writer of the importing module is required to know the name of -the module supplying the imported conversions. - -
  3. There can be only one way to extract any given C++ type from a -Python object in a given module. -
- -The first item might be addressed by moving Boost.Python into a shared -library, but the other two cannot. Ralf turned the limitation in item -two into a feature: the required module is loaded implicitly when a -conversion it defines is invoked. We will probably want to provide -that functionality anyway, but it's not clear that we should require -the declaration of all such conversions. The final item is a more -serious limitation. If, for example, new numeric types are defined in -separate modules, and these types can all be converted to -doubles, we have to choose just one conversion method. - -

Ease-of-use

- -One persistent source of confusion for users of Boost.Python has been -the fact that conversions for a class are not be visible at -compile-time until the declaration of that class has been seen. When -the user tries to expose a (member) function operating on or returning -an instance of the class in question, compilation fails...even though -the user goes on to expose the class in the same translation unit! - -

-The new system lifts all compile-time checks for the existence of -particular type conversions and replaces them with runtime checks, in -true Pythonic style. While this might seem cavalier, the compile-time -checks are actually not much use in the current system if many classes -are wrapped in separate modules, since the checks are based only on -the user's declaration that the conversions exist. - -

The New Design

- -

Motivation

- -The new design was heavily influenced by a desire to generate as -little code as possible in extension modules. Some of Boost.Python's -clients are enormous projects where link time is proportional to the -amount of object code, and there are many Python extension modules. As -such, we try to keep type-specific conversion code out of modules -other than the one the converters are defined in, and rely as much as -possible on centralized control through a shared library. - -

The Basics

- -The library contains a registry which maps runtime type -identifiers (actually an extension of std::type_info which -preserves references and constness) to entries containing type -converters. An entry can contain only one converter from C++ to Python -(wrapper), but many converters from Python to C++ -(unwrappers). What should happen if -multiple modules try to register wrappers for the same type?. Wrappers -and unwrappers are known as body objects, and are accessed -by the user and the library (in its function-wrapping code) through -corresponding handle (wrap<T> and -unwrap<T>) objects. The handle objects are -extremely lightweight, and delegate all of their operations to -the corresponding body. - -

-When a handle object is constructed, it accesses the -registry to find a corresponding body that can convert the -handle's constructor argument. Actually the registry record for any -type -Tused in a module is looked up only once and stored in a -static registration<T> object for efficiency. For -example, if the handle is an unwrap<Foo&> object, -the entry for Foo& is looked up in the -registry, and each unwrapper it contains is queried -to determine if it can convert the -PyObject* with which the unwrap was constructed. If -a body object which can perform the conversion is found, a pointer to -it is stored in the handle. A body object may at any point store -additional data in the handle to speed up the conversion process. - -

-Now that the handle has been constructed, the user can ask it whether -the conversion can be performed. All handles can be tested as though -they were convertible to bool; a true value -indicates success. If the user forges ahead and tries to do the -conversion without checking when no conversion is possible, an -exception will be thrown as usual. The conversion itself is performed -by the body object. - -

Handling complex conversions

- -

Some conversions may require a dynamic allocation. For example, -when a Python tuple is converted to a std::vector<double> -const&, we need some storage into which to construct the -vector so that a reference to it can be formed. Furthermore, multiple -conversions of the same type may need to be "active" -simultaneously, so we can't keep a single copy of the storage -anywhere. We could keep the storage in the body object, and -have the body clone itself in case the storage is used, but in that -case the storage in the body which lives in the registry is never -used. If the storage was actually an object of the target type (the -safest way in C++), we'd have to find a way to construct one for the -body in the registry, since it may not have a default constructor. - -

-The most obvious way out of this quagmire is to allocate the object using a -new-expression, and store a pointer to it in the handle. Since -the body object knows everything about the data it needs to -allocate (if any), it is also given responsibility for destroying that -data. When the handle is destroyed it asks the body -object to tear down any data it may have stored there. In many ways, -you can think of the body as a "dynamically-determined -vtable" for the handle. - -

Eliminating Redundancy

- -If you look at the current Boost.Python code, you'll see that there -are an enormous number of conversion functions generated for each -wrapped class. For a given class T, functions are generated -to extract the following types from_python: - -
-T*
-T const*
-T const* const&
-T* const&
-T&
-T const&
-T
-std::auto_ptr<T>&
-std::auto_ptr<T>
-std::auto_ptr<T> const&
-boost::shared_ptr<T>&
-boost::shared_ptr<T>
-boost::shared_ptr<T> const&
-
- -Most of these are implemented in terms of just a few conversions, and -if you're lucky, they will be inlined and cause no extra -overhead. In the new system, however, a significant amount of data -will be associated with each type that needs to be converted. We -certainly don't want to register a separate unwrapper object for all -of the above types. - -

Fortunately, much of the redundancy can be eliminated. For example, -if we generate an unwrapper for T&, we don't need an -unwrapper for T const& or T. Accordingly, the user's -request to wrap/unwrap a given type is translated at compile-time into -a request which helps to eliminate redundancy. The rules used to -unwrap a type are: - -

    -
  1. Treat built-in types specially: when unwrapping a value or - constant reference to one of these, use a value for the target - type. It will bind to a const reference if neccessary, and more - importantly, avoids having to dynamically allocate room for - an lvalue of types which can be cheaply copied. -
  2. - Reduce everything else to a reference to an un-cv-qualified type - where possible. Since cv-qualification is lost on Python - anyway, there's no point in trying to convert to a - const&. What about conversions - to values like the tuple->vector example above? It seems to me - that we don't want to make a vector<double>& - (non-const) converter available for that case. We may need to - rethink this slightly. -
- -

To handle the problem described above in item 2, we modify the -procedure slightly. To unwrap any non-scalar T, we seek an -unwrapper for add_reference<T>::type. Unwrappers for -T const& always return T&, and are -registered under both T & and -T const&. - -

For compilers not supporting partial specialization, unwrappers for -T const& must return T const& -(since constness can't be stripped), but a separate unwrapper object -need to be registered for T & and -T const& anyway, for the same reasons. - -We may want to make it possible to compile as -though partial specialization were unavailable even on compilers where -it is available, in case modules could be compiled by different -compilers with compatible ABIs (e.g. Intel C++ and MSVC6). - -

Efficient Argument Conversion

- -Since type conversions are primarily used in function wrappers, an -optimization is provided for the case where a group of conversions are -used together. Each handle class has a corresponding -"_more" class which does the same job, but has a -trivial destructor. Instead of asking each "_more" -handle to destroy its own body, it is linked into an endogenous list -managed by the first (ordinary) handle. The wrap and -unwrap destructors are responsible for traversing that list -and asking each body class to tear down its -handle. This mechanism is also used to determine if all of -the argument/return-value conversions can succeed with a single -function call in the function wrapping code. We -might need to handle return values in a separate step for Python -callbacks, since the availablility of a conversion won't be known -until the result object is retrieved. - -
-
-

References

- -

[1]B. Stroustrup, The C++ Programming Language -Special Edition Addison-Wesley, ISBN 0-201-70073-5. - -


-

Revised - 13 November, 2002 -

-

© Copyright David Abrahams, 2001

- - - - diff --git a/doc/new-conversions.txt b/doc/new-conversions.txt deleted file mode 100644 index 1540e199..00000000 --- a/doc/new-conversions.txt +++ /dev/null @@ -1,111 +0,0 @@ -This hierarchy contains converter handle classes. - - - +-------------+ - | noncopyable | - +-------------+ - ^ - | A common base class used so that - +--------+--------+ conversions can be linked into a - | conversion_base | chain for efficient argument - +-----------------+ conversion - ^ - | - +---------+-----------+ - | | -+-----------+----+ +------+-------+ only used for -| unwrap_more | | wrap_more | chaining, and don't manage any -+----------------+ +--------------+ resources. - ^ ^ - | | - +-----+-----+ +-------+-+ These converters are what users - | unwrap | | wrap | actually touch, but they do so - +-----------+ +---------+ through a type generator which - minimizes the number of converters - that must be generated, so they - - -Each unwrap, unwrap_more, wrap, wrap_more converter holds -a reference to an appropriate converter object - -This hierarchy contains converter body classes - - Exposes use/release which - are needed in case the converter - +-----------+ in the registry needs to be - | converter | cloned. That occurs when a - +-----------+ unwrap target type is not - ^ contained within the Python object. - | - +------------------+-----+ - | | - +--------+-------+ Exposes | - | unwrapper_base | convertible() | - +----------------+ | - ^ | - | | - +--------+----+ +-----+-----+ - | unwrapper| | wrapper| - +-------------+ +-----------+ - Exposes T convert(PyObject*) Exposes PyObject* convert(T) - - -unwrap: - - constructed with a PyObject*, whose reference count is - incremented. - - find the registry entry for the target type - - look in the collection of converters for one which claims to be - able to convert the PyObject to the target type. - - stick a pointer to the unwrapper in the unwrap object - - when unwrap is queried for convertibility, it checks to see - if it has a pointer to an unwrapper. - - on conversion, the unwrapper is asked to allocate an - implementation if the unwrap object isn't already holding - one. The unwrap object "takes ownership" of the unwrapper's - implementation. No memory allocation will actually take place - unless this is a value conversion. - - on destruction, the unwrapper is asked to free any implementation - held by the unwrap object. No memory deallocation actually - takes place unless this is a value conversion - - on destruction, the reference count on the held PyObject is - decremented. - - We need to make sure that by default, you can't instantiate - callback<> for reference and pointer return types: although the - unwrappers may exist, they may convert by-value, which would cause - the referent to be destroyed upon return. - -wrap: - - find the registry entry for the source type - - see if there is a converter. If found, stick a pointer to it in - the wrap object. - - when queried for convertibility, it checks to see if it has a - pointer to a converter. - - on conversion, a reference to the target PyObject is held by the - converter. Generally, the PyObject will have been created by the - converter, but in certain cases it may be a pre-existing object, - whose reference count will have been incremented. - - when a wrap x is used to return from a C++ function, - x.release() is returned so that x no longer holds a reference to - the PyObject when destroyed. - - Otherwise, on destruction, any PyObject still held has its - reference-count decremented. - - -When a converter is created by the user, the appropriate element must -be added to the registry; when it is destroyed, it must be removed -from the registry. diff --git a/doc/news.html b/doc/news.html deleted file mode 100644 index 8ab97245..00000000 --- a/doc/news.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - Boost.Python - News/Change Log - - - - - - - - - -
-

-

-
-

Boost.Python

- -

News/Change Log

-
-
- -
-
24 February 2003
- -
Finished improved support - for boost::shared_ptr. Now any wrapped object of - C++ class X can be converted automatically - to shared_ptr<X>, regardless of how it was - wrapped. The shared_ptr will manage the lifetime - of the Python object which supplied the X, rather - than just the X object itself, and when such - a shared_ptr is converted back to Python, the - original Python object will be returned.
- -
19 January 2003
- -
Integrated staticmethod support from Nikolay Mladenov. Thanks, - Nikolay!
- -
29 December 2002
- -
Added Visual Studio project file and instructions from Brett - Calcott. Thanks, Brett!
- -
20 December 2002
- -
Added automatic downcasting for pointers, references, and smart - pointers to polymorphic class types upon conversion to python
- -
18 December 2002
- -
Optimized from_python conversions for wrapped classes by putting - the conversion logic in the shared library instead of registering - separate converters for each class in each extension module
- -
19 November 2002
- -
Removed the need for users to cast base class member function - pointers when used as arguments to add_property
- -
13 December 2002
- -
Allow exporting of enum_ values into enclosing - scope.
- Fixed unsigned integer conversions to deal correctly with numbers that - are out-of-range of signed long.
- -
14 November 2002
- -
Auto-detection of class data members wrapped with make_getter
- -
13 November 2002
- -
Full Support for std::auto_ptr<> added.
- -
October 2002
- -
Ongoing updates and improvements to tutorial documentation
- -
10 October 2002
- -
Boost.Python V2 is released!
-
-
- -

Revised - - 20 December, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt deleted file mode 100644 index c6f89416..00000000 --- a/doc/polymorphism.txt +++ /dev/null @@ -1,217 +0,0 @@ -How Runtime Polymorphism is expressed in Boost.Python: ------------------------------------------------------ - - struct A { virtual std::string f(); virtual ~A(); }; - - std::string call_f(A& x) { return x.f(); } - - struct B { virtual std::string f() { return "B"; } }; - - struct Bcb : B - { - Bcb(PyObject* self) : m_self(self) {} - - virtual std::string f() { return call_method(m_sef, "f"); } - static std::string f_default(B& b) { return b.B::f(); } - - PyObject* m_self; - }; - - struct C : B - { - virtual std::string f() { return "C"; } - }; - - >>> class D(B): - ... def f(): - ... return 'D' - ... - >>> class E(B): pass - ... - - -When we write, "invokes B::f non-virtually", we mean: - - void g(B& x) { x.B::f(); } - -This will call B::f() regardless of the dynamic type of x. Any other -way of invoking B::f, including through a function pointer, is a -"virtual invocation", and will call the most-derived override of f(). - -Case studies - - C++\Python class - \___A_____B_____C_____D____E___ - | - A | 1 - | - B | 2 3 - | - Bcb | 4 5 6 - | - C | 7 8 - | - - -1. Simple case - -2. Python A holds a B*. Probably won't happen once we have forced - downcasting. - - Requires: - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: A.f invokes A::f() (virtually or otherwise) - -3. Python B holds a B*. - - Requires: - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f (virtually or otherwise) - - -4. B constructed from Python - - Requires: - - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f non-virtually. Bcb::f invokes B::f - non-virtually. - - Question: Does it help if we arrange for Python B construction to - build a true B object? Then this case doesn't arise. - - -5. D is a Python class derived from B - - Requires: - - x.f() -> 'D' - call_f(x) -> 'D' - - Implies: Bcb::f must invoke call_method to look up the Python - method override, otherwise call_f wouldn't work. - -6. E is like D, but doesn't override f - - Requires: - - x.f() -> 'B' - call_f(x) -> 'B' - - Implies: B.f invokes B::f non-virtually. If it were virtual, x.f() - would cause infinite recursion, because we've already - determined that Bcb::f must invoke call_method to look up - the Python method override. - -7. Python B object holds a C* - - Requires: - - x.f() -> 'C' - call_f(x) -> 'C' - - Implies: B.f invokes B::f virtually. - -8. C object constructed from Python - - Requires: - - x.f() -> 'C' - call_f(x) -> 'C' - - Implies: nothing new. - ------- - -Total implications: - -2: A.f invokes A::f() (virtually or otherwise) -3: B.f invokes B::f (virtually or otherwise) -4: B.f invokes B::f non-virtually. Bcb::f invokes B::f non-virtually -6: B.f invokes B::f non-virtually. -7: B.f invokes B::f virtually. - -5: Bcb::f invokes call_method to look up the Python method - -Though (4) is avoidable, clearly 6 and 7 are not, and they -conflict. The implication is that B.f must choose its behavior -according to the type of the contained C++ object. If it is Bcb, a -non-virtual call to B::f must occur. Otherwise, a virtual call to B::f -must occur. This is essentially the same scheme we had with -Boost.Python v1. - -Note: in early versions of Boost.Python v1, we solved this problem by -introducing a new Python class in the hierarchy, so that D and E -actually derive from a B', and B'.f invokes B::f non-virtually, while -B.f invokes B::f virtually. However, people complained about the -artificial class in the hierarchy, which was revealed when they tried -to do normal kinds of Python introspection. - -------- - -Assumption: we will have a function which builds a virtual function -dispatch callable Python object. - - make_virtual_function(pvmf, default_impl, call_policies, dispatch_type) - -Pseudocode: - - Get first argument from Python arg tuple - if it contains dispatch_type - call default_impl - else - call through pvmf - - -Open questions: - - 1. What about Python multiple inheritance? Do we have the right - check in the if clause above? - - A: Not quite. The correct test looks like: - - Deduce target type of pvmf, i.e. T in R(T::*)(A1...AN). - Find holder in first argument which holds T - if it holds dispatch_type... - - 2. Can we make this more efficient? - - The current "returning" mechanism will look up a holder for T - again. I don't know if we know how to avoid that. - - - OK, the solution involves reworking the call mechanism. This is - neccesary anyway in order to enable wrapping of function objects. - - It can result in a reduction in the overall amount of source code, - because returning<> won't need to be specialized for every - combination of function and member function... though it will still - need a void specialization. We will still need a way to dispatch to - member functions through a regular function interface. mem_fn is - almost the right tool, but it only goes up to 8 - arguments. Forwarding is tricky if you don't want to incur copies. - I think the trick is to use arg_from_python::result_type for each - argument to the forwarder. - - Another option would be to use separate function, function object, - and member function dispatchers. Once you know you have a member - function, you don't need cv-qualified overloads to call it. - - Hmm, while we're at this, maybe we should solve the write-back - converter problem. Can we do it? Maybe not. Ralf doesn't want to - write special write-back functions here, does he? He wants the - converter to do the work automatically. We could add - cleanup/destructor registration. That would relieve the client from - having accessible destructors for types which are being converted by - rvalue. I'm not sure that this will really save any code, - however. It rather depends on the linker, doesn't it? I wonder if - this can be done in a backwards-compatible fashion by generating the - delete function when it's not supplied? - - diff --git a/doc/projects.html b/doc/projects.html deleted file mode 100644 index 5db7ec27..00000000 --- a/doc/projects.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - Boost.Python - Projects using Boost.Python - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Projects using Boost.Python

-
-
- -

Introduction

- -

This is a partial list of projects using Boost.Python. If you are - using Boost.Python as your Python/C++ binding solution, we'd be proud to - list your project on this page. Just post a short description of your project - and how Boost.Python helps you get the job done, and we'll add it to this - page .

-
- -

Enterprise Software

- -
-
OpenWBEM
- -
- The OpenWBEM project is an effort to develop an open-source - implementation of Web Based Enterprise Management suitable for - commercial and non-commercial application - -

Dan Nuffer writes:

- -
- I'm using Boost.Python to wrap the client API of OpenWBEM.This will - make it easier to do rapid prototyping, testing, and scripting when - developing management solutions that use WBEM. -
-
-
- -

Financial Analysis

- -
-
TSLib - Fortress - Investment Group LLC
- -
- Fortress Investment Group has contracted Boost Consulting to develop - core internal financial analysis tools in C++ and to prepare Python - bindings for them using Boost.Python. - -

Tom Barket of Fortress writes:

- -
- We have a large C++ analytical library specialized for research in - finance and economics, built for speed and mission critical - stability. Yet Python offers us the flexibility to test out new - ideas quickly and increase the productivity of our time versus - working in C++. There are several key features which make Python - stand out. Its elegance, stability, and breadth of resources on the - web are all valuable, but the most important is its extensibility, - due to its open source transparency. Boost.Python makes Python - extensibility extremely simple and straightforward, yet preserves a - great deal of power and control. -
-
-
- -

Graphics

- -
-
OpenSceneGraph
- -
Gideon May has created a - set of bindings for OpenSceneGraph, a cross-platform C++/OpenGL library - for the real-time visualization. You can read the release announcement - at www.hypereyes.com. Contact Gideon for more - information.
-  
- -
PythonMagick
- -
PythonMagick binds the ImageMagick image manipulation library - to Python.
-  
- -
HippoDraw - Stanford - Linear Accelerator Center
- -
- HippoDraw is a data analysis environment consisting of a canvas upon - which graphs such as histograms, scattter plots, etc, are prsented. - It has a highly interactive GUI interface, but some things you need - to do with scripts. HippoDraw can be run as Python extension module - so that all the manipulation can be done from either Python or the - GUI. - -

Paul F. Kunz - writes:

- -
- Don't have a web page for the project, but the organization's is http://www.slac.stanford.edu - (the first web server site in America, I installed it). -
- Which was just too cool a piece of trivia to omit.
-   -
-
- -

Scientific Computing

- -
-
CAMFR
- -
- CAMFR is a photonics and electromagnetics modelling tool. Python is - used for computational steering. - -

Peter Bienstman - writes:

- -
- Thanks for providing such a great tool! -
-
- -
cctbx - Computational - Crystallography Toolbox
- -
- Computational Crystallography is concerned with the derivation of - atomic models of crystal structures, given experimental X-ray - diffraction data. The cctbx is an open-source library of fundamental - algorithms for crystallographic computations. The core algorithms are - implemented in C++ and accessed through higher-level Python - interfaces. - -

The cctbx grew together with Boost.Python and is designed from the - ground up as a hybrid Python/C++ system. With one minor exception, - run-time polymorphism is completely handled by Python. C++ - compile-time polymorphism is used to implement performance critical - algorithms. The Python and C++ layers are seamlessly integrated using - Boost.Python.

- -

The SourceForge cctbx project is organized in modules to - facilitate use in non-crystallographic applications. The scitbx - module implements a general purpose array family for scientific - applications and pure C++ ports of FFTPACK and the LBFGS conjugate - gradient minimizer.

-
- -
EMSolve
- -
EMSolve is a provably stable, charge conserving, and energy - conserving solver for Maxwell's equations.
-  
- -
Gaudi and RootPython
- -
- Gaudi is a framework for particle physics collision data processing - applications developed in the context of the LHCb and ATLAS - experiments at CERN. - -

Pere Mato Vila writes:

- -
- We are using Boost.Python to provide scripting/interactive - capability to our framework. We have a module called "GaudiPython" - implemented using Boost.Python that allows the interaction with any - framework service or algorithm from python. RootPython also uses - Boost.Python to provide a generic "gateway" between the ROOT framework and python - -

Boost.Python is great. We managed very quickly to interface our - framework to python, which is great language. We are trying to - facilitate to our physicists (end-users) a rapid analysis - application development environment based on python. For that, - Boost.Python plays and essential role.

-
-
-
-
- -

Revised - - 16 November, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/support.html b/doc/support.html deleted file mode 100644 index 1f0e932c..00000000 --- a/doc/support.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - Boost.Python - Support Resources - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Support Resources

-
-
- -

Synopsis

- -

This is a list of available resources for support with Boost.Python - problems and feature requests.

-
- -
-
Boost - Consulting - Commercial support, development, training, and - distribution for all the Boost libraries, from the people who brought - you Boost.Python.
-  
- -
The Python - C++-sig mailing list is a forum for discussing Python/C++ - interoperability, and Boost.Python in particular.
-  
- -
The Boost.Python Wiki - Pages established by Mike Rovner as part of the PythonInfo Wiki serves as - a forum to gather peoples' experience and as a cookbook.
-  
-
-
- -

Revised - - 17 November, 2002 - -

- -

© Copyright Dave - Abrahams 2002. All Rights Reserved.

- - - diff --git a/doc/tutorial/doc/auto_overloading.html b/doc/tutorial/doc/auto_overloading.html deleted file mode 100644 index d478eeae..00000000 --- a/doc/tutorial/doc/auto_overloading.html +++ /dev/null @@ -1,112 +0,0 @@ - - - -Auto-Overloading - - - - - - - - - - -
- - Auto-Overloading -
-
- - - - - - -
-

-It was mentioned in passing in the previous section that -BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_FUNCTION_OVERLOADS -can also be used for overloaded functions and member functions with a -common sequence of initial arguments. Here is an example:

-
-     void foo()
-     {
-        /*...*/
-     }
-
-     void foo(bool a)
-     {
-        /*...*/
-     }
-
-     void foo(bool a, int b)
-     {
-        /*...*/
-     }
-
-     void foo(bool a, int b, char c)
-     {
-        /*...*/
-     }
-
-

-Like in the previous section, we can generate thin wrappers for these -overloaded functions in one-shot:

-
-    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
-
-

-Then...

-
-    .def("foo", foo, foo_overloads());
-
-

-Notice though that we have a situation now where we have a minimum of zero -(0) arguments and a maximum of 3 arguments.

-

Manual Wrapping

-It is important to emphasize however that the overloaded functions must -have a common sequence of initial arguments. Otherwise, our scheme above -will not work. If this is not the case, we have to wrap our functions - -manually.

-

-Actually, we can mix and match manual wrapping of overloaded functions and -automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS and -its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Following up on our example -presented in the section -on overloading, since the -first 4 overload functins have a common sequence of initial arguments, we -can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS to automatically wrap the -first three of the defs and manually wrap just the last. Here's -how we'll do this:

-
-    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
-
-

-Create a member function pointers as above for both X::f overloads:

-
-    bool    (X::*fx1)(int, double, char)    = &X::f;
-    int     (X::*fx2)(int, int, int)        = &X::f;
-
-

-Then...

-
-    .def("f", fx1, xf_overloads());
-    .def("f", fx2)
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/basic_interface.html b/doc/tutorial/doc/basic_interface.html deleted file mode 100644 index 8165b121..00000000 --- a/doc/tutorial/doc/basic_interface.html +++ /dev/null @@ -1,77 +0,0 @@ - - - -Basic Interface - - - - - - - - - - -
- - Basic Interface -
-
- - - - - - -
-

-Class object wraps PyObject*. All the intricacies of dealing with -PyObjects such as managing reference counting are handled by the -object class. C++ object interoperability is seamless. Boost.Python C++ -objects can in fact be explicitly constructed from any C++ object.

-

-To illustrate, this Python code snippet:

-
-    def f(x, y):
-         if (y == 'foo'):
-             x[3:7] = 'bar'
-         else:
-             x.items += y(3, x)
-         return x
-
-    def getfunc():
-       return f;
-
-

-Can be rewritten in C++ using Boost.Python facilities this way:

-
-    object f(object x, object y) {
-         if (y == "foo")
-             x.slice(3,7) = "bar";
-         else
-             x.attr("items") += y(3, x);
-         return x;
-    }
-    object getfunc() {
-        return object(f);
-    }
-
-

-Apart from cosmetic differences due to the fact that we are writing the -code in C++, the look and feel should be immediately apparent to the Python -coder.

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/building_hello_world.html b/doc/tutorial/doc/building_hello_world.html deleted file mode 100644 index 09b7ba93..00000000 --- a/doc/tutorial/doc/building_hello_world.html +++ /dev/null @@ -1,191 +0,0 @@ - - - -Building Hello World - - - - - - - - - - -
- - Building Hello World -
-
- - - - - - -
-

From Start To Finish

-Now the first thing you'd want to do is to build the Hello World module and -try it for yourself in Python. In this section, we shall outline the steps -necessary to achieve that. We shall use the build tool that comes bundled -with every boost distribution: bjam.

- - - - -
- Building without bjam

- -Besides bjam, there are of course other ways to get your module built. -What's written here should not be taken as "the one and only way". -There are of course other build tools apart from bjam. -
-

-We shall skip over the details. Our objective will be to simply create the -hello world module and run it in Python. For a complete reference to -building Boost.Python, check out: -building.html. -After this brief bjam tutorial, we should have built two DLLs:

-
  • boost_python.dll
  • hello.pyd

-if you are on Windows, and

-
  • libboost_python.so
  • hello.so

-if you are on Unix.

-

-The tutorial example can be found in the directory: -libs/python/example/tutorial. There, you can find:

-
  • hello.cpp
  • Jamfile

-The hello.cpp file is our C++ hello world example. The Jamfile is a -minimalist bjam script that builds the DLLs for us.

-

-Before anything else, you should have the bjam executable in your boost -directory or somewhere in your path such that bjam can be executed in -the command line. Pre-built Boost.Jam executables are available for most -platforms. For example, a pre-built Microsoft Windows bjam executable can -be downloaded -here. -The complete list of bjam pre-built -executables can be found -here.

-

Lets Jam!

-

-

-Here is our minimalist Jamfile:

-
-    subproject libs/python/example/tutorial ;
-
-    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
-    include python.jam ;
-
-    extension hello                     # Declare a Python extension called hello
-    :   hello.cpp                       # source
-        <dll>../../build/boost_python   # dependencies
-        ;
-

-First, we need to specify our location in the boost project hierarchy. -It so happens that the tutorial example is located in /libs/python/example/tutorial. -Thus:

-
-    subproject libs/python/example/tutorial ;
-

-Then we will include the definitions needed by Python modules:

-
-    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
-    include python.jam ;
-

-Finally we declare our hello extension:

-
-    extension hello                     # Declare a Python extension called hello
-    :   hello.cpp                       # source
-        <dll>../../build/boost_python   # dependencies
-        ;
-

Running bjam

-bjam is run using your operating system's command line interpreter.

-

Start it up.

-Make sure that the environment is set so that we can invoke the C++ -compiler. With MSVC, that would mean running the Vcvars32.bat batch -file. For instance:

-
-    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
-
-

-Some environment variables will have to be setup for proper building of our -Python modules. Example:

-
-    set PYTHON_ROOT=c:/dev/tools/python
-    set PYTHON_VERSION=2.2
-
-

-The above assumes that the Python installation is in c:/dev/tools/python -and that we are using Python version 2.2. You'll have to tweak this path -appropriately. Be sure not to include a third number, e.g. not "2.2.1", -even if that's the version you have.

-

-Now we are ready... Be sure to cd to libs/python/example/tutorial -where the tutorial "hello.cpp" and the "Jamfile" is situated.

-

-Finally:

-
-    bjam -sTOOLS=msvc
-
-

-We are again assuming that we are using Microsoft Visual C++ version 6. If -not, then you will have to specify the appropriate tool. See - -Building Boost Libraries for -further details.

-

-It should be building now:

-
-    cd C:\dev\boost\libs\python\example\tutorial
-    bjam -sTOOLS=msvc
-    ...patience...
-    ...found 1703 targets...
-    ...updating 40 targets...
-

-And so on... Finally:

-
-    vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
-    runtime-link-dynamic\hello.obj
-    hello.cpp
-    vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
-    runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\
-    hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
-       Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\
-       msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\
-       example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
-    ...updated 40 targets...
-

-If all is well, you should now have:

-
  • boost_python.dll
  • hello.pyd

-if you are on Windows, and

-
  • libboost_python.so
  • hello.so

-if you are on Unix.

-

-boost_python.dll can be found somewhere in libs\python\build\bin -while hello.pyd can be found somewhere in -libs\python\example\tutorial\bin. After a successful build, you can just -link in these DLLs with the Python interpreter. In Windows for example, you -can simply put these libraries inside the directory where the Python -executable is.

-

-You may now fire up Python and run our hello module:

-
-    >>> import hello
-    >>> print hello.greet()
-    hello, world
-
-

There you go... Have fun!

- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/call_policies.html b/doc/tutorial/doc/call_policies.html deleted file mode 100644 index dc94ea5b..00000000 --- a/doc/tutorial/doc/call_policies.html +++ /dev/null @@ -1,169 +0,0 @@ - - - -Call Policies - - - - - - - - - - -
- - Call Policies -
-
- - - - - - -
-

-In C++, we often deal with arguments and return types such as pointers -and references. Such primitive types are rather, ummmm, low level and -they really don't tell us much. At the very least, we don't know the -owner of the pointer or the referenced object. No wonder languages -such as Java and Python never deal with such low level entities. In -C++, it's usually considered a good practice to use smart pointers -which exactly describe ownership semantics. Still, even good C++ -interfaces use raw references and pointers sometimes, so Boost.Python -must deal with them. To do this, it may need your help. Consider the -following C++ function:

-
-    X& f(Y& y, Z* z);
-
-

-How should the library wrap this function? A naive approach builds a -Python X object around result reference. This strategy might or might -not work out. Here's an example where it didn't

-
-    >>> x = f(y, z) ##x refers to some C++ X
-    >>> del y
-    >>> x.some_method() ##CRASH!
-
-

-What's the problem?

-

-Well, what if f() was implemented as shown below:

-
-    X& f(Y& y, Z* z)
-    {
-        y.z = z;
-        return y.x;
-    }
-
-

-The problem is that the lifetime of result X& is tied to the lifetime -of y, because the f() returns a reference to a member of the y -object. This idiom is is not uncommon and perfectly acceptable in the -context of C++. However, Python users should not be able to crash the -system just by using our C++ interface. In this case deleting y will -invalidate the reference to X. We have a dangling reference.

-

-Here's what's happening:

-
  1. f is called passing in a reference to y and a pointer to z
  2. A reference to y.x is returned
  3. y is deleted. x is a dangling reference
  4. x.some_method() is called
  5. BOOM!

-We could copy result into a new object:

-
-    >>> f(y, z).set(42) ##Result disappears
-    >>> y.x.get()       ##No crash, but still bad
-    3.14
-
-

-This is not really our intent of our C++ interface. We've broken our -promise that the Python interface should reflect the C++ interface as -closely as possible.

-

-Our problems do not end there. Suppose Y is implemented as follows:

-
-    struct Y
-    {
-        X x; Z* z;
-        int z_value() { return z->value(); }
-    };
-
-

-Notice that the data member z is held by class Y using a raw -pointer. Now we have a potential dangling pointer problem inside Y:

-
-    >>> x = f(y, z) ##y refers to z
-    >>> del z       ##Kill the z object
-    >>> y.z_value() ##CRASH!
-
-

-For reference, here's the implementation of f again:

-
-    X& f(Y& y, Z* z)
-    {
-        y.z = z;
-        return y.x;
-    }
-
-

-Here's what's happening:

-
  1. f is called passing in a reference to y and a pointer to z
  2. A pointer to z is held by y
  3. A reference to y.x is returned
  4. z is deleted. y.z is a dangling pointer
  5. y.z_value() is called
  6. z->value() is called
  7. BOOM!

Call Policies

-Call Policies may be used in situations such as the example detailed above. -In our example, return_internal_reference and with_custodian_and_ward -are our friends:

-
-    def("f", f,
-        return_internal_reference<1,
-            with_custodian_and_ward<1, 2> >());
-
-

-What are the 1 and 2 parameters, you ask?

-
-    return_internal_reference<1
-
-

-Informs Boost.Python that the first argument, in our case Y& y, is the -owner of the returned reference: X&. The "1" simply specifies the -first argument. In short: "return an internal reference X& owned by the -1st argument Y& y".

-
-    with_custodian_and_ward<1, 2>
-
-

-Informs Boost.Python that the lifetime of the argument indicated by ward -(i.e. the 2nd argument: Z* z) is dependent on the lifetime of the -argument indicated by custodian (i.e. the 1st argument: Y& y).

-

-It is also important to note that we have defined two policies above. Two -or more policies can be composed by chaining. Here's the general syntax:

-
-    policy1<args...,
-        policy2<args...,
-            policy3<args...> > >
-
-

-Here is the list of predefined call policies. A complete reference detailing -these can be found -here.

-
  • with_custodian_and_ward
    Ties lifetimes of the arguments
  • with_custodian_and_ward_postcall
    Ties lifetimes of the arguments and results
  • return_internal_reference
    Ties lifetime of one argument to that of result
  • return_value_policy<T> with T one of:
  • reference_existing_object
    naïve (dangerous) approach
  • copy_const_reference
    Boost.Python v1 approach
  • copy_non_const_reference
  • manage_new_object
    Adopt a pointer and hold the instance
- - - -
- Remember the Zen, Luke:

-"Explicit is better than implicit"
-"In the face of ambiguity, refuse the temptation to guess"
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_data_members.html b/doc/tutorial/doc/class_data_members.html deleted file mode 100644 index b43bf83c..00000000 --- a/doc/tutorial/doc/class_data_members.html +++ /dev/null @@ -1,78 +0,0 @@ - - - -Class Data Members - - - - - - - - - - -
- - Class Data Members -
-
- - - - - - -
-

-Data members may also be exposed to Python so that they can be -accessed as attributes of the corresponding Python class. Each data -member that we wish to be exposed may be regarded as read-only or -read-write. Consider this class Var:

-
-    struct Var
-    {
-        Var(std::string name) : name(name), value() {}
-        std::string const name;
-        float value;
-    };
-
-

-Our C++ Var class and its data members can be exposed to Python:

-
-    class_<Var>("Var", init<std::string>())
-        .def_readonly("name", &Var::name)
-        .def_readwrite("value", &Var::value);
-
-

-Then, in Python, assuming we have placed our Var class inside the namespace -hello as we did before:

-
-    >>> x = hello.Var('pi')
-    >>> x.value = 3.14
-    >>> print x.name, 'is around', x.value
-    pi is around 3.14
-
-

-Note that name is exposed as read-only while value is exposed -as read-write.

-
-    >>> x.name = 'e' # can't change name
-    Traceback (most recent call last):
-      File "<stdin>", line 1, in ?
-    AttributeError: can't set attribute
-
- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_operators_special_functions.html b/doc/tutorial/doc/class_operators_special_functions.html deleted file mode 100644 index ce7aab66..00000000 --- a/doc/tutorial/doc/class_operators_special_functions.html +++ /dev/null @@ -1,109 +0,0 @@ - - - -Class Operators/Special Functions - - - - - - - - - - -
- - Class Operators/Special Functions -
-
- - - - - - -
-

Python Operators

-C is well known for the abundance of operators. C++ extends this to the -extremes by allowing operator overloading. Boost.Python takes advantage of -this and makes it easy to wrap C++ operator-powered classes.

-

-Consider a file position class FilePos and a set of operators that take -on FilePos instances:

-
-    class FilePos { /*...*/ };
-
-    FilePos     operator+(FilePos, int);
-    FilePos     operator+(int, FilePos);
-    int         operator-(FilePos, FilePos);
-    FilePos     operator-(FilePos, int);
-    FilePos&    operator+=(FilePos&, int);
-    FilePos&    operator-=(FilePos&, int);
-    bool        operator<(FilePos, FilePos);
-
-

-The class and the various operators can be mapped to Python rather easily -and intuitively:

-
-    class_<FilePos>("FilePos")
-        .def(self + int())          // __add__
-        .def(int() + self)          // __radd__
-        .def(self - self)           // __sub__
-        .def(self - int())          // __sub__
-        .def(self += int())         // __iadd__
-        .def(self -= other<int>())
-        .def(self < self);          // __lt__
-
-

-The code snippet above is very clear and needs almost no explanation at -all. It is virtually the same as the operators' signatures. Just take -note that self refers to FilePos object. Also, not every class T that -you might need to interact with in an operator expression is (cheaply) -default-constructible. You can use other<T>() in place of an actual -T instance when writing "self expressions".

-

Special Methods

-Python has a few more Special Methods. Boost.Python supports all of the -standard special method names supported by real Python class instances. A -similar set of intuitive interfaces can also be used to wrap C++ functions -that correspond to these Python special functions. Example:

-
-    class Rational
-    { operator double() const; };
-
-    Rational pow(Rational, Rational);
-    Rational abs(Rational);
-    ostream& operator<<(ostream&,Rational);
-
-    class_<Rational>()
-        .def(float_(self))                  // __float__
-        .def(pow(self, other<Rational>))    // __pow__
-        .def(abs(self))                     // __abs__
-        .def(str(self))                     // __str__
-        ;
-
-

-Need we say more?

- - - - -
- What is the business of operator<< .def(str(self))? -Well, the method str requires the operator<< to do its work (i.e. -operator<< is used by the method defined by def(str(self)).
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_properties.html b/doc/tutorial/doc/class_properties.html deleted file mode 100644 index 99f340c4..00000000 --- a/doc/tutorial/doc/class_properties.html +++ /dev/null @@ -1,81 +0,0 @@ - - - -Class Properties - - - - - - - - - - -
- - Class Properties -
-
- - - - - - -
-

-In C++, classes with public data members are usually frowned -upon. Well designed classes that take advantage of encapsulation hide -the class' data members. The only way to access the class' data is -through access (getter/setter) functions. Access functions expose class -properties. Here's an example:

-
-    struct Num
-    {
-        Num();
-        float get() const;
-        void set(float value);
-        ...
-    };
-
-

-However, in Python attribute access is fine; it doesn't neccessarily break -encapsulation to let users handle attributes directly, because the -attributes can just be a different syntax for a method call. Wrapping our -Num class using Boost.Python:

-
-    class_<Num>("Num")
-        .add_property("rovalue", &Num::get)
-        .add_property("value", &Num::get, &Num::set);
-
-

-And at last, in Python:

-
-    >>> x = Num()
-    >>> x.value = 3.14
-    >>> x.value, x.rovalue
-    (3.14, 3.14)
-    >>> x.rovalue = 2.17 ##error!
-
-

-Take note that the class property rovalue is exposed as read-only -since the rovalue setter member function is not passed in:

-
-    .add_property("rovalue", &Num::get)
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html deleted file mode 100644 index 37ce60ce..00000000 --- a/doc/tutorial/doc/class_virtual_functions.html +++ /dev/null @@ -1,129 +0,0 @@ - - - -Class Virtual Functions - - - - - - - - - - -
- - Class Virtual Functions -
-
- - - - - - -
-

-In this section, we shall learn how to make functions behave -polymorphically through virtual functions. Continuing our example, let us -add a virtual function to our Base class:

-
-    struct Base
-    {
-        virtual int f() = 0;
-    };
-
-

-Since f is a pure virtual function, Base is now an abstract -class. Given an instance of our class, the free function call_f -calls some implementation of this virtual function in a concrete -derived class:

-
-    int call_f(Base& b) { return b.f(); }
-
-

-To allow this function to be implemented in a Python derived class, we -need to create a class wrapper:

-
-    struct BaseWrap : Base
-    {
-        BaseWrap(PyObject* self_)
-            : self(self_) {}
-        int f() { return call_method<int>(self, "f"); }
-        PyObject* self;
-    };
-
- - - - -
- member function and methods

Python, like -many object oriented languages uses the term methods. Methods -correspond roughly to C++'s member functions
-

-Our class wrapper BaseWrap is derived from Base. Its overridden -virtual member function f in effect calls the corresponding method -of the Python object self, which is a pointer back to the Python -Base object holding our BaseWrap instance.

- - - - -
- Why do we need BaseWrap?

- -You may ask, "Why do we need the BaseWrap derived class? This could -have been designed so that everything gets done right inside of -Base."

- -One of the goals of Boost.Python is to be minimally intrusive on an -existing C++ design. In principle, it should be possible to expose the -interface for a 3rd party library without changing it. To unintrusively -hook into the virtual functions so that a Python override may be called, we -must use a derived class.

- -Note however that you don't need to do this to get methods overridden -in Python to behave virtually when called from Python. The only -time you need to do the BaseWrap dance is when you have a virtual -function that's going to be overridden in Python and called -polymorphically from C++.
-

-Wrapping Base and the free function call_f:

-
-    class_<Base, BaseWrap, boost::noncopyable>("Base", no_init)
-        ;
-    def("call_f", call_f);
-
-

-Notice that we parameterized the class_ template with BaseWrap as the -second parameter. What is noncopyable? Without it, the library will try -to create code for converting Base return values of wrapped functions to -Python. To do that, it needs Base's copy constructor... which isn't -available, since Base is an abstract class.

-

-In Python, let us try to instantiate our Base class:

-
-    >>> base = Base()
-    RuntimeError: This class cannot be instantiated from Python
-
-

-Why is it an error? Base is an abstract class. As such it is advisable -to define the Python wrapper with no_init as we have done above. Doing -so will disallow abstract base classes such as Base to be instantiated.

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/constructors.html b/doc/tutorial/doc/constructors.html deleted file mode 100644 index 809bfee3..00000000 --- a/doc/tutorial/doc/constructors.html +++ /dev/null @@ -1,102 +0,0 @@ - - - -Constructors - - - - - - - - - - -
- - Constructors -
-
- - - - - - -
-

-Our previous example didn't have any explicit constructors. -Since World is declared as a plain struct, it has an implicit default -constructor. Boost.Python exposes the default constructor by default, -which is why we were able to write

-
-    >>> planet = hello.World()
-
-

-We may wish to wrap a class with a non-default constructor. Let us -build on our previous example:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} // added constructor
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-

-This time World has no default constructor; our previous -wrapping code would fail to compile when the library tried to expose -it. We have to tell class_<World> about the constructor we want to -expose instead.

-
-    #include <boost/python.hpp>
-    using namespace boost::python;
-
-    BOOST_PYTHON_MODULE(hello)
-    {
-        class_<World>("World", init<std::string>())
-            .def("greet", &World::greet)
-            .def("set", &World::set)
-        ;
-    }
-
-

-init<std::string>() exposes the constructor taking in a -std::string (in Python, constructors are spelled -""__init__"").

-

-We can expose additional constructors by passing more init<...>s to -the def() member function. Say for example we have another World -constructor taking in two doubles:

-
-    class_<World>("World", init<std::string>())
-        .def(init<double, double>())
-        .def("greet", &World::greet)
-        .def("set", &World::set)
-    ;
-
-

-On the other hand, if we do not wish to expose any constructors at -all, we may use no_init instead:

-
-    class_<Abstract>("Abstract", no_init)
-
-

-This actually adds an __init__ method which always raises a -Python RuntimeError exception.

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/default_arguments.html b/doc/tutorial/doc/default_arguments.html deleted file mode 100644 index d0c1f426..00000000 --- a/doc/tutorial/doc/default_arguments.html +++ /dev/null @@ -1,158 +0,0 @@ - - - -Default Arguments - - - - - - - - - - -
- - Default Arguments -
-
- - - - - - -
-

-Boost.Python wraps (member) function pointers. Unfortunately, C++ function -pointers carry no default argument info. Take a function f with default -arguments:

-
-    int f(int, double = 3.14, char const* = "hello");
-
-

-But the type of a pointer to the function f has no information -about its default arguments:

-
-    int(*g)(int,double,char const*) = f;    // defaults lost!
-
-

-When we pass this function pointer to the def function, there is no way -to retrieve the default arguments:

-
-    def("f", f);                            // defaults lost!
-
-

-Because of this, when wrapping C++ code, we had to resort to manual -wrapping as outlined in the -previous section, or -writing thin wrappers:

-
-    // write "thin wrappers"
-    int f1(int x) { f(x); }
-    int f2(int x, double y) { f(x,y); }
-
-    /*...*/
-
-        // in module init
-        def("f", f);  // all arguments
-        def("f", f2); // two arguments
-        def("f", f1); // one argument
-
-

-When you want to wrap functions (or member functions) that either:

-
  • have default arguments, or
  • are overloaded with a common sequence of initial arguments

BOOST_PYTHON_FUNCTION_OVERLOADS

-Boost.Python now has a way to make it easier. For instance, given a function:

-
-    int foo(int a, char b = 1, unsigned c = 2, double d = 3)
-    {
-        /*...*/
-    }
-
-

-The macro invocation:

-
-    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)
-
-

-will automatically create the thin wrappers for us. This macro will create -a class foo_overloads that can be passed on to def(...). The third -and fourth macro argument are the minimum arguments and maximum arguments, -respectively. In our foo function the minimum number of arguments is 1 -and the maximum number of arguments is 4. The def(...) function will -automatically add all the foo variants for us:

-
-    .def("foo", foo, foo_overloads());
-
-

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS

-Objects here, objects there, objects here there everywhere. More frequently -than anything else, we need to expose member functions of our classes to -Python. Then again, we have the same inconveniences as before when default -arguments or overloads with a common sequence of initial arguments come -into play. Another macro is provided to make this a breeze.

-

-Like BOOST_PYTHON_FUNCTION_OVERLOADS, -BOOST_PYTHON_FUNCTION_OVERLOADS may be used to automatically create -the thin wrappers for wrapping member functions. Let's have an example:

-
-    struct george
-    {
-        void
-        wack_em(int a, int b = 0, char c = 'x')
-        {
-            /*...*/
-        }
-    };
-
-

-The macro invocation:

-
-    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
-
-

-will generate a set of thin wrappers for george's wack_em member function -accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and -fourth macro argument). The thin wrappers are all enclosed in a class named -george_overloads that can then be used as an argument to def(...):

-
-    .def("wack_em", &george::wack_em, george_overloads());
-
-

-See the -overloads reference -for details.

-

init and optional

-A similar facility is provided for class constructors, again, with -default arguments or a sequence of overloads. Remember init<...>? For example, -given a class X with a constructor:

-
-    struct X
-    {
-        X(int a, char b = 'D', std::string c = "constructor", double d = 0.0);
-        /*...*/
-    }
-
-

-You can easily add this constructor to Boost.Python in one shot:

-
-    .def(init<int, optional<char, std::string, double> >())
-
-

-Notice the use of init<...> and optional<...> to signify the default -(optional arguments).

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/derived_object_types.html b/doc/tutorial/doc/derived_object_types.html deleted file mode 100644 index fbe44584..00000000 --- a/doc/tutorial/doc/derived_object_types.html +++ /dev/null @@ -1,117 +0,0 @@ - - - -Derived Object types - - - - - - - - - - -
- - Derived Object types -
-
- - - - - - -
-

-Boost.Python comes with a set of derived object types corresponding to -that of Python's:

-
  • list
  • dict
  • tuple
  • str
  • long_
  • enum

-These derived object types act like real Python types. For instance:

-
-    str(1) ==> "1"
-
-

-Wherever appropriate, a particular derived object has corresponding -Python type's methods. For instance, dict has a keys() method:

-
-    d.keys()
-
-

-make_tuple is provided for declaring tuple literals. Example:

-
-    make_tuple(123, 'D', "Hello, World", 0.0);
-
-

-In C++, when Boost.Python objects are used as arguments to functions, -subtype matching is required. For example, when a function f, as -declared below, is wrapped, it will only accept instances of Python's -str type and subtypes.

-
-    void f(str name)
-    {
-        object n2 = name.attr("upper")();   // NAME = name.upper()
-        str NAME = name.upper();            // better
-        object msg = "%s is bigger than %s" % make_tuple(NAME,name);
-    }
-
-

-In finer detail:

-
-    str NAME = name.upper();
-
-

-Illustrates that we provide versions of the str type's methods as C++ -member functions.

-
-    object msg = "%s is bigger than %s" % make_tuple(NAME,name);
-
-

-Demonstrates that you can write the C++ equivalent of "format" % x,y,z -in Python, which is useful since there's no easy way to do that in std C++.

-

- Beware the common pitfall of forgetting that the constructors -of most of Python's mutable types make copies, just as in Python.

-

-Python:

-
-    >>> d = dict(x.__dict__)     ##copies x.__dict__
-    >>> d['whatever']            ##modifies the copy
-
-

-C++:

-
-    dict d(x.attr("__dict__"));  ##copies x.__dict__
-    d['whatever'] = 3;           ##modifies the copy
-
-

class_<T> as objects

-Due to the dynamic nature of Boost.Python objects, any class_<T> may -also be one of these types! The following code snippet wraps the class -(type) object.

-

-We can use this to create wrapped instances. Example:

-
-    object vec345 = (
-        class_<Vec2>("Vec2", init<double, double>())
-            .def_readonly("length", &Point::length)
-            .def_readonly("angle", &Point::angle)
-        )(3.0, 4.0);
-
-    assert(vec345.attr("length") == 5.0);
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/deriving_a_python_class.html b/doc/tutorial/doc/deriving_a_python_class.html deleted file mode 100644 index 5c268371..00000000 --- a/doc/tutorial/doc/deriving_a_python_class.html +++ /dev/null @@ -1,83 +0,0 @@ - - - -Deriving a Python Class - - - - - - - - - - -
- - Deriving a Python Class -
-
- - - - - - -
-

-Continuing, we can derive from our base class Base in Python and override -the virtual function in Python. Before we can do that, we have to set up -our class_ wrapper as:

-
-    class_<Base, BaseWrap, boost::noncopyable>("Base")
-        ;
-
-

-Otherwise, we have to suppress the Base class' no_init by adding an -__init__() method to all our derived classes. no_init actually adds -an __init__ method that raises a Python RuntimeError exception.

-
-    >>> class Derived(Base):
-    ...     def f(self):
-    ...         return 42
-    ...
-
-

-Cool eh? A Python class deriving from a C++ class!

-

-Let's now make an instance of our Python class Derived:

-
-    >>> derived = Derived()
-
-

-Calling derived.f():

-
-    >>> derived.f()
-    42
-
-

-Will yield the expected result. Finally, calling calling the free function -call_f with derived as argument:

-
-    >>> call_f(derived)
-    42
-
-

-Will also yield the expected result.

-

-Here's what's happening:

-
  1. call_f(derived) is called in Python
  2. This corresponds to def("call_f", call_f);. Boost.Python dispatches this call.
  3. int call_f(Base& b) { return b.f(); } accepts the call.
  4. The overridden virtual function f of BaseWrap is called.
  5. call_method<int>(self, "f"); dispatches the call back to Python.
  6. def f(self): return 42 is finally called.
- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/embedding.html b/doc/tutorial/doc/embedding.html deleted file mode 100644 index 8cd1c725..00000000 --- a/doc/tutorial/doc/embedding.html +++ /dev/null @@ -1,97 +0,0 @@ - - - -Embedding - - - - - - - - - - -
- - Embedding -
-
- - - - - - -
-

-By now you should know how to use Boost.Python to call your C++ code from -Python. However, sometimes you may need to do the reverse: call Python code -from the C++-side. This requires you to embed the Python interpreter -into your C++ program.

-

-Currently, Boost.Python does not directly support everything you'll need -when embedding. Therefore you'll need to use the - -Python/C API to fill in -the gaps. However, Boost.Python already makes embedding a lot easier and, -in a future version, it may become unnecessary to touch the Python/C API at -all. So stay tuned...

-

Building embedded programs

-To be able to use embedding in your programs, they have to be linked to -both Boost.Python's and Python's static link library.

-

-Boost.Python's static link library comes in two variants. Both are located -in Boost's /libs/python/build/bin-stage subdirectory. On Windows, the -variants are called boost_python.lib (for release builds) and -boost_python_debug.lib (for debugging). If you can't find the -libraries, you probably haven't built Boost.Python yet. See Building and Testing on how to do -this.

-

-Python's static link library can be found in the /libs subdirectory of -your Python directory. On Windows it is called pythonXY.lib where X.Y is -your major Python version number.

-

-Additionally, Python's /include subdirectory has to be added to your -include path.

-

-In a Jamfile, all the above boils down to:

-
-    projectroot c:\projects\embedded_program ; # location of the program
-
-    # bring in the rules for python
-    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
-    include python.jam ;
-
-    exe embedded_program # name of the executable
-      : #sources
-         embedded_program.cpp
-      : # requirements
-         <find-library>boost_python <library-path>c:\boost\libs\python
-      $(PYTHON_PROPERTIES)
-        <library-path>$(PYTHON_LIB_PATH)
-        <find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
-

Getting started

-Being able to build is nice, but there is nothing to build yet. Embedding -the Python interpreter into one of your C++ programs requires these 4 -steps:

-
  1. #include <boost/python.hpp>

  2. Call -Py_Initialize() to start the interpreter and create the __main__ module.

  3. Call other Python C API routines to use the interpreter.

  4. Call -Py_Finalize() to stop the interpreter and release its resources.

-(Of course, there can be other C++ code between all of these steps.)

-

Now that we can embed the interpreter in our programs, lets see how to put it to use...

- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html deleted file mode 100644 index 09632e31..00000000 --- a/doc/tutorial/doc/enums.html +++ /dev/null @@ -1,95 +0,0 @@ - - - -Enums - - - - - - - - - - -
- - Enums -
-
- - - - - - -
-

-Boost.Python has a nifty facility to capture and wrap C++ enums. While -Python has no enum type, we'll often want to expose our C++ enums to -Python as an int. Boost.Python's enum facility makes this easy while -taking care of the proper conversions from Python's dynamic typing to C++'s -strong static typing (in C++, ints cannot be implicitly converted to -enums). To illustrate, given a C++ enum:

-
-    enum choice { red, blue };
-
-

-the construct:

-
-    enum_<choice>("choice")
-        .value("red", red)
-        .value("blue", blue)
-        ;
-
-

-can be used to expose to Python. The new enum type is created in the -current scope(), which is usually the current module. The snippet above -creates a Python class derived from Python's int type which is -associated with the C++ type passed as its first parameter.

- - - - -
- what is a scope?

The scope is a class that has an -associated global Python object which controls the Python namespace in -which new extension classes and wrapped functions will be defined as -attributes. Details can be found -here.
-

-You can access those values in Python as

-
-    >>> my_module.choice.red
-    my_module.choice.red
-
-

-where my_module is the module where the enum is declared. You can also -create a new scope around a class:

-
-    scope in_X = class_<X>("X")
-                    .def( ... )
-                    .def( ... )
-                ;
-
-    // Expose X::nested as X.nested
-    enum_<X::nested>("nested")
-        .value("red", red)
-        .value("blue", blue)
-        ;
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/exception_translation.html b/doc/tutorial/doc/exception_translation.html deleted file mode 100644 index 51c73560..00000000 --- a/doc/tutorial/doc/exception_translation.html +++ /dev/null @@ -1,60 +0,0 @@ - - - -Exception Translation - - - - - - - - - -
- - Exception Translation -
-
- - - - - - -
-

-All C++ exceptions must be caught at the boundary with Python code. This -boundary is the point where C++ meets Python. Boost.Python provides a -default exception handler that translates selected standard exceptions, -then gives up:

-
-    raise RuntimeError, 'unidentifiable C++ Exception'
-
-

-Users may provide custom translation. Here's an example:

-
-    struct PodBayDoorException;
-    void translator(PodBayDoorException const& x) {
-        PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
-    }
-    BOOST_PYTHON_MODULE(kubrick) {
-         register_exception_translator<
-              PodBayDoorException>(translator);
-         ...
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/exposing_classes.html b/doc/tutorial/doc/exposing_classes.html deleted file mode 100644 index 18f2e8d0..00000000 --- a/doc/tutorial/doc/exposing_classes.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Exposing Classes - - - - - - - - - - -
- - Exposing Classes -
-
- - - - - - -
-

-Now let's expose a C++ class to Python.

-

-Consider a C++ class/struct that we want to expose to Python:

-
-    struct World
-    {
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-

-We can expose this to Python by writing a corresponding Boost.Python -C++ Wrapper:

-
-    #include <boost/python.hpp>
-    using namespace boost::python;
-
-    BOOST_PYTHON_MODULE(hello)
-    {
-        class_<World>("World")
-            .def("greet", &World::greet)
-            .def("set", &World::set)
-        ;
-    }
-
-

-Here, we wrote a C++ class wrapper that exposes the member functions -greet and set. Now, after building our module as a shared library, we -may use our class World in Python. Here's a sample Python session:

-
-    >>> import hello
-    >>> planet = hello.World()
-    >>> planet.set('howdy')
-    >>> planet.greet()
-    'howdy'
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/extracting_c___objects.html b/doc/tutorial/doc/extracting_c___objects.html deleted file mode 100644 index 82096e6d..00000000 --- a/doc/tutorial/doc/extracting_c___objects.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Extracting C++ objects - - - - - - - - - - -
- - Extracting C++ objects -
-
- - - - - - -
-

-At some point, we will need to get C++ values out of object instances. This -can be achieved with the extract<T> function. Consider the following:

-
-    double x = o.attr("length"); // compile error
-
-

-In the code above, we got a compiler error because Boost.Python -object can't be implicitly converted to doubles. Instead, what -we wanted to do above can be achieved by writing:

-
-    double l = extract<double>(o.attr("length"));
-    Vec2& v = extract<Vec2&>(o);
-    assert(l == v.length());
-
-

-The first line attempts to extract the "length" attribute of the -Boost.Python object o. The second line attempts to extract the -Vec2 object from held by the Boost.Python object o.

-

-Take note that we said "attempt to" above. What if the Boost.Python -object o does not really hold a Vec2 type? This is certainly -a possibility considering the dynamic nature of Python objects. To -be on the safe side, if the C++ type can't be extracted, an -appropriate exception is thrown. To avoid an exception, we need to -test for extractibility:

-
-    extract<Vec2&> x(o);
-    if (x.check()) {
-        Vec2& v = x(); ...
-
-

- The astute reader might have noticed that the extract<T> -facility in fact solves the mutable copying problem:

-
-    dict d = extract<dict>(x.attr("__dict__"));
-    d['whatever'] = 3;          ##modifies x.__dict__ !
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/functions.html b/doc/tutorial/doc/functions.html deleted file mode 100644 index 6a29d89b..00000000 --- a/doc/tutorial/doc/functions.html +++ /dev/null @@ -1,73 +0,0 @@ - - - -Functions - - - - - - - - - - -
- - Functions -
-
- - - - - - -
-

-In this chapter, we'll look at Boost.Python powered functions in closer -detail. We shall see some facilities to make exposing C++ functions to -Python safe from potential pifalls such as dangling pointers and -references. We shall also see facilities that will make it even easier for -us to expose C++ functions that take advantage of C++ features such as -overloading and default arguments.

-

Read on...

-But before you do, you might want to fire up Python 2.2 or later and type ->>> import this.

-
-    >>> import this
-    The Zen of Python, by Tim Peters
-    Beautiful is better than ugly.
-    Explicit is better than implicit.
-    Simple is better than complex.
-    Complex is better than complicated.
-    Flat is better than nested.
-    Sparse is better than dense.
-    Readability counts.
-    Special cases aren't special enough to break the rules.
-    Although practicality beats purity.
-    Errors should never pass silently.
-    Unless explicitly silenced.
-    In the face of ambiguity, refuse the temptation to guess.
-    There should be one-- and preferably only one --obvious way to do it
-    Although that way may not be obvious at first unless you're Dutch.
-    Now is better than never.
-    Although never is often better than *right* now.
-    If the implementation is hard to explain, it's a bad idea.
-    If the implementation is easy to explain, it may be a good idea.
-    Namespaces are one honking great idea -- let's do more of those!
-
- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/inheritance.html b/doc/tutorial/doc/inheritance.html deleted file mode 100644 index acd18942..00000000 --- a/doc/tutorial/doc/inheritance.html +++ /dev/null @@ -1,98 +0,0 @@ - - - -Inheritance - - - - - - - - - - -
- - Inheritance -
-
- - - - - - -
-

-In the previous examples, we dealt with classes that are not polymorphic. -This is not often the case. Much of the time, we will be wrapping -polymorphic classes and class hierarchies related by inheritance. We will -often have to write Boost.Python wrappers for classes that are derived from -abstract base classes.

-

-Consider this trivial inheritance structure:

-
-    struct Base { virtual ~Base(); };
-    struct Derived : Base {};
-
-

-And a set of C++ functions operating on Base and Derived object -instances:

-
-    void b(Base*);
-    void d(Derived*);
-    Base* factory() { return new Derived; }
-
-

-We've seen how we can wrap the base class Base:

-
-    class_<Base>("Base")
-        /*...*/
-        ;
-
-

-Now we can inform Boost.Python of the inheritance relationship between -Derived and its base class Base. Thus:

-
-    class_<Derived, bases<Base> >("Derived")
-        /*...*/
-        ;
-
-

-Doing so, we get some things for free:

-
  1. Derived automatically inherits all of Base's Python methods (wrapped C++ member functions)
  2. If Base is polymorphic, Derived objects which have been passed to Python via a pointer or reference to Base can be passed where a pointer or reference to Derived is expected.

-Now, we shall expose the C++ free functions b and d and factory:

-
-    def("b", b);
-    def("d", d);
-    def("factory", factory);
-
-

-Note that free function factory is being used to generate new -instances of class Derived. In such cases, we use -return_value_policy<manage_new_object> to instruct Python to adopt -the pointer to Base and hold the instance in a new Python Base -object until the the Python object is destroyed. We shall see more of -Boost.Python -call policies later.

-
-    // Tell Python to take ownership of factory's result
-    def("factory", factory,
-        return_value_policy<manage_new_object>());
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/iterators.html b/doc/tutorial/doc/iterators.html deleted file mode 100644 index 585f89b1..00000000 --- a/doc/tutorial/doc/iterators.html +++ /dev/null @@ -1,101 +0,0 @@ - - - -Iterators - - - - - - - - - - -
- - Iterators -
-
- - - - - - -
-

-In C++, and STL in particular, we see iterators everywhere. Python also has -iterators, but these are two very different beasts.

-

-C++ iterators:

-
  • C++ has 5 type categories (random-access, bidirectional, forward, input, output)
  • There are 2 Operation categories: reposition, access
  • A pair of iterators is needed to represent a (first/last) range.

-Python Iterators:

-
  • 1 category (forward)
  • 1 operation category (next())
  • Raises StopIteration exception at end

-The typical Python iteration protocol: for y in x... is as follows:

-
-    iter = x.__iter__()         ##get iterator
-    try:
-        while 1:
-        y = iter.next()         ##get each item
-        ...                     ##process y
-    except StopIteration: pass  ##iterator exhausted
-
-

-Boost.Python provides some mechanisms to make C++ iterators play along -nicely as Python iterators. What we need to do is to produce -appropriate __iter__ function from C++ iterators that is compatible -with the Python iteration protocol. For example:

-
-    object get_iterator = iterator<vector<int> >();
-    object iter = get_iterator(v);
-    object first = iter.next();
-
-

-Or for use in class_<>:

-
-    .def("__iter__", iterator<vector<int> >())
-
-

-range

-

-We can create a Python savvy iterator using the range function:

-
  • range(start, finish)
  • range<Policies,Target>(start, finish)

-Here, start/finish may be one of:

-
  • member data pointers
  • member function pointers
  • adaptable function object (use Target parameter)

-iterator

-
  • iterator<T, Policies>()

-Given a container T, iterator is a shortcut that simply calls range -with &T::begin, &T::end.

-

-Let's put this into action... Here's an example from some hypothetical -bogon Particle accelerator code:

-
-    f = Field()
-    for x in f.pions:
-        smash(x)
-    for y in f.bogons:
-        count(y)
-
-

-Now, our C++ Wrapper:

-
-    class_<F>("Field")
-        .property("pions", range(&F::p_begin, &F::p_end))
-        .property("bogons", range(&F::b_begin, &F::b_end));
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/object_interface.html b/doc/tutorial/doc/object_interface.html deleted file mode 100644 index 1988dcd7..00000000 --- a/doc/tutorial/doc/object_interface.html +++ /dev/null @@ -1,54 +0,0 @@ - - - -Object Interface - - - - - - - - - - -
- - Object Interface -
-
- - - - - - -
-

-Python is dynamically typed, unlike C++ which is statically typed. Python -variables may hold an integer, a float, list, dict, tuple, str, long etc., -among other things. In the viewpoint of Boost.Python and C++, these -Pythonic variables are just instances of class object. We shall see in -this chapter how to deal with Python objects.

-

-As mentioned, one of the goals of Boost.Python is to provide a -bidirectional mapping between C++ and Python while maintaining the Python -feel. Boost.Python C++ objects are as close as possible to Python. This -should minimize the learning curve significantly.

-

-

- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/overloading.html b/doc/tutorial/doc/overloading.html deleted file mode 100644 index f93edcac..00000000 --- a/doc/tutorial/doc/overloading.html +++ /dev/null @@ -1,88 +0,0 @@ - - - -Overloading - - - - - - - - - - -
- - Overloading -
-
- - - - - - -
-

-The following illustrates a scheme for manually wrapping an overloaded -member functions. Of course, the same technique can be applied to wrapping -overloaded non-member functions.

-

-We have here our C++ class:

-
-    struct X
-    {
-        bool f(int a)
-        {
-            return true;
-        }
-
-        bool f(int a, double b)
-        {
-            return true;
-        }
-
-        bool f(int a, double b, char c)
-        {
-            return true;
-        }
-
-        int f(int a, int b, int c)
-        {
-            return a + b + c;
-        };
-    };
-
-

-Class X has 4 overloaded functions. We shall start by introducing some -member function pointer variables:

-
-    bool    (X::*fx1)(int)              = &X::f;
-    bool    (X::*fx2)(int, double)      = &X::f;
-    bool    (X::*fx3)(int, double, char)= &X::f;
-    int     (X::*fx4)(int, int, int)    = &X::f;
-
-

-With these in hand, we can proceed to define and wrap this for Python:

-
-    .def("f", fx1)
-    .def("f", fx2)
-    .def("f", fx3)
-    .def("f", fx4)
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/quickstart.html b/doc/tutorial/doc/quickstart.html deleted file mode 100644 index 02ba7a1a..00000000 --- a/doc/tutorial/doc/quickstart.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -QuickStart - - - - - - - - - -
- - QuickStart -
-
- - - - - - -
-

-The Boost Python Library is a framework for interfacing Python and -C++. It allows you to quickly and seamlessly expose C++ classes -functions and objects to Python, and vice-versa, using no special -tools -- just your C++ compiler. It is designed to wrap C++ interfaces -non-intrusively, so that you should not have to change the C++ code at -all in order to wrap it, making Boost.Python ideal for exposing -3rd-party libraries to Python. The library's use of advanced -metaprogramming techniques simplifies its syntax for users, so that -wrapping code takes on the look of a kind of declarative interface -definition language (IDL).

-

Hello World

-Following C/C++ tradition, let's start with the "hello, world". A C++ -Function:

-
-    char const* greet()
-    {
-       return "hello, world";
-    }
-
-

-can be exposed to Python by writing a Boost.Python wrapper:

-
-    #include <boost/python.hpp>
-    using namespace boost::python;
-
-    BOOST_PYTHON_MODULE(hello)
-    {
-        def("greet", greet);
-    }
-
-

-That's it. We're done. We can now build this as a shared library. The -resulting DLL is now visible to Python. Here's a sample Python session:

-
-    >>> import hello
-    >>> print hello.greet()
-    hello, world
-
-

Next stop... Building your Hello World module from start to finish...

- - - - - -
-
-
- - diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt deleted file mode 100644 index 7efc63bf..00000000 --- a/doc/tutorial/doc/quickstart.txt +++ /dev/null @@ -1,1426 +0,0 @@ -[doc Boost Python Tutorial] - -[def __note__ [$theme/note.gif]] -[def __alert__ [$theme/alert.gif]] -[def __detail__ [$theme/lens.gif]] -[def __tip__ [$theme/bulb.gif]] -[def :-) [$theme/smiley.gif]] - -[page QuickStart] - -The Boost Python Library is a framework for interfacing Python and -C++. It allows you to quickly and seamlessly expose C++ classes -functions and objects to Python, and vice-versa, using no special -tools -- just your C++ compiler. It is designed to wrap C++ interfaces -non-intrusively, so that you should not have to change the C++ code at -all in order to wrap it, making Boost.Python ideal for exposing -3rd-party libraries to Python. The library's use of advanced -metaprogramming techniques simplifies its syntax for users, so that -wrapping code takes on the look of a kind of declarative interface -definition language (IDL). - -[h2 Hello World] - -Following C/C++ tradition, let's start with the "hello, world". A C++ -Function: - - char const* greet() - { - return "hello, world"; - } - -can be exposed to Python by writing a Boost.Python wrapper: - - #include - using namespace boost::python; - - BOOST_PYTHON_MODULE(hello) - { - def("greet", greet); - } - -That's it. We're done. We can now build this as a shared library. The -resulting DLL is now visible to Python. Here's a sample Python session: - - >>> import hello - >>> print hello.greet() - hello, world - -[:['[*Next stop... Building your Hello World module from start to finish...]]] - -[page Building Hello World] - -[h2 From Start To Finish] - -Now the first thing you'd want to do is to build the Hello World module and -try it for yourself in Python. In this section, we shall outline the steps -necessary to achieve that. We shall use the build tool that comes bundled -with every boost distribution: [*bjam]. - -[blurb __detail__ [*Building without bjam][br][br] - -Besides bjam, there are of course other ways to get your module built. -What's written here should not be taken as "the one and only way". -There are of course other build tools apart from [^bjam]. -] - -We shall skip over the details. Our objective will be to simply create the -hello world module and run it in Python. For a complete reference to -building Boost.Python, check out: [@../../building.html building.html]. -After this brief ['bjam] tutorial, we should have built two DLLs: - -* boost_python.dll -* hello.pyd - -if you are on Windows, and - -* libboost_python.so -* hello.so - -if you are on Unix. - -The tutorial example can be found in the directory: -[^libs/python/example/tutorial]. There, you can find: - -* hello.cpp -* Jamfile - -The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a -minimalist ['bjam] script that builds the DLLs for us. - -Before anything else, you should have the bjam executable in your boost -directory or somewhere in your path such that [^bjam] can be executed in -the command line. Pre-built Boost.Jam executables are available for most -platforms. For example, a pre-built Microsoft Windows bjam executable can -be downloaded [@http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip here]. -The complete list of bjam pre-built -executables can be found [@../../../../../tools/build/index.html#Jam here]. - -[h2 Lets Jam!] -[$theme/jam.png] - -Here is our minimalist Jamfile: - -[pre - subproject libs/python/example/tutorial ; - - SEARCH on python.jam = $(BOOST_BUILD_PATH) ; - include python.jam ; - - extension hello # Declare a Python extension called hello - : hello.cpp # source - ../../build/boost_python # dependencies - ; -] - -First, we need to specify our location in the boost project hierarchy. -It so happens that the tutorial example is located in [^/libs/python/example/tutorial]. -Thus: - -[pre - subproject libs/python/example/tutorial ; -] - -Then we will include the definitions needed by Python modules: - -[pre - SEARCH on python.jam = $(BOOST_BUILD_PATH) ; - include python.jam ; -] - -Finally we declare our [^hello] extension: - -[pre - extension hello # Declare a Python extension called hello - : hello.cpp # source - ../../build/boost_python # dependencies - ; -] - -[h2 Running bjam] - -['bjam] is run using your operating system's command line interpreter. - -[:Start it up.] - -Make sure that the environment is set so that we can invoke the C++ -compiler. With MSVC, that would mean running the [^Vcvars32.bat] batch -file. For instance: - - C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat - -Some environment variables will have to be setup for proper building of our -Python modules. Example: - - set PYTHON_ROOT=c:/dev/tools/python - set PYTHON_VERSION=2.2 - -The above assumes that the Python installation is in [^c:/dev/tools/python] -and that we are using Python version 2.2. You'll have to tweak this path -appropriately. __note__ Be sure not to include a third number, e.g. [*not] "2.2.1", -even if that's the version you have. - -Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial] -where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated. - -Finally: - - bjam -sTOOLS=msvc - -We are again assuming that we are using Microsoft Visual C++ version 6. If -not, then you will have to specify the appropriate tool. See -[@../../../../../tools/build/index.html Building Boost Libraries] for -further details. - -It should be building now: - -[pre - cd C:\dev\boost\libs\python\example\tutorial - bjam -sTOOLS=msvc - ...patience... - ...found 1703 targets... - ...updating 40 targets... -] - -And so on... Finally: - -[pre - vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\ - runtime-link-dynamic\hello.obj - hello.cpp - vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\ - runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\ - hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib - Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\ - msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\ - example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp - ...updated 40 targets... -] - -If all is well, you should now have: - -* boost_python.dll -* hello.pyd - -if you are on Windows, and - -* libboost_python.so -* hello.so - -if you are on Unix. - -[^boost_python.dll] can be found somewhere in [^libs\python\build\bin] -while [^hello.pyd] can be found somewhere in -[^libs\python\example\tutorial\bin]. After a successful build, you can just -link in these DLLs with the Python interpreter. In Windows for example, you -can simply put these libraries inside the directory where the Python -executable is. - -You may now fire up Python and run our hello module: - - >>> import hello - >>> print hello.greet() - hello, world - -[:[*There you go... Have fun!]] - -[page Exposing Classes] - -Now let's expose a C++ class to Python. - -Consider a C++ class/struct that we want to expose to Python: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -We can expose this to Python by writing a corresponding Boost.Python -C++ Wrapper: - - #include - using namespace boost::python; - - BOOST_PYTHON_MODULE(hello) - { - class_("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -Here, we wrote a C++ class wrapper that exposes the member functions -[^greet] and [^set]. Now, after building our module as a shared library, we -may use our class [^World] in Python. Here's a sample Python session: - - >>> import hello - >>> planet = hello.World() - >>> planet.set('howdy') - >>> planet.greet() - 'howdy' - -[page:1 Constructors] - -Our previous example didn't have any explicit constructors. -Since [^World] is declared as a plain struct, it has an implicit default -constructor. Boost.Python exposes the default constructor by default, -which is why we were able to write - - >>> planet = hello.World() - -We may wish to wrap a class with a non-default constructor. Let us -build on our previous example: - - struct World - { - World(std::string msg): msg(msg) {} // added constructor - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -This time [^World] has no default constructor; our previous -wrapping code would fail to compile when the library tried to expose -it. We have to tell [^class_] about the constructor we want to -expose instead. - - #include - using namespace boost::python; - - BOOST_PYTHON_MODULE(hello) - { - class_("World", init()) - .def("greet", &World::greet) - .def("set", &World::set) - ; - } - -[^init()] exposes the constructor taking in a -[^std::string] (in Python, constructors are spelled -"[^"__init__"]"). - -We can expose additional constructors by passing more [^init<...>]s to -the [^def()] member function. Say for example we have another World -constructor taking in two doubles: - - class_("World", init()) - .def(init()) - .def("greet", &World::greet) - .def("set", &World::set) - ; - -On the other hand, if we do not wish to expose any constructors at -all, we may use [^no_init] instead: - - class_("Abstract", no_init) - -This actually adds an [^__init__] method which always raises a -Python RuntimeError exception. - -[page:1 Class Data Members] - -Data members may also be exposed to Python so that they can be -accessed as attributes of the corresponding Python class. Each data -member that we wish to be exposed may be regarded as [*read-only] or -[*read-write]. Consider this class [^Var]: - - struct Var - { - Var(std::string name) : name(name), value() {} - std::string const name; - float value; - }; - -Our C++ [^Var] class and its data members can be exposed to Python: - - class_("Var", init()) - .def_readonly("name", &Var::name) - .def_readwrite("value", &Var::value); - -Then, in Python, assuming we have placed our Var class inside the namespace -hello as we did before: - - >>> x = hello.Var('pi') - >>> x.value = 3.14 - >>> print x.name, 'is around', x.value - pi is around 3.14 - -Note that [^name] is exposed as [*read-only] while [^value] is exposed -as [*read-write]. - -[pre - >>> x.name = 'e' # can't change name - Traceback (most recent call last): - File "", line 1, in ? - AttributeError: can't set attribute -] - -[page:1 Class Properties] - -In C++, classes with public data members are usually frowned -upon. Well designed classes that take advantage of encapsulation hide -the class' data members. The only way to access the class' data is -through access (getter/setter) functions. Access functions expose class -properties. Here's an example: - - struct Num - { - Num(); - float get() const; - void set(float value); - ... - }; - -However, in Python attribute access is fine; it doesn't neccessarily break -encapsulation to let users handle attributes directly, because the -attributes can just be a different syntax for a method call. Wrapping our -[^Num] class using Boost.Python: - - class_("Num") - .add_property("rovalue", &Num::get) - .add_property("value", &Num::get, &Num::set); - -And at last, in Python: - - >>> x = Num() - >>> x.value = 3.14 - >>> x.value, x.rovalue - (3.14, 3.14) - >>> x.rovalue = 2.17 # error! - -Take note that the class property [^rovalue] is exposed as [*read-only] -since the [^rovalue] setter member function is not passed in: - - .add_property("rovalue", &Num::get) - -[page:1 Inheritance] - -In the previous examples, we dealt with classes that are not polymorphic. -This is not often the case. Much of the time, we will be wrapping -polymorphic classes and class hierarchies related by inheritance. We will -often have to write Boost.Python wrappers for classes that are derived from -abstract base classes. - -Consider this trivial inheritance structure: - - struct Base { virtual ~Base(); }; - struct Derived : Base {}; - -And a set of C++ functions operating on [^Base] and [^Derived] object -instances: - - void b(Base*); - void d(Derived*); - Base* factory() { return new Derived; } - -We've seen how we can wrap the base class [^Base]: - - class_("Base") - /*...*/ - ; - -Now we can inform Boost.Python of the inheritance relationship between -[^Derived] and its base class [^Base]. Thus: - - class_ >("Derived") - /*...*/ - ; - -Doing so, we get some things for free: - -# Derived automatically inherits all of Base's Python methods (wrapped C++ member functions) -# [*If] Base is polymorphic, [^Derived] objects which have been passed to Python via a pointer or reference to [^Base] can be passed where a pointer or reference to [^Derived] is expected. - -Now, we shall expose the C++ free functions [^b] and [^d] and [^factory]: - - def("b", b); - def("d", d); - def("factory", factory); - -Note that free function [^factory] is being used to generate new -instances of class [^Derived]. In such cases, we use -[^return_value_policy] to instruct Python to adopt -the pointer to [^Base] and hold the instance in a new Python [^Base] -object until the the Python object is destroyed. We shall see more of -Boost.Python [@call_policies.html call policies] later. - - // Tell Python to take ownership of factory's result - def("factory", factory, - return_value_policy()); - -[page:1 Class Virtual Functions] - -In this section, we shall learn how to make functions behave -polymorphically through virtual functions. Continuing our example, let us -add a virtual function to our [^Base] class: - - struct Base - { - virtual int f() = 0; - }; - -Since [^f] is a pure virtual function, [^Base] is now an abstract -class. Given an instance of our class, the free function [^call_f] -calls some implementation of this virtual function in a concrete -derived class: - - int call_f(Base& b) { return b.f(); } - -To allow this function to be implemented in a Python derived class, we -need to create a class wrapper: - - struct BaseWrap : Base - { - BaseWrap(PyObject* self_) - : self(self_) {} - int f() { return call_method(self, "f"); } - PyObject* self; - }; - -[blurb __detail__ [*member function and methods][br][br] Python, like -many object oriented languages uses the term [*methods]. Methods -correspond roughly to C++'s [*member functions]] - -Our class wrapper [^BaseWrap] is derived from [^Base]. Its overridden -virtual member function [^f] in effect calls the corresponding method -of the Python object [^self], which is a pointer back to the Python -[^Base] object holding our [^BaseWrap] instance. - -[blurb __note__ [*Why do we need BaseWrap?][br][br] - -['You may ask], "Why do we need the [^BaseWrap] derived class? This could -have been designed so that everything gets done right inside of -Base."[br][br] - -One of the goals of Boost.Python is to be minimally intrusive on an -existing C++ design. In principle, it should be possible to expose the -interface for a 3rd party library without changing it. To unintrusively -hook into the virtual functions so that a Python override may be called, we -must use a derived class.[br][br] - -Note however that you don't need to do this to get methods overridden -in Python to behave virtually when called ['from] [*Python]. The only -time you need to do the [^BaseWrap] dance is when you have a virtual -function that's going to be overridden in Python and called -polymorphically ['from] [*C++].] - -Wrapping [^Base] and the free function [^call_f]: - - class_("Base", no_init) - ; - def("call_f", call_f); - -Notice that we parameterized the [^class_] template with [^BaseWrap] as the -second parameter. What is [^noncopyable]? Without it, the library will try -to create code for converting Base return values of wrapped functions to -Python. To do that, it needs Base's copy constructor... which isn't -available, since Base is an abstract class. - -In Python, let us try to instantiate our [^Base] class: - - >>> base = Base() - RuntimeError: This class cannot be instantiated from Python - -Why is it an error? [^Base] is an abstract class. As such it is advisable -to define the Python wrapper with [^no_init] as we have done above. Doing -so will disallow abstract base classes such as [^Base] to be instantiated. - -[page:1 Deriving a Python Class] - -Continuing, we can derive from our base class Base in Python and override -the virtual function in Python. Before we can do that, we have to set up -our [^class_] wrapper as: - - class_("Base") - ; - -Otherwise, we have to suppress the Base class' [^no_init] by adding an -[^__init__()] method to all our derived classes. [^no_init] actually adds -an [^__init__] method that raises a Python RuntimeError exception. - - >>> class Derived(Base): - ... def f(self): - ... return 42 - ... - -Cool eh? A Python class deriving from a C++ class! - -Let's now make an instance of our Python class [^Derived]: - - >>> derived = Derived() - -Calling [^derived.f()]: - - >>> derived.f() - 42 - -Will yield the expected result. Finally, calling calling the free function -[^call_f] with [^derived] as argument: - - >>> call_f(derived) - 42 - -Will also yield the expected result. - -Here's what's happening: - -# [^call_f(derived)] is called in Python -# This corresponds to [^def("call_f", call_f);]. Boost.Python dispatches this call. -# [^int call_f(Base& b) { return b.f(); }] accepts the call. -# The overridden virtual function [^f] of [^BaseWrap] is called. -# [^call_method(self, "f");] dispatches the call back to Python. -# [^def f(self): return 42] is finally called. - -[page:1 Virtual Functions with Default Implementations] - -Recall that in the [@class_virtual_functions.html previous section], we -wrapped a class with a pure virtual function that we then implemented in -C++ or Python classes derived from it. Our base class: - - struct Base - { - virtual int f() = 0; - }; - -had a pure virtual function [^f]. If, however, its member function [^f] was -not declared as pure virtual: - - struct Base - { - virtual int f() { return 0; } - }; - -and instead had a default implementation that returns [^0], as shown above, -we need to add a forwarding function that calls the [^Base] default virtual -function [^f] implementation: - - struct BaseWrap : Base - { - BaseWrap(PyObject* self_) - : self(self_) {} - int f() { return call_method(self, "f"); } - int default_f() { return Base::f(); } // <<=== ***ADDED*** - PyObject* self; - }; - -Then, Boost.Python needs to keep track of 1) the dispatch function [^f] and -2) the forwarding function to its default implementation [^default_f]. -There's a special [^def] function for this purpose. Here's how it is -applied to our example above: - - class_("Base") - .def("f", &Base::f, &BaseWrap::default_f) - -Note that we are allowing [^Base] objects to be instantiated this time, -unlike before where we specifically defined the [^class_] with -[^no_init]. - -In Python, the results would be as expected: - - >>> base = Base() - >>> class Derived(Base): - ... def f(self): - ... return 42 - ... - >>> derived = Derived() - -Calling [^base.f()]: - - >>> base.f() - 0 - -Calling [^derived.f()]: - - >>> derived.f() - 42 - -Calling [^call_f], passing in a [^base] object: - - >>> call_f(base) - 0 - -Calling [^call_f], passing in a [^derived] object: - - >>> call_f(derived) - 42 - -[page:1 Class Operators/Special Functions] - -[h2 Python Operators] - -C is well known for the abundance of operators. C++ extends this to the -extremes by allowing operator overloading. Boost.Python takes advantage of -this and makes it easy to wrap C++ operator-powered classes. - -Consider a file position class [^FilePos] and a set of operators that take -on FilePos instances: - - class FilePos { /*...*/ }; - - FilePos operator+(FilePos, int); - FilePos operator+(int, FilePos); - int operator-(FilePos, FilePos); - FilePos operator-(FilePos, int); - FilePos& operator+=(FilePos&, int); - FilePos& operator-=(FilePos&, int); - bool operator<(FilePos, FilePos); - -The class and the various operators can be mapped to Python rather easily -and intuitively: - - class_("FilePos") - .def(self + int()) // __add__ - .def(int() + self) // __radd__ - .def(self - self) // __sub__ - .def(self - int()) // __sub__ - .def(self += int()) // __iadd__ - .def(self -= other()) - .def(self < self); // __lt__ - -The code snippet above is very clear and needs almost no explanation at -all. It is virtually the same as the operators' signatures. Just take -note that [^self] refers to FilePos object. Also, not every class [^T] that -you might need to interact with in an operator expression is (cheaply) -default-constructible. You can use [^other()] in place of an actual -[^T] instance when writing "self expressions". - -[h2 Special Methods] - -Python has a few more ['Special Methods]. Boost.Python supports all of the -standard special method names supported by real Python class instances. A -similar set of intuitive interfaces can also be used to wrap C++ functions -that correspond to these Python ['special functions]. Example: - - class Rational - { operator double() const; }; - - Rational pow(Rational, Rational); - Rational abs(Rational); - ostream& operator<<(ostream&,Rational); - - class_() - .def(float_(self)) // __float__ - .def(pow(self, other)) // __pow__ - .def(abs(self)) // __abs__ - .def(str(self)) // __str__ - ; - -Need we say more? - -[blurb __detail__ What is the business of [^operator<<] [^.def(str(self))]? -Well, the method [^str] requires the [^operator<<] to do its work (i.e. -[^operator<<] is used by the method defined by def(str(self)).] - -[page Functions] - -In this chapter, we'll look at Boost.Python powered functions in closer -detail. We shall see some facilities to make exposing C++ functions to -Python safe from potential pifalls such as dangling pointers and -references. We shall also see facilities that will make it even easier for -us to expose C++ functions that take advantage of C++ features such as -overloading and default arguments. - -[:['Read on...]] - -But before you do, you might want to fire up Python 2.2 or later and type -[^>>> import this]. - -[pre - >>> import this - The Zen of Python, by Tim Peters - Beautiful is better than ugly. - Explicit is better than implicit. - Simple is better than complex. - Complex is better than complicated. - Flat is better than nested. - Sparse is better than dense. - Readability counts. - Special cases aren't special enough to break the rules. - Although practicality beats purity. - Errors should never pass silently. - Unless explicitly silenced. - In the face of ambiguity, refuse the temptation to guess. - There should be one-- and preferably only one --obvious way to do it - Although that way may not be obvious at first unless you're Dutch. - Now is better than never. - Although never is often better than *right* now. - If the implementation is hard to explain, it's a bad idea. - If the implementation is easy to explain, it may be a good idea. - Namespaces are one honking great idea -- let's do more of those! -] - -[page:1 Call Policies] - -In C++, we often deal with arguments and return types such as pointers -and references. Such primitive types are rather, ummmm, low level and -they really don't tell us much. At the very least, we don't know the -owner of the pointer or the referenced object. No wonder languages -such as Java and Python never deal with such low level entities. In -C++, it's usually considered a good practice to use smart pointers -which exactly describe ownership semantics. Still, even good C++ -interfaces use raw references and pointers sometimes, so Boost.Python -must deal with them. To do this, it may need your help. Consider the -following C++ function: - - X& f(Y& y, Z* z); - -How should the library wrap this function? A naive approach builds a -Python X object around result reference. This strategy might or might -not work out. Here's an example where it didn't - - >>> x = f(y, z) # x refers to some C++ X - >>> del y - >>> x.some_method() # CRASH! - -What's the problem? - -Well, what if f() was implemented as shown below: - - X& f(Y& y, Z* z) - { - y.z = z; - return y.x; - } - -The problem is that the lifetime of result X& is tied to the lifetime -of y, because the f() returns a reference to a member of the y -object. This idiom is is not uncommon and perfectly acceptable in the -context of C++. However, Python users should not be able to crash the -system just by using our C++ interface. In this case deleting y will -invalidate the reference to X. We have a dangling reference. - -Here's what's happening: - -# [^f] is called passing in a reference to [^y] and a pointer to [^z] -# A reference to [^y.x] is returned -# [^y] is deleted. [^x] is a dangling reference -# [^x.some_method()] is called -# [*BOOM!] - -We could copy result into a new object: - - >>> f(y, z).set(42) # Result disappears - >>> y.x.get() # No crash, but still bad - 3.14 - -This is not really our intent of our C++ interface. We've broken our -promise that the Python interface should reflect the C++ interface as -closely as possible. - -Our problems do not end there. Suppose Y is implemented as follows: - - struct Y - { - X x; Z* z; - int z_value() { return z->value(); } - }; - -Notice that the data member [^z] is held by class Y using a raw -pointer. Now we have a potential dangling pointer problem inside Y: - - >>> x = f(y, z) # y refers to z - >>> del z # Kill the z object - >>> y.z_value() # CRASH! - -For reference, here's the implementation of [^f] again: - - X& f(Y& y, Z* z) - { - y.z = z; - return y.x; - } - -Here's what's happening: - -# [^f] is called passing in a reference to [^y] and a pointer to [^z] -# A pointer to [^z] is held by [^y] -# A reference to [^y.x] is returned -# [^z] is deleted. [^y.z] is a dangling pointer -# [^y.z_value()] is called -# [^z->value()] is called -# [*BOOM!] - -[h2 Call Policies] - -Call Policies may be used in situations such as the example detailed above. -In our example, [^return_internal_reference] and [^with_custodian_and_ward] -are our friends: - - def("f", f, - return_internal_reference<1, - with_custodian_and_ward<1, 2> >()); - -What are the [^1] and [^2] parameters, you ask? - - return_internal_reference<1 - -Informs Boost.Python that the first argument, in our case [^Y& y], is the -owner of the returned reference: [^X&]. The "[^1]" simply specifies the -first argument. In short: "return an internal reference [^X&] owned by the -1st argument [^Y& y]". - - with_custodian_and_ward<1, 2> - -Informs Boost.Python that the lifetime of the argument indicated by ward -(i.e. the 2nd argument: [^Z* z]) is dependent on the lifetime of the -argument indicated by custodian (i.e. the 1st argument: [^Y& y]). - -It is also important to note that we have defined two policies above. Two -or more policies can be composed by chaining. Here's the general syntax: - - policy1 > > - -Here is the list of predefined call policies. A complete reference detailing -these can be found [@../../v2/reference.html#models_of_call_policies here]. - -* [*with_custodian_and_ward][br] Ties lifetimes of the arguments -* [*with_custodian_and_ward_postcall][br] Ties lifetimes of the arguments and results -* [*return_internal_reference][br] Ties lifetime of one argument to that of result -* [*return_value_policy with T one of:][br] -* [*reference_existing_object][br]naïve (dangerous) approach -* [*copy_const_reference][br]Boost.Python v1 approach -* [*copy_non_const_reference][br] -* [*manage_new_object][br] Adopt a pointer and hold the instance - -[blurb :-) [*Remember the Zen, Luke:][br][br] -"Explicit is better than implicit"[br] -"In the face of ambiguity, refuse the temptation to guess"[br]] - -[page:1 Overloading] - -The following illustrates a scheme for manually wrapping an overloaded -member functions. Of course, the same technique can be applied to wrapping -overloaded non-member functions. - -We have here our C++ class: - - struct X - { - bool f(int a) - { - return true; - } - - bool f(int a, double b) - { - return true; - } - - bool f(int a, double b, char c) - { - return true; - } - - int f(int a, int b, int c) - { - return a + b + c; - }; - }; - -Class X has 4 overloaded functions. We shall start by introducing some -member function pointer variables: - - bool (X::*fx1)(int) = &X::f; - bool (X::*fx2)(int, double) = &X::f; - bool (X::*fx3)(int, double, char)= &X::f; - int (X::*fx4)(int, int, int) = &X::f; - -With these in hand, we can proceed to define and wrap this for Python: - - .def("f", fx1) - .def("f", fx2) - .def("f", fx3) - .def("f", fx4) - -[page:1 Default Arguments] - -Boost.Python wraps (member) function pointers. Unfortunately, C++ function -pointers carry no default argument info. Take a function [^f] with default -arguments: - - int f(int, double = 3.14, char const* = "hello"); - -But the type of a pointer to the function [^f] has no information -about its default arguments: - - int(*g)(int,double,char const*) = f; // defaults lost! - -When we pass this function pointer to the [^def] function, there is no way -to retrieve the default arguments: - - def("f", f); // defaults lost! - -Because of this, when wrapping C++ code, we had to resort to manual -wrapping as outlined in the [@overloading.html previous section], or -writing thin wrappers: - - // write "thin wrappers" - int f1(int x) { f(x); } - int f2(int x, double y) { f(x,y); } - - /*...*/ - - // in module init - def("f", f); // all arguments - def("f", f2); // two arguments - def("f", f1); // one argument - -When you want to wrap functions (or member functions) that either: - -* have default arguments, or -* are overloaded with a common sequence of initial arguments - -[h2 BOOST_PYTHON_FUNCTION_OVERLOADS] - -Boost.Python now has a way to make it easier. For instance, given a function: - - int foo(int a, char b = 1, unsigned c = 2, double d = 3) - { - /*...*/ - } - -The macro invocation: - - BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4) - -will automatically create the thin wrappers for us. This macro will create -a class [^foo_overloads] that can be passed on to [^def(...)]. The third -and fourth macro argument are the minimum arguments and maximum arguments, -respectively. In our [^foo] function the minimum number of arguments is 1 -and the maximum number of arguments is 4. The [^def(...)] function will -automatically add all the foo variants for us: - - .def("foo", foo, foo_overloads()); - -[h2 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] - -Objects here, objects there, objects here there everywhere. More frequently -than anything else, we need to expose member functions of our classes to -Python. Then again, we have the same inconveniences as before when default -arguments or overloads with a common sequence of initial arguments come -into play. Another macro is provided to make this a breeze. - -Like [^BOOST_PYTHON_FUNCTION_OVERLOADS], -[^BOOST_PYTHON_FUNCTION_OVERLOADS] may be used to automatically create -the thin wrappers for wrapping member functions. Let's have an example: - - struct george - { - void - wack_em(int a, int b = 0, char c = 'x') - { - /*...*/ - } - }; - -The macro invocation: - - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3) - -will generate a set of thin wrappers for george's [^wack_em] member function -accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and -fourth macro argument). The thin wrappers are all enclosed in a class named -[^george_overloads] that can then be used as an argument to [^def(...)]: - - .def("wack_em", &george::wack_em, george_overloads()); - -See the [@../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec overloads reference] -for details. - -[h2 init and optional] - -A similar facility is provided for class constructors, again, with -default arguments or a sequence of overloads. Remember [^init<...>]? For example, -given a class X with a constructor: - - struct X - { - X(int a, char b = 'D', std::string c = "constructor", double d = 0.0); - /*...*/ - } - -You can easily add this constructor to Boost.Python in one shot: - - .def(init >()) - -Notice the use of [^init<...>] and [^optional<...>] to signify the default -(optional arguments). - -[page:1 Auto-Overloading] - -It was mentioned in passing in the previous section that -[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_FUNCTION_OVERLOADS] -can also be used for overloaded functions and member functions with a -common sequence of initial arguments. Here is an example: - - void foo() - { - /*...*/ - } - - void foo(bool a) - { - /*...*/ - } - - void foo(bool a, int b) - { - /*...*/ - } - - void foo(bool a, int b, char c) - { - /*...*/ - } - -Like in the previous section, we can generate thin wrappers for these -overloaded functions in one-shot: - - BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3) - -Then... - - .def("foo", foo, foo_overloads()); - -Notice though that we have a situation now where we have a minimum of zero -(0) arguments and a maximum of 3 arguments. - -[h2 Manual Wrapping] - -It is important to emphasize however that [*the overloaded functions must -have a common sequence of initial arguments]. Otherwise, our scheme above -will not work. If this is not the case, we have to wrap our functions -[@overloading.html manually]. - -Actually, we can mix and match manual wrapping of overloaded functions and -automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and -its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Following up on our example -presented in the section [@overloading.html on overloading], since the -first 4 overload functins have a common sequence of initial arguments, we -can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the -first three of the [^def]s and manually wrap just the last. Here's -how we'll do this: - - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4) - -Create a member function pointers as above for both X::f overloads: - - bool (X::*fx1)(int, double, char) = &X::f; - int (X::*fx2)(int, int, int) = &X::f; - -Then... - - .def("f", fx1, xf_overloads()); - .def("f", fx2) - -[page Object Interface] - -Python is dynamically typed, unlike C++ which is statically typed. Python -variables may hold an integer, a float, list, dict, tuple, str, long etc., -among other things. In the viewpoint of Boost.Python and C++, these -Pythonic variables are just instances of class [^object]. We shall see in -this chapter how to deal with Python objects. - -As mentioned, one of the goals of Boost.Python is to provide a -bidirectional mapping between C++ and Python while maintaining the Python -feel. Boost.Python C++ [^object]s are as close as possible to Python. This -should minimize the learning curve significantly. - -[$theme/python.png] - -[page:1 Basic Interface] - -Class [^object] wraps [^PyObject*]. All the intricacies of dealing with -[^PyObject]s such as managing reference counting are handled by the -[^object] class. C++ object interoperability is seamless. Boost.Python C++ -[^object]s can in fact be explicitly constructed from any C++ object. - -To illustrate, this Python code snippet: - - def f(x, y): - if (y == 'foo'): - x[3:7] = 'bar' - else: - x.items += y(3, x) - return x - - def getfunc(): - return f; - -Can be rewritten in C++ using Boost.Python facilities this way: - - object f(object x, object y) { - if (y == "foo") - x.slice(3,7) = "bar"; - else - x.attr("items") += y(3, x); - return x; - } - object getfunc() { - return object(f); - } - -Apart from cosmetic differences due to the fact that we are writing the -code in C++, the look and feel should be immediately apparent to the Python -coder. - -[page:1 Derived Object types] - -Boost.Python comes with a set of derived [^object] types corresponding to -that of Python's: - -* list -* dict -* tuple -* str -* long_ -* enum - -These derived [^object] types act like real Python types. For instance: - - str(1) ==> "1" - -Wherever appropriate, a particular derived [^object] has corresponding -Python type's methods. For instance, [^dict] has a [^keys()] method: - - d.keys() - -[^make_tuple] is provided for declaring ['tuple literals]. Example: - - make_tuple(123, 'D', "Hello, World", 0.0); - -In C++, when Boost.Python [^object]s are used as arguments to functions, -subtype matching is required. For example, when a function [^f], as -declared below, is wrapped, it will only accept instances of Python's -[^str] type and subtypes. - - void f(str name) - { - object n2 = name.attr("upper")(); // NAME = name.upper() - str NAME = name.upper(); // better - object msg = "%s is bigger than %s" % make_tuple(NAME,name); - } - -In finer detail: - - str NAME = name.upper(); - -Illustrates that we provide versions of the str type's methods as C++ -member functions. - - object msg = "%s is bigger than %s" % make_tuple(NAME,name); - -Demonstrates that you can write the C++ equivalent of [^"format" % x,y,z] -in Python, which is useful since there's no easy way to do that in std C++. - -__alert__ [*Beware] the common pitfall of forgetting that the constructors -of most of Python's mutable types make copies, just as in Python. - -Python: - - >>> d = dict(x.__dict__) # copies x.__dict__ - >>> d['whatever'] # modifies the copy - -C++: - - dict d(x.attr("__dict__")); # copies x.__dict__ - d['whatever'] = 3; # modifies the copy - -[h2 class_ as objects] - -Due to the dynamic nature of Boost.Python objects, any [^class_] may -also be one of these types! The following code snippet wraps the class -(type) object. - -We can use this to create wrapped instances. Example: - - object vec345 = ( - class_("Vec2", init()) - .def_readonly("length", &Point::length) - .def_readonly("angle", &Point::angle) - )(3.0, 4.0); - - assert(vec345.attr("length") == 5.0); - -[page:1 Extracting C++ objects] - -At some point, we will need to get C++ values out of object instances. This -can be achieved with the [^extract] function. Consider the following: - - double x = o.attr("length"); // compile error - -In the code above, we got a compiler error because Boost.Python -[^object] can't be implicitly converted to [^double]s. Instead, what -we wanted to do above can be achieved by writing: - - double l = extract(o.attr("length")); - Vec2& v = extract(o); - assert(l == v.length()); - -The first line attempts to extract the "length" attribute of the -Boost.Python [^object] [^o]. The second line attempts to ['extract] the -[^Vec2] object from held by the Boost.Python [^object] [^o]. - -Take note that we said "attempt to" above. What if the Boost.Python -[^object] [^o] does not really hold a [^Vec2] type? This is certainly -a possibility considering the dynamic nature of Python [^object]s. To -be on the safe side, if the C++ type can't be extracted, an -appropriate exception is thrown. To avoid an exception, we need to -test for extractibility: - - extract x(o); - if (x.check()) { - Vec2& v = x(); ... - -__tip__ The astute reader might have noticed that the [^extract] -facility in fact solves the mutable copying problem: - - dict d = extract(x.attr("__dict__")); - d['whatever'] = 3; # modifies x.__dict__ ! - - -[page:1 Enums] - -Boost.Python has a nifty facility to capture and wrap C++ enums. While -Python has no [^enum] type, we'll often want to expose our C++ enums to -Python as an [^int]. Boost.Python's enum facility makes this easy while -taking care of the proper conversions from Python's dynamic typing to C++'s -strong static typing (in C++, ints cannot be implicitly converted to -enums). To illustrate, given a C++ enum: - - enum choice { red, blue }; - -the construct: - - enum_("choice") - .value("red", red) - .value("blue", blue) - ; - -can be used to expose to Python. The new enum type is created in the -current [^scope()], which is usually the current module. The snippet above -creates a Python class derived from Python's [^int] type which is -associated with the C++ type passed as its first parameter. - -[blurb __detail__ [*what is a scope?][br][br] The scope is a class that has an -associated global Python object which controls the Python namespace in -which new extension classes and wrapped functions will be defined as -attributes. Details can be found [@../../v2/scope.html here].] - -You can access those values in Python as - - >>> my_module.choice.red - my_module.choice.red - -where my_module is the module where the enum is declared. You can also -create a new scope around a class: - - scope in_X = class_("X") - .def( ... ) - .def( ... ) - ; - - // Expose X::nested as X.nested - enum_("nested") - .value("red", red) - .value("blue", blue) - ; - -[page Iterators] - -In C++, and STL in particular, we see iterators everywhere. Python also has -iterators, but these are two very different beasts. - -[*C++ iterators:] - -* C++ has 5 type categories (random-access, bidirectional, forward, input, output) -* There are 2 Operation categories: reposition, access -* A pair of iterators is needed to represent a (first/last) range. - -[*Python Iterators:] - -* 1 category (forward) -* 1 operation category (next()) -* Raises StopIteration exception at end - -The typical Python iteration protocol: [^[*for y in x...]] is as follows: - - iter = x.__iter__() # get iterator - try: - while 1: - y = iter.next() # get each item - ... # process y - except StopIteration: pass # iterator exhausted - -Boost.Python provides some mechanisms to make C++ iterators play along -nicely as Python iterators. What we need to do is to produce -appropriate __iter__ function from C++ iterators that is compatible -with the Python iteration protocol. For example: - - object get_iterator = iterator >(); - object iter = get_iterator(v); - object first = iter.next(); - -Or for use in class_<>: - - .def("__iter__", iterator >()) - -[*range] - -We can create a Python savvy iterator using the range function: - -* range(start, finish) -* range(start, finish) - -Here, start/finish may be one of: - -* member data pointers -* member function pointers -* adaptable function object (use Target parameter) - -[*iterator] - -* iterator() - -Given a container [^T], iterator is a shortcut that simply calls [^range] -with &T::begin, &T::end. - -Let's put this into action... Here's an example from some hypothetical -bogon Particle accelerator code: - - f = Field() - for x in f.pions: - smash(x) - for y in f.bogons: - count(y) - -Now, our C++ Wrapper: - - class_("Field") - .property("pions", range(&F::p_begin, &F::p_end)) - .property("bogons", range(&F::b_begin, &F::b_end)); - -[page Exception Translation] - -All C++ exceptions must be caught at the boundary with Python code. This -boundary is the point where C++ meets Python. Boost.Python provides a -default exception handler that translates selected standard exceptions, -then gives up: - - raise RuntimeError, 'unidentifiable C++ Exception' - -Users may provide custom translation. Here's an example: - - struct PodBayDoorException; - void translator(PodBayDoorException const& x) { - PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave..."); - } - BOOST_PYTHON_MODULE(kubrick) { - register_exception_translator< - PodBayDoorException>(translator); - ... - diff --git a/doc/tutorial/doc/theme/alert.gif b/doc/tutorial/doc/theme/alert.gif deleted file mode 100644 index 270764cc58716d36f8545c07ffbccb76a3dbc7f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 577 zcmZ?wbhEHb6krfwc*el+^5x4HFJ3%)^yuNkhj;GW`TvCB_N{CGA2IyD%W(C|x&OBr z{@-G_a_Q{m__~8F~vDYEl>qqZpDSjq@WJa>5z1Lm6Vd z86rG+L!23`^cb|27{rAb*jO1D7#RNl{|}<5jTL{gu!=AwGw6T}2E_>j`@DwarsiZ7 zvzCqy8~4s$Mnes@-VRGi5tqr$%yz7-+I%yUbrd6_%=Konm?$SD`KoeGb{17nO!DDy z>t(PKkWWZ*<cQAmnAE=fsD%$UE$ROUW+NUZ1+QQKJ-!ms2) z!wk-f=<_sLpE#kg){9r_k3+JcmI}v|3yP=3Bn5<=JQ5$B644M)RP)^A(&gG6!^Fs7 F4FJH#(p~@n diff --git a/doc/tutorial/doc/theme/arrow.gif b/doc/tutorial/doc/theme/arrow.gif deleted file mode 100644 index e33db0fb4dd85e0fe527343d95a3f28a0ebb74f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70 zcmZ?wbhEHb6lLIGn8?8J9}E~6W->4^DE?&OC-XFJFH7^5yH-udiOcdjJ0Y=g*&CzkdDw`}cS6-hKG+ zVdct|pFVy1_U+rhfB)XRdGq$|+aEuEeEj(F|NsB1R;~K`_wVY}tN;A@vu4ej6)RT! z{{8#cuU~7|u3fio-TL+GfByWrapT4f8#Zj(v}yC^&D*wZ+q!k@mMvR$@7{gjz=7@C zx9{A!bMM~0yLRo`vuDr#{rh+9*s*WlzC(u&9X)#V)TvV^Po6w- zyLay%Jb3Wz*|X1|Kfizf{+Tmpu3fwK^y$-^H*a3Qe*M|AXXnnHJAeNCg$oysA3uKe z>eWk^E+4<0lBLU*@T^?5dd(`K^&2*BTFEI`2zd3>o;z)v)s9R@BSUeM~|O8Wn_5q^405CHt*hl`1r~B%hzw;zdQW;{pasr zF9v2V8Hs|fgUuYmej5*MSa`TSY=y@hkBv&AY7)j-cRDt)dE zU9$D{^$pSTGkte&%f01a^!nae>+L=F4>WVj`|WA_`1r(RZF9M$J3l|aF#GrnzrDM@ zzP^$C;>NkXyT8BJIMglgzi&_FC%sFnlY$n!TsEid z)yw4z+N54FEt!_}YUPS$t6r^IvuM`A)fY$|rssS*xogRqPp5XWJpOdrfW7(58I$WZ zJ;oN#*L*&AD&X$RBj zw_mR(wCjGmkup8^+s%ySYroyf+5Yz1?SkXF-|v)M&;5S4;`!R|_iFabaxho}0O~&E Au>b%7 diff --git a/doc/tutorial/doc/theme/bkd2.gif b/doc/tutorial/doc/theme/bkd2.gif deleted file mode 100644 index b03d9ba97ca7a4c4de297b5413fd3d3df8e0fb49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2543 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 diff --git a/doc/tutorial/doc/theme/bulb.gif b/doc/tutorial/doc/theme/bulb.gif deleted file mode 100644 index 74f3baac42f12ac0551040a00f78cb573360a0ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 944 zcmZ?wbhEHbU2JX=yWO8qb`WHgo38Gifu=q@6jF_W#UGhBGsb&&*6a zGjrydnP<+-{D0;Q!i=IrIPje+GvC495Q% z(*85d1W7Xd|8LCj-`M!SaoT_5nIN^s|No~k{7*CfpO*GNZ6-)-+W-GE8UD{S{y#JA z|IC>nlV<+^e}>`z8RP$8cYq8A8~y)3Nb~>yAnE^L0P?^n9t{C$ zm!W3VRz=HX0SO5P1_s5SEQ|~c3=BFT0%V2*i>ts1&-4h1-QU}6JQPJ#9Az#qP{_IL z>m8xcQ#>ccK&B>uvC-M7@I$1?63NFG4AfGLn>kr6)<~>7uC&oZb>E%VNA7Gc3=Gx) DZ>u*X diff --git a/doc/tutorial/doc/theme/c++boost.gif b/doc/tutorial/doc/theme/c++boost.gif deleted file mode 100644 index 58be431a3fafbd5adfa01e829ce8d80a03a83ed0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8819 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 diff --git a/doc/tutorial/doc/theme/jam.png b/doc/tutorial/doc/theme/jam.png deleted file mode 100644 index 224ed7914bb5a31a407511093500aa1fe9d9e571..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3884 zcmeAS@N?(olHy`uVBq!ia0y~yV5nzcU~uJNV_;xNjW#hE=bLrwBlWk7u9BNWG%WIzG^?ia{Jx0?d2cu65lo_tIq4R{ZpB|^Gj6) zSQHbUotHf@zxm;v$tNPW%s1Luc2<|6?FW0^VrZqF7Q%Y`1Ew|lr=xYj$EHQEz3mDMmMpd z>ejiX)97pynn`5kW z|CRi$_`uF-U0Tl!|N5S1TOOPDXU~o+TYOinI`YoqQ_`=^1)VOOpVS2UPMZHtf92(U zF(~lpmyJ~=b>FwfdM6w>w@64vPjkD9T!BlS8{-PeFW+C~FR$XwJ;(0LL4_y0b2(bBrxt6b;~fkM&QareVtIlX>mx{c)k=f}URyJiaR zcRjOF;pM%D1^TaQcvl$+gnzii-F1xrciDrp+t{xBlnQwM`lzw)`c>DOBDhY4PWZnt zR)FQek=PkocKsFVcH$fQ_AtJdIN(>n{=t*q-~sQq@h3+fzfG`F{L=O>KV|n{Gpl%-%i!=JgyXArJMZ($hYaT!{XP6Jj;Fo) z|Aw2nSEX5*73

m`0On#VPL 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 diff --git a/doc/tutorial/doc/theme/note.gif b/doc/tutorial/doc/theme/note.gif deleted file mode 100644 index bd92f07555d06e0744b408acc0fbf463e280f2f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 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 U=h+`HFfcH9y85}Sb4q9e0E&RLWB>pF diff --git a/doc/tutorial/doc/theme/r_arr.gif b/doc/tutorial/doc/theme/r_arr.gif deleted file mode 100644 index 2dcdad117debc34257b746cbe843bf5ca8737b59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#&gTE>G6muSe93zS-%fd>Q)&EUbx3v}%NcRk;>%V0Cvz}Z0{|MoM2G+Y diff --git a/doc/tutorial/doc/theme/r_arr_disabled.gif b/doc/tutorial/doc/theme/r_arr_disabled.gif deleted file mode 100644 index 2100f78bf35a47e09ca76ffcc6e80c5a2b11e359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91 zcmZ?wbhEHb6k!l%n8?5|bLPzZ_wWDz|DS<@LGdRGs|W)VgAM}&0|Q8&fk|gd|H|rv v@(cz3o}Svfg4O3$GVLgQHgm3)*?|1&XIvGFi0itr1TiFoeP&p1C|3gi5M|Dy8)Dq>pVFYM_y+=U^T ztHBMdj+tQ(A2Y*wF$RYE_4D-@jtU##9xMTW{_9v6c`wK7#J8B1sE6<80-`n z7><}aTg5mA1O&%;g!uX}*f26MGK54pa~u~3ne&L_xcGT71qKC%`|QWX?G$<#K=P%G z=f$!jvLf=G=8H2hFfyd8*(n?_D`m7(uv4gs=yaGbo~{-bxlJUa@tDY4zP5<9g6(Q8 z@$VV#2iy??g*_vVXy`OS*Qv? diff --git a/doc/tutorial/doc/theme/style.css b/doc/tutorial/doc/theme/style.css deleted file mode 100644 index 53a6205e..00000000 --- a/doc/tutorial/doc/theme/style.css +++ /dev/null @@ -1,170 +0,0 @@ -body -{ - background-image: url(bkd.gif); - background-color: #FFFFFF; - margin: 1em 2em 1em 2em; -} - -h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; } -h2 { font: 140% sans-serif; font-weight: bold; text-align: left; } -h3 { font: 120% sans-serif; font-weight: bold; text-align: left; } -h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; } -h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; } -h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; } - -pre -{ - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-top: 2pt; - padding-right: 2pt; - padding-left: 2pt; - padding-bottom: 2pt; - - display: block; - font-family: "courier new", courier, mono; - background-color: #eeeeee; font-size: small -} - -code -{ - font-family: "Courier New", Courier, mono; - font-size: small -} - -tt -{ - display: inline; - font-family: "Courier New", Courier, mono; - color: #000099; - font-size: small -} - -p -{ - text-align: justify; - font-family: Georgia, "Times New Roman", Times, serif -} - -ul -{ - list-style-image: url(bullet.gif); - font-family: Georgia, "Times New Roman", Times, serif -} - -ol -{ - font-family: Georgia, "Times New Roman", Times, serif -} - -a -{ - font-weight: bold; - color: #003366; - text-decoration: none; -} - -a:hover { color: #8080FF; } - -.literal { color: #666666; font-style: italic} -.keyword { color: #000099} -.identifier {} -.comment { font-style: italic; color: #990000} -.special { color: #800040} -.preprocessor { color: #FF0000} -.string { font-style: italic; color: #666666} -.copyright { color: #666666; font-size: small} -.white_bkd { background-color: #FFFFFF} -.dk_grey_bkd { background-color: #999999} -.quotes { color: #666666; font-style: italic; font-weight: bold} - -.note_box -{ - display: block; - - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-right: 12pt; - padding-left: 12pt; - padding-bottom: 12pt; - padding-top: 12pt; - - font-family: Arial, Helvetica, sans-serif; - background-color: #E2E9EF; - font-size: small; text-align: justify -} - -.table_title -{ - background-color: #648CCA; - - font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; - font-weight: bold -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.table_cells -{ - background-color: #E2E9EF; - - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.toc -{ - DISPLAY: block; - background-color: #E2E9EF - font-family: Arial, Helvetica, sans-serif; - - border-top: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - border-right: gray 1pt solid; - - padding-top: 24pt; - padding-right: 24pt; - padding-left: 24pt; - padding-bottom: 24pt; -} - -.toc_title -{ - background-color: #648CCA; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - color: #FFFFFF; - font-weight: bold -} - -.toc_cells -{ - background-color: #E2E9EF; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -} - -div.logo -{ - float: right; -} - -.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } diff --git a/doc/tutorial/doc/theme/u_arr.gif b/doc/tutorial/doc/theme/u_arr.gif deleted file mode 100644 index ada3d6e043d2e4314a20d6783f2800f2f21d89c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#pCE@bTiY5O-A{7vV42g%c7%l^E8u0x - - -Using the interpreter - - - - - - - - - - -
- - Using the interpreter -
-
- - - - - - -
-

-As you probably already know, objects in Python are reference-counted. -Naturally, the PyObjects of the Python/C API are also reference-counted. -There is a difference however. While the reference-counting is fully -automatic in Python, the Python/C API requires you to do it - -by hand. This is -messy and especially hard to get right in the presence of C++ exceptions. -Fortunately Boost.Python provides the -handle class -template to automate the process.

-

Reference-counting handles

-There are two ways in which a function in the Python/C API can return a -PyObject*: as a borrowed reference or as a new reference. Which of -these a function uses, is listed in that function's documentation. The two -require slightely different approaches to reference-counting but both can -be 'handled' by Boost.Python.

-

-For a function returning a borrowed reference we'll have to tell the -handle that the PyObject* is borrowed with the aptly named - -borrowed function. Two functions -returning borrowed references are -PyImport_AddModule and -PyModule_GetDict. -The former returns a reference to an already imported module, the latter -retrieves a module's namespace dictionary. Let's use them to retrieve the -namespace of the __main__ module:

-
-    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
-    handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
-
-

-Because the Python/C API doesn't know anything about handles, we used -the -get member function to -retrieve the PyObject* from which the handle was constructed.

-

-For a function returning a new reference we can just create a handle -out of the raw PyObject* without wrapping it in a call to borrowed. One -such function that returns a new reference is -PyRun_String which we'll -discuss in the next section.

- - - - -
- Handle is a class template, so why haven't we been using any template parameters?
-
-handle has a single template parameter specifying the type of the managed object. This type is PyObject 99% of the time, so the parameter was defaulted to PyObject for convenience. Therefore we can use the shorthand handle<> instead of the longer, but equivalent, handle<PyObject>. -
-

Running Python code

-To run Python code from C++ there is a family of functions in the API -starting with the PyRun prefix. You can find the full list of these -functions -here. They -all work similarly so we will look at only one of them, namely:

-
-    PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
-
-

- -PyRun_String takes the code to execute as a null-terminated (C-style) -string in its str parameter. The function returns a new reference to a -Python object. Which object is returned depends on the start paramater.

-

-The start parameter is the start symbol from the Python grammar to use -for interpreting the code. The possible values are:

- - - -
-Start symbols
-Py_eval_inputfor interpreting isolated expressions
-Py_file_inputfor interpreting sequences of statements
-Py_single_inputfor interpreting a single statement
-

-When using -Py_eval_input, the input string must contain a single expression -and its result is returned. When using -Py_file_input, the string can -contain an abitrary number of statements and None is returned. - -Py_single_input works in the same way as -Py_file_input but only accepts a -single statement.

-

-Lastly, the globals and locals parameters are Python dictionaries -containing the globals and locals of the context in which to run the code. -For most intents and purposes you can use the namespace dictionary of the -__main__ module for both parameters.

-

-We have already seen how to get the __main__ module's namespace so let's -run some Python code in it:

-
-    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
-    handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
-    handle<>( PyRun_String("hello = file('hello.txt', 'w')\n"
-                           "hello.write('Hello world!')\n"
-                           "hello.close()", Py_file_input,
-                           main_namespace.get(), main_namespace.get()) );
-
-

-This should create a file called 'hello.txt' in the current directory -containing a phrase that is well-known in programming circles.

-

- Note that we wrap the return value of -PyRun_String in a -(nameless) handle even though we are not interested in it. If we didn't -do this, the the returned object would be kept alive unnecessarily. Unless -you want to be a Dr. Frankenstein, always wrap PyObject*s in handles.

-

Beyond handles

-It's nice that handle manages the reference counting details for us, but -other than that it doesn't do much. Often we'd like to have a more useful -class to manipulate Python objects. But we have already seen such a class -in the -previous section: the aptly named object -class and it's derivatives. What we haven't seen, is that they can be -constructed from a handle. The following examples should illustrate this -fact:

-
-    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
-    main_namespace dict(handle<>(borrowed( PyModule_GetDict(main_module.get()) )));
-    handle<>( PyRun_String("result = 5 ** 2", Py_file_input,
-                           main_namespace.ptr(), main_namespace.ptr()) );
-    int five_squared = extract<int>( main_namespace["result"] );
-
-

-Here we create a dictionary object for the __main__ module's namespace. -Then we assign 5 squared to the result variable and read this variable from -the dictionary. Another way to achieve the same result is to let - -PyRun_String return the result directly with -Py_eval_input:

-
-    object result(handle<>( PyRun_String("5 ** 2", Py_eval_input,
-                                         main_namespace.ptr(), main_namespace.ptr()) ));
-    int five_squared = extract<int>(result);
-
-

- Note that object's member function to return the wrapped -PyObject* is called ptr instead of get. This makes sense if you -take into account the different functions that object and handle -perform.

-

Exception handling

-If an exception occurs in the execution of some Python code, the -PyRun_String function returns a null pointer. Constructing a handle out of this null pointer throws -error_already_set, so basically, the Python exception is automatically translated into a C++ exception when using handle:

-
-    try
-    {
-        object result(handle<>( PyRun_String("5/0", Py_eval_input,
-                                             main_namespace.ptr(), main_namespace.ptr()) ));
-        // execution will never get here:
-        int five_divided_by_zero = extract<int>(result);
-    }
-    catch(error_already_set)
-    {
-        // handle the exception in some way
-    }
-
-

-The error_already_set exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the -exception handling functions of the Python/C API in your catch-statement. This can be as simple as calling -PyErr_Print() to print the exception's traceback to the console, or comparing the type of the exception with those of the -standard exceptions:

-
-    catch(error_already_set)
-    {
-        if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
-        {
-            // handle ZeroDivisionError specially
-        }
-        else
-        {
-            // print all other errors to stderr
-            PyErr_Print();
-        }
-    }
-
-

-(To retrieve even more information from the exception you can use some of the other exception handling functions listed -here.)

-

-If you'd rather not have handle throw a C++ exception when it is constructed, you can use the -allow_null function in the same way you'd use borrowed:

-
-    handle<> result(allow_null( PyRun_String("5/0", Py_eval_input,
-                                             main_namespace.ptr(), main_namespace.ptr()) ));
-    if (!result)
-        // Python exception occurred
-    else
-        // everything went okay, it's safe to use the result
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/doc/virtual_functions_with_default_implementations.html b/doc/tutorial/doc/virtual_functions_with_default_implementations.html deleted file mode 100644 index f7b15115..00000000 --- a/doc/tutorial/doc/virtual_functions_with_default_implementations.html +++ /dev/null @@ -1,122 +0,0 @@ - - - -Virtual Functions with Default Implementations - - - - - - - - - - -
- - Virtual Functions with Default Implementations -
-
- - - - - - -
-

-Recall that in the -previous section, we -wrapped a class with a pure virtual function that we then implemented in -C++ or Python classes derived from it. Our base class:

-
-    struct Base
-    {
-        virtual int f() = 0;
-    };
-
-

-had a pure virtual function f. If, however, its member function f was -not declared as pure virtual:

-
-    struct Base
-    {
-        virtual int f() { return 0; }
-    };
-
-

-and instead had a default implementation that returns 0, as shown above, -we need to add a forwarding function that calls the Base default virtual -function f implementation:

-
-    struct BaseWrap : Base
-    {
-        BaseWrap(PyObject* self_)
-            : self(self_) {}
-        int f() { return call_method<int>(self, "f"); }
-        int default_f() { return Base::f(); } // <<=== ***ADDED***
-        PyObject* self;
-    };
-
-

-Then, Boost.Python needs to keep track of 1) the dispatch function f and -2) the forwarding function to its default implementation default_f. -There's a special def function for this purpose. Here's how it is -applied to our example above:

-
-    class_<Base, BaseWrap>("Base")
-        .def("f", &Base::f, &BaseWrap::default_f)
-
-

-Note that we are allowing Base objects to be instantiated this time, -unlike before where we specifically defined the class_<Base> with -no_init.

-

-In Python, the results would be as expected:

-
-    >>> base = Base()
-    >>> class Derived(Base):
-    ...     def f(self):
-    ...         return 42
-    ...
-    >>> derived = Derived()
-
-

-Calling base.f():

-
-    >>> base.f()
-    0
-
-

-Calling derived.f():

-
-    >>> derived.f()
-    42
-
-

-Calling call_f, passing in a base object:

-
-    >>> call_f(base)
-    0
-
-

-Calling call_f, passing in a derived object:

-
-    >>> call_f(derived)
-    42
-
- - - - - - -
-
-
- - diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html deleted file mode 100644 index eaeffa03..00000000 --- a/doc/tutorial/index.html +++ /dev/null @@ -1,156 +0,0 @@ - - - -Boost Python Tutorial - - - - - - - - - -
- - Boost Python Tutorial -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table of contents
- QuickStart -
- Building Hello World -
- Exposing Classes -
- Constructors -
- Class Data Members -
- Class Properties -
- Inheritance -
- Class Virtual Functions -
- Deriving a Python Class -
- Virtual Functions with Default Implementations -
- Class Operators/Special Functions -
- Functions -
- Call Policies -
- Overloading -
- Default Arguments -
- Auto-Overloading -
- Object Interface -
- Basic Interface -
- Derived Object types -
- Extracting C++ objects -
- Enums -
- Embedding -
- Using the interpreter -
- Iterators -
- Exception Translation -
-
-
- - diff --git a/doc/v2/Apr2002.html b/doc/v2/Apr2002.html deleted file mode 100644 index 1f2853c0..00000000 --- a/doc/v2/Apr2002.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - -Boost.Python - April 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

April 2002 Progress Report

-
-
-

Contents

-
-
Accomplishments
-
-
Arbitrary Arity Support
-
New Callback Interface
-
Call Policies for Construtors
-
Real Users, Real Bugs
-
New Insights
-
Boost.Python V1 Maintenance
-
- -
What's Missing
- -
- -

Accomplishments

- -April was a short month as far as Boost.Python was concerned, since -the spring ISO C++ Committee Meeting (and associated vacation) -occupied me for the 2nd half of the month. However, a suprising amount -of work got done... - -

Arbitrary Arity Support

- -I began using the Boost.Preprocessor -metaprogramming library to generate support for functions and member -functions of arbitrary arity, which was, to say the least, quite an -adventure. The feedback cycle resulting from my foray into -Boost.Preprocessor resulted in several improvements to the library, -most notably in its documentation. - -

- -Boost.Python now supports calls of up to 17 arguments on most -compilers. Because most EDG-based compilers have dismal preprocessor -performance, I had to "manually" expand the metaprograms for -arities from zero to fifteen arguments, and EDG-based compilers with -__EDG_VERSION__ <= 245 only support 15 -arguments by default. If some crazy program finds a need for more than -the default arity support, users can increase the base support by -setting the BOOST_PYTHON_MAX_ARITY preprocessor symbol. - -

New Callback Interface

- -I mentioned in last month's report that I -wasn't pleased with the interface for the interface for calling into -Python, so now it has been redesigned. The new interface is outlined -in this -message (though the GCC 2.95.3 bugs have been fixed). - -

Call Policies for Constructors

- -On April 2nd, I announced -support for the use of call policies with constructors. - -

Real Users, Real Bugs

- -At least two people outside of Kull began actually using Boost.Python -v2 in earnest this month. Peter Bienstman and Pearu Pearson both -provided valuable real-world bug reports that helped me to improve the -library's robustness. - -

New Insights

- -Answering some of Pearu's questions about explicitly converting -objects between Python and C++ actually led me to a new understanding -of the role of the current conversion facilities. In Boost.Python v1, -all conversions between Python and C++ were handled by a single family -of functions, called to_python() and -from_python(). Since the primary role of Boost.Python is -to wrap C++ functions in Python, I used these names for the first kind -of converters I needed: those that extract C++ objects to be used as -function arguments and which C++ function return values to -Python. The better-considered approach in Boost.Python v2 uses a -completely different mechanism for conversions used when calling -Python from C++, as in wrapped virtual function implementations. I -usually think of this as a "callback", as in "calling -back into Python", and I named the converters used in callbacks -accordingly: to_python_callback and -from_python_callback. However, as it turns out, the -behavior of the "callback" converters is the appropriate one -for users who want to explicitly extract a C++ value from a Python -object, or create a Python object from a C++ value. The upshot is that -it probably makes sense to change the name of the existing to_python and -from_python so those names are available for the -user-friendly explicit converters. - -

-Another -of Pearu's questions pushes momentum further in the direction of a -more-sophisticated overloading mechanism than the current -simple-minded "first match" approach, as I suggested last month. - -

Boost.Python V1 Maintenance

- -As much as I'm looking forward to retiring Boost.Python v1, a -significant amount of effort has been being spent dealing with support -problems; the saying that code rots when left alone is true, and -Boost.Python is no exception. Eventually it became obvious to me that -we were going to have to invest some effort in keeping V1 healthy -while working on V2. Ralf and I have expanded support for various -compilers and stabilized the V1 codebase considerably. We discarded -the obsolete Visual Studio projects which were causing so much -confusion. Still to do before the next Boost release: -
    -
  1. Update the build/test documentation with detailed instructions for -configuring various toolsets. -
  2. Provide some links to Boost.Python v2 to let people know what's -coming. -
- - -

What's Missing

- -Last month I announced that I would implement the following which are -not yet complete: -
    -
  1. Document all implemented features -
  2. Implement conversions for char types. This is -implemented but not tested, so we have to assume it doesn't work. -
- -These are my first priority for this month (especially the -documentation). - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/CallPolicies.html b/doc/v2/CallPolicies.html deleted file mode 100644 index 09877c5d..00000000 --- a/doc/v2/CallPolicies.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - Boost.Python - CallPolicies Concept - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

CallPolicies Concept

-
-
- -
-
Introduction
- -
CallPolicies Composition
- -
Concept Requirements
- -
-
-
CallPolicies Concept
-
-
-
- -

Introduction

- -

Models of the CallPolicies concept are used to specialize the behavior - of Python callable objects generated by Boost.Python to wrapped C++ - objects like function and member function pointers, providing three - behaviors:

- -
    -
  1. precall - Python argument tuple management before the - wrapped object is invoked
  2. - -
  3. result_converter - C++ return value handling
  4. - -
  5. postcall - Python argument tuple and result management - after the wrapped object is invoked
  6. -
- -

CallPolicies Composition

- In order to allow the use of multiple models of CallPolicies in the same - callable object, Boost.Python's CallPolicies class templates provide a - chaining interface which allows them to be recursively composed. This - interface takes the form of an optional template parameter, - Base which defaults to default_call_policies. - By convention, the precall function of the Base - is invoked after the precall function supplied by the - outer template, and the postcall function of the - Base is invoked before the postcall - function of the outer template. If a result_converter is - supplied by the outer template, it replaces any - result_converter supplied by the Base. For an - example, see return_internal_reference. - - -

Concept Requirements

- -

CallPolicies Concept

- -

In the table below, x denotes an object whose type - P is a model of CallPolicies, a - denotes a PyObject* pointing to a Python argument tuple - object, and r denotes a PyObject* - referring to a "preliminary" result object.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ExpressionTypeResult/Semantics
x.precall(a)convertible to boolreturns false and PyErr_Occurred() != 0 - upon failure, true otherwise.
P::result_converterA model of ResultConverterGenerator.An MPL unary Metafunction - Class used produce the "preliminary" result object.
x.postcall(a, r)convertible to PyObject*0 0 and PyErr_Occurred() != 0 - upon failure. Must "conserve references" even in the event of an - exception. In other words, if r is not returned, its - reference count must be decremented; if another existing object is - returned, its reference count must be incremented.
- Models of CallPolicies are required to be CopyConstructible. -
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- -

Permission to copy, use, modify, sell and distribute this software is - granted provided this copyright notice appears in all copies. This - software is provided "as is" without express or implied warranty, and - with no claim as to its suitability for any purpose.

- - - diff --git a/doc/v2/Dereferenceable.html b/doc/v2/Dereferenceable.html deleted file mode 100644 index fdea0fc0..00000000 --- a/doc/v2/Dereferenceable.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -Boost.Python - Dereferenceable Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

Dereferenceable Concept

-
-
-
-
Introduction
-
Concept Requirements
-
-
Dereferenceable Concept
-
-
- -

Introduction

- -

Instances of a dereferenceable type can be used like a pointer to access an lvalue. - -

Concept Requirements

-

Dereferenceable Concept

- -

In the table below, x denotes an object whose -type is a model of Dereferenceable. - - - - - - - - - - - -
ExpressionRequirements
*xAn lvalue -
- -If x is not a pointer type, it also must satsify the following expression: - - - - - - - - - - - -
ExpressionOperational Semantics
x.get()&*x, or a null pointer -
- -


-

Revised - - 29 November, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/Extractor.html b/doc/v2/Extractor.html deleted file mode 100755 index c28f5f58..00000000 --- a/doc/v2/Extractor.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - -Boost.Python - Extractor Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

Extractor Concept

-
-


-
-
Introduction
-
Concept Requirements
-
-
Extractor Concept
-
-
Notes
-
- -

Introduction

- -

An Extractor is a class which Boost.Python can use to extract C++ -objects from Python objects, and is typically used by facilities that -define from_python conversions for -"traditional" Python extension types. - -

Concept Requirements

-

Extractor Concept

- -

In the table below, X denotes a model of -Extractor and a denotes an instance of a Python -object type. - - - - - - - - - - - - - - - - - - -
ExpressionTypeSemantics
X::execute(a)non-void - Returns the C++ object being extracted. The - execute function must not be overloaded. -
&a.ob_type - PyTypeObject** - Points to the ob_type field of an object which is - layout-compatible with PyObject -
- -

Notes

- -Informally, an Extractor's execute member must be a -non-overloaded static function whose single argument is a Python -object type. Acceptable Python object types include those publicly (and -unambiguously) derived from PyObject, and POD types which -are layout-compatible with PyObject. - -
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/HolderGenerator.html b/doc/v2/HolderGenerator.html deleted file mode 100755 index 34634798..00000000 --- a/doc/v2/HolderGenerator.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - -Boost.Python - Holder Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

HolderGenerator Concept

-
-


-
-
Introduction
-
Concept Requirements
-
-
HolderGenerator Concept
-
-
- -

Introduction

- -

A HolderGenerator is a unary metafunction class which returns types -suitable for holding instances of its argument in a wrapped C++ class -instance. - -

Concept Requirements

-

HolderGenerator Concept

- -

In the table below, G denotes an type which -models HolderGenerator, and X denotes a class -type. - - - - - - - - - - - -
ExpressionRequirements
G::apply<X>::typeA concrete subclass of instance_holder - which can hold objects of type X. -
- -


-

Revised - - 13 November, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/Jun2002.html b/doc/v2/Jun2002.html deleted file mode 100644 index 9c396ed7..00000000 --- a/doc/v2/Jun2002.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - -Boost.Python - June 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

June 2002 Progress Report

-
-


-

Contents

-
-
Introduction
-
handle<T>
-
object
-
-
object operators
-
object conversions
-
-
list
-
Numerics
-
Community
-
What's Next
-
- -

Introduction

- -July was mostly focused on allowing expressive manipulation of -individual Python objects, or what Ralf Grosse-Kunstleve calls -"Writing Python in C++". The work began with this posting, -which outlines the issues and intention. - -

handle<T>

- -The most basic element needed was a replacement for the -reference<> class template and the -ref typedef from Boost.Python v1, a simple smart -pointer to a Python object. The old v1 typedef -"ref" (for -reference<PyObject>) had to be retired because I -thought it would be too confusing given the importance of boost::ref() to this -library. I began a discussionof -possible names, and it was eventually decided -to rename reference to handle and supply a -default argument so that ref could be spelled -handle<> without an additional typedef. There -were also some interface changes to make it safer and more-efficient -to interface with the raw -PyObject*s forced on us by Python's 'C' API. A -discussion of those protocols can be found here. - -

object

- -It is intended that users will seldom need or want to work with -handle<>; its major distinguishing features are -that it gives direct access to the underlying object representation -through operator* and operator->, and -that can be NULL, both sources of danger. Instead the -library provides a class called object, which -encapsulates a valid Python object and provides a similar interface to -Python's. - -

object operators

- -The first challenge was to provide support for object manipulations -using a Python-like syntax, mostly in the form of operator overloads: - - - - - - - - - - - - - -
Python C++ - -
y = x.foo y = x.attr("foo"); -
x.foo = 1 x.attr("foo") = 1; - -
y = x[z] y = x[z]; -
x[z] = 1 x[z] = 1; - -
y = x[3:-1] y = x.slice(3,-1); - -
y = x[3:] y = x.slice(3,_); - -
y = x[:-2] y = x.slice(_,-2); - -
z = x(1, y) z = x(1, y); -
z = x.f(1, y) z = x.attr("f")(1, y); - -
not x !x - -
x and y x and y -
- -I'm still a unsatisfied with the interface for attribute access. There -original proposal used a syntax like this one: -
-y = x._("foo"); 
-x._("foo") = 1; 
-
- -which was only marginally better than what we've got. Niki Spahiev -then pointed -out a potential conflict with the macro which GNU Gettext suggests -people define. This unfortunate state of affairs forced us into using -attr instead. I'd still like to find a better interface, -but the lack of overloadable C++ operators which aren't already used -in Python is an obstacle. The comma operator is still a possibility, -but it has the wrong precedence: -
-y = x,"foo"    // error
-x,"foo" = 1;   // error
-
-y = (x,"foo"); // ok
-(x,"foo") = 1; // ok
-
- -Well, I guess we could consider adding that to the interface without -removing attr(), to see how it plays out... - -

object conversions

- -The object class also provided an opportunity to replace -Boost.Python v1's to_python() as a user-level -interface. Instead, object has a templated constructor -which can be used to convert any C++ object to Python using the same -underlying mechanisms used for the arguments to call<>. - -

Incidentally, the implementation of operator and conversion support -for object uncovered an inordinate number of compiler bugs in our -targeted platforms. It was a lot more "interesting" than it -should have been. - -

list

- -With object implemented, it was time to begin replacing -the ad-hoc implementations of list, string, -and dictionary supplied by Boost.Python v1 with something -more robust. I started with list as an example. Because -object already provides all of the requisite operators, -publicly deriving list from object seemed like a good -choice. The remaining issues were what do do about the one-argument -list constructor (which in Python attempts to convert its argument to -a list), and how to deal converting with list arguments -to wrapped functions. Some of the issues are laid out in this -thread. Ultimately, it was decided that list(x) -should do the same thing in C++ as in Python (conversion), while -list arguments should only match Python -lists (and list subclasses). The -implementation worked well, and provided a roadmap -for the protocol to be used for implementation of the other built-in -types. - -

Numerics

- -Support for C++ long long and unsigned long -long -(and __int64 on MSVC) to/from python conversions was -added this month. We also improved handling of numeric overflows when -converting, e.g., a Python int to a type with a more limited range of -representation. - -

Community

- - - -Deep thanks to all the Boost.Python contributors! This project -wouldn't be possible without your participation. - -

What's Next

- -As I write this we are already well into the month of July, so I -suggest you consult the Mailing -List Archive if you want to know what's been happening. Otherwise -you'll just have to wait till next month (hopefully the beginning). - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/Mar2002.html b/doc/v2/Mar2002.html deleted file mode 100644 index a8a165d8..00000000 --- a/doc/v2/Mar2002.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - -Boost.Python - March 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

March 2002 Progress Report

-
-
-

Contents

-
-
Accomplishments
-
-
Calling Python from C++
-
Virtual Functions
-
Abstract Classes
-
C++ Implicit Conversions
-
C++ Data Members
-
Miscellaneous
-
- -
The Near future
- -
Notes
- -
- -

Accomplishments

- -March was mostly devoted to the reimplementation of features from -Boost.Python v1, and some new features. Re-examination of the features -from Boost.Python v1 allowed me to make significant improvements. - -

Calling Python from C++

- -The ability to call Python from C++ is crucial for virtual function -support. Implementing this feature well for V2 proved to be more -interesting than I expected. You can review most of the relevant -design decisions -here. - -

-One point which isn't emphasized in that document is that there -are subtle differences in the way from_python conversions -work when used for C++ function arguments and Python function return -values. In particular, while T const& arguments may -invoke rvalue converters, a reference-to-const return value requires -an lvalue converter, since a temporary conversion result would leave -the returned reference dangling. - -

I'm not particularly pleased with the current callback interface, -since it usually results in constructs like: -

-return returning<X&>::call(f, obj);
-
-However, I think the following may be possible and I plan to investigate: -
-return apply<X&>(f, obj);
-
-I'm open to suggestion for better names (and syntaxes)! - -

Virtual Functions

- -Once Python callbacks were implemented, it was just a short step to -implementing virtual functions. Python extension class exposing a C++ -class whose virtual functions are overridable in Python must actually -hold a C++ instance of a class derived from the one exposed to -Python. Needing some way for users to specify that class, I added an -optional template argument to value_holder_generator and -pointer_holder_generator<> to specify the class -actually held. This move began to put pressure on the -class_<> interface, since the need for the user to -produce complicated instantations of -class_<> was increased: - -
-class<Foo, bases<>, value_holder_generator<Foo_callback> >("Foo")
-.def("hello", &Foo::hello)
-...
-
- -

Abstract Classes

- -Normally when a C++ class is exposed to Python, the library registers -a conversion function which allows users to wrap functions returning -values of that type. Naturally, these return values are temporaries, -so the conversion function must make a copy in some -dynamically-allocated storage (a "holder") which is managed -by the corresponding Python object. - -

Unfortunately, in the case of abstract classes (and other types -without a publicly-accessible copy constructor), instantiating this -conversion function causes a compilation error. In order to support -non-copyable classes, there had to be some way to prevent the library -from trying to instantiate the conversion function. The only practical -approach I could think of was to add an additional template parameter -to the class_<> interface. When the number of -template parameters with useful defaults begins to grow, it is often -hard to choose an order which allows users to take advantage of the -defaults. - -

- -This was the straw that broke the -class_<> interface's back and caused the redesign -whose outcome is detailed here. -The approach allows the user to supply the optional parameters in an -arbitrary order. It was inspired by the use of named -template parameters in the Boost Iterator Adaptor -Library, though in this case it is possible to deduce the meaning -of the template parameters entirely from their type properties, -resulting in a simpler interface. Although the move from a -policy-based design to what resembles a configuration DSL usually -implies a loss of flexibility, in this case I think any costs are far -outweighed by the advantages. - -

Note: working around the limitations of the various compilers I'm -supporting was non-trivial, and resulted in a few messy implementation -details. It might be a good idea to switch to a more-straightforward -approach once Metrowerks CodeWarrior Pro8 is released. - -

C++ Implicit Conversions

- -Support for C++ implicit conversion involves creating -from_python converters for a type U which in -turn use from_python converters registered for a type -T where there exists a implicit conversion from -T to U. The current implementation is -subject to two inefficiencies: -
    - -
  1. Because an rvalue from_python converter produces two -pieces of data (a function and a void*) from its -convertible() function, we end up calling the function -for T twice: once when the converter is looked up in the -registry, and again when the conversion is actually performed. - -
  2. A vector is used to mark the "visited" converters, preventing -infinite recursion as T to -U and U to T converters -continually search through one-another. - -
- -I consider the former to be a minor issue. The second may or may not -prove to be computationally significant, but I believe that -architecturally, it points toward a need for more sophisticated -overload resolution. It may be that we want CLOS-style multimethod -dispatching along with C++ style rules that prevent more than one -implicit conversion per argument. - -

C++ Data Members

- -To supply the ability to directly access data members, I was able to -hijack the new Python property -type. I had hoped that I would also be able to re-use the work of make_function to create callable python -objects from C++ functions which access a data member of a given -class. C++ facilities for specifying data member pointer non-type -template arguments require the user to explicitly specify the type of -the data member and this under-utilized feature is also not -well-implemented on all compilers, so passing the member pointer as a -runtime value is the only practical approach. The upshot is that any -such entity would actually have to be a function object, and I -haven't implemented automatic wrapping of C++ callable function -objects yet, so there is less re-use in the implementation than I'd -like. I hope to implement callable object wrapping and refactor this -code one day. I also hope to implement static data member support, -for which Python's property will not be an appropriate descriptor. - -

Miscellaneous

-
    -
  • Moved args<> and bases<> from unnamed namespace to boost::python in their own header files. -
  • Convert NULL pointers returned from wrapped C++ functions to None. -
  • Improved some compile-time error checks. -
  • Eliminated boost/python/detail/eval.hpp in favor of -more-general boost/mpl/apply.hpp. -
  • General code cleanup and refactoring. -
  • Works with Microsoft Visual C++ 7.0 -
  • Warning suppression for many compilers -
  • Elegant interface design for exporting enum types. -
-
- -

The Near Future

- -Before April 15th I plan to -
    -
  1. Document all implemented features -
  2. Implement a CallPolicy interface for constructors of wrapped -classes -
  3. Implement conversions for char types. -
  4. Implement automated code generation for all headers containing -families of overloaded functions to handle arbitrary arity. -
- -I also hope to implement a mechanism for generating conversions -between arbitrary Python sequences and C++ containers, if time permits -(and others haven't already done it)! - -

Notes

- -The older version of KCC used by Kull is generating lots of warnings -about a construct I use to instantiate static members of various class -templates. I'm thinking of moving to an idiom which uses a function -template to suppress it, but worry about bloating the size of debug -builds. Since KCC users may be moving to GCC, I'm not sure that it's -worth doing anything about it. - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/May2002.html b/doc/v2/May2002.html deleted file mode 100644 index b5eb4e4f..00000000 --- a/doc/v2/May2002.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - -Boost.Python - May 2002 Progress Report - - - - - - - -
-

-

-
-

Boost.Python

-

May 2002 Progress Report

-
-
-

Contents

-
-
Introduction
-
New Features
-
-
Shared Library Support for AIX
-
Class Enhancements
-
-
Operators
-
Iterators
-
Properties
-
setattr
-
__module__ Attribute
-
-
back_reference
-
- -
Documentation
-
Miscellaneous
-
-
Converters
-
Checkins Mailing List
-
Shared Libraries
-
- -
What's Next
-
- -

Introduction

- -Aside from library development, work on Boost.Python in May was -focused on reducing the support burden. In recent weeks, responding to -requests for support, espcially surrounding building the library, had -begun to impede progress on development. There was a major push to -release a stable 1.28.0 of Boost, including documentation of Boost.Build and specific -instructions for building Boost.Python -v1. The documentation for Boost.Python v2 was also updated as -described here. - -

New Features

- -

Shared Library Support for AIX

- - The Kull group required the ability to build and test Boost.Python - extensions on AIX, a platform with "creatively designed" - shared library semantics. Making this work was a multi-pronged - effort, involving changes to Boost.Build and some great research by - Martin Casado which uncovered the key mechanism required to allow - shared libraries to use functions from the Python executable. The - current solution used in Boost.Build relies on a Python - Script as part of the build process. This is not a problem for - Boost.Python, as Python will be available. However, the commands - issued by the script are so simple that a 100%-pure-Boost.Jam - solution is surely possible. Linking on AIX is sufficiently - interesting to have skewed the Boost.Python development schedule a - bit. - -

Class Enhancements

- -

Operators

- -Support for exposing C++ operators and functions as the corresponding -Python special methods was added. Thinking that the Boost.Python -v1 interface was a little too -esoteric (especially the use of -left_operand<...>/right_operand<...> for -asymmetric operands), I introduced a simple form of expression -templates which allow users to simply write the expressions that -should be wrapped, as in this example. - -

Iterators

- -Python iterator support as required by the Kull project resulted in a -highly flexible interface allowing: - -
- -
Direct exposure of a class' begin() and -end() functions: - -
-    ...
-    .def("__iter__", iterator<list_int>())
-
-
- -
Creation of iterators from member functions... -
-    ...
-    .def("__iter__"
-         , range(&my_class::x_begin, &my_class::x_end))
-    )
-
-
- -
...and member data: -
-    ...
-    .def("__iter__"
-         , range(&std::pair<char*,char*>::first, &std::pair<char*,char*>::second))
-    )
-
-
- -
The ability to specify CallPolicies, e.g. to prevent copying of -heavyweight values: - -
-    ...
-    .def("__iter__", 
-         , range<return_value_policy<copy_non_const_reference> >(
-               &my_sequence<heavy>::begin
-             , &my_sequence<heavy>::end))
-
-
- -
- -

Properties

- -The Kull iteration interfaces also required the ability to iterate -over a sequence specified by an instance's attribute: -
->>> f = field()
->>> for e in f.elements:
-...     print e,
-
- -This forced the exposure of the property - interface used internally to implement the data member exposure - facility described in March. Properties are an - incredibly useful idiom, so it's good to be able to provide them - at little new development cost. - -

setattr

- -class_<> acquired a setattr member -function which allows users to easily add new Python objects as class -attributes. - -

__module__ Attribute

- -Ralf Grosse-Kunstleve has been working on pickling support for v2. To -make it work correctly, he had to make sure that a class' -__module__ attribute was set correctly. - -

back_reference

- -The new back_reference<T> template can be used as a -function parameter when the user needs access to both a T -argument and to the Python object which manages it. The function will -only match in the overload resolution process if it would match the -same function signature with T substituted for -back_reference<T>. This feature is not yet -documented. - -

Documentation

- -In a major effort to prepare Boost.Python v2 to replace v1, many pages -of new reference documentation were added: - -
- -
-
CallPolicies.html
-
Dereferenceable.html
-
Extractor.html
-
HolderGenerator.html
-
ResultConverter.html
-
call_method.html
-
callbacks.html
-
data_members.html
-
has_back_reference.html
-
implicit.html
-
instance_holder.html
-
operators.html
-
ptr.html
-
type_id.html
-
with_custodian_and_ward.html
-
- -
-Major updates were made to the following pages: - - -
-
-
call.html
updated
-
class.html
-
reference.html
-
-
- - As usual, careful documentation forces one to consider the - interface again, and there were many interface changes - associated with this effort, including the elevation of the - following components from implementation detail to - first-class library citizen: - -
-
-
type_id.hpp
-
pointee.hpp
-
lvalue_from_pytype.hpp
- -
- -

Miscellaneous

- -

Converters

- -It appears that the world of C++ <==> Python conversion rules is -an endlessly-rich area of exploration. Completing the conversions for -char and char const* types, as described at -the end of April's report, -uncovered some interesting new shades to the problem. It turns out to -be worth distinguishing mutable and immutable lvalue conversions, -because despite the fact that Python doesn't understand -const, it does understand immutability (c.f. Python -strings, which expose an immutable char pointer). It is -also worth recognizing types which represent lvalue sequences, -to prevent Python "foobar" from being silently -truncated to C++ 'f'. More details on this insight can be -found in the mailing list -archive. I don't plan to do anything about this immediately, but I -do think it's the right direction to go in the long run. - -

Checkins Mailing List

- -In order to better coordinate changes made by multiple developers, I -enabled syncmail -for the Boost.Python CVS trees, and established an associated mailing -list. Subscribe to this list to receive notices of each new -checkin. - -

Shared Libraries

- -Beyond the vagaries of dynamic linking on AIX, I have been -participating in a more-general discussion of dynamic linking for -C++. Needless to say, C++ dynamic linking is of critical importance to -Boost.Python: all extension modules are normally built as shared -libraries, and Boost.Python extension modules share a common library -as well. - -In fact, there are at least two separate conversations. One -in the C++ standard extensions mailing list concerns what can be -standardized for C++ and shared libraries; the other, mostly on the gcc mailing list, concerns the -behavior of GCC on Posix/ELF platforms. - -Some of the GCC threads are here: - -
-http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html
-http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html
-http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html -
- -

What's Next

- -Development is focused on what's needed to be able to retire -Boost.Python v1. At the moment, that means deciding the user-friendly -interfaces for to_/from_python conversion, and formally exposing the -Python object smart pointers and object wrapper classes. Quite a few -questions have also been showing up recently about how to embed Python -with Boost.Python, and how to link with it statically; the solutions -to these issues will probably have to be formalized before long. - -

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/ObjectWrapper.html b/doc/v2/ObjectWrapper.html deleted file mode 100644 index 82a940e3..00000000 --- a/doc/v2/ObjectWrapper.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - Boost.Python - ObjectWrapper Concept - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

ObjectWrapper and TypeWrapper Concepts

-
-
- -
-
Introduction
- -
Concept Requirements
- -
-
-
ObjectWrapper Concept
- -
TypeWrapper Concept
-
-
- -
Caveat
-
- -

Introduction

- -

This page defines two concepts used to describe classes which manage a - Python objects, and which are intended to support usage with a - Python-like syntax.

- -

Concept Requirements

- -

ObjectWrapper Concept

- Models of the ObjectWrapper concept have object as a publicly-accessible base class, - and are used to supply special construction behavior and/or additional - convenient functionality through (often templated) member functions. - Except when the return type R is itself an TypeWrapper, a member function invocation of - the form -
-x.some_function(a1, a2,...an)
-
- always has semantics equivalent to: -
-extract<R>(x.attr("some_function")(object(a1), object(a2),...object(an)))()
-
- When the R is an TypeWrapper, the result type may be - constructed by taking direct posession of: -
-x.attr("some_function")(object(a1), object(a2),...object(an)).ptr()
-
- [see caveat below] - -

TypeWrapper Concept

- TypeWrapper is a refinement of ObjectWrapper which is associated with a - particular Python type X. For a given TypeWrapper - T, a valid constructor expression -
-T(a1, a2,...an)
-
- builds a new T object managing the result of invoking - X with arguments corresponding to -
-object(a1), object(a2),...object(an)
-
- -When used as arguments to wrapped C++ functions, or as the template -parameter to extract<>, only -instances of the associated Python type will be considered a match. - -

Caveat

- The upshot of the special member function invocation rules when the - return type is a TypeWrapper is that it is possible for the returned - object to manage a Python object of an inappropriate type. This is not - usually a serious problem; the worst-case result is that errors will be - detected at runtime a little later than they might otherwise be. For an - example of how this can occur, note that the dict member function items - returns an object of type list. Now suppose the user defines this - dict subclass in Python: -
->>> class mydict(dict):
-...     def items(self):
-...         return tuple(dict.items(self)) # return a tuple
-
- Since an instance of mydict is also an instance of - dict, when used as an argument to a wrapped C++ function, - boost::python::dict can - accept objects of Python type mydict. Invoking - items() on this object can result in an instance of boost::python::list which actually - holds a Python tuple. Subsequent attempts to use list methods (e.g. - append, or any other mutating operation) on this object will - raise the same exception that would occur if you tried to do it from - Python. -
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- -

Permission to copy, use, modify, sell and distribute this software is - granted provided this copyright notice appears in all copies. This - software is provided "as is" without express or implied warranty, and - with no claim as to its suitability for any purpose.

- - - diff --git a/doc/v2/ResultConverter.html b/doc/v2/ResultConverter.html deleted file mode 100644 index 63187c3a..00000000 --- a/doc/v2/ResultConverter.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - -Boost.Python - ResultConverter Concept - - - - - - - -
-

C++ Boost

-
-

Boost.Python

-

ResultConverter Concept

-
-
-
-
Introduction
-
Concept Requirements
-
-
ResultConverter Concept
-
ResultConverterGenerator Concept
-
-
- -

Introduction

- -

A ResultConverter for a type T is a type whose -instances can be used to convert C++ return values of type -T to_python. A ResultConverterGenerator is -an MPL unary metafunction class which, given the return type of a C++ -function, returns a ResultConverter for that type. ResultConverters in -Boost.Python generally inspect library's registry of converters to -find a suitable converter, but converters which don't use the registry -are also possible. - -

Concept Requirements

-

ResultConverter Concept

- -

In the table below, C denotes a ResultConverter -type for a type R , c denotes -an object of type C , and r -denotes an object of type R. - - - - - - - - - - - - - - - - - - - - - - - - -
ExpressionTypeSemantics
C c; - Constructs a C object. -
c.convertible()convertible to boolfalse iff no conversion from any R value - to a Python object is possible.
c(r)convertible to PyObject*A pointer to a Python object corresponding to r, - or 0 iff r could not be converted - to_python, in which case PyErr_Occurred - should return non-zero.
- -

ResultConverterGenerator Concept

-

In the table below, G denotes a -ResultConverterGenerator type and R denotes a possible -C++ function return type. - - - - - - - - - -
ExpressionRequirements
G::apply<R>::typeA ResultConverter type for R.
- -


-

Revised - - 09 May, 2002 - -

-

© Copyright Dave - Abrahams 2002. All Rights Reserved. - -

Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - - diff --git a/doc/v2/args.html b/doc/v2/args.html deleted file mode 100644 index c2f29269..00000000 --- a/doc/v2/args.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/args.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/args.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
keyword-expressions
- -
Functions
- -
-
-
args(...)
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Supplies a family of overloaded functions for specifying argument - keywords for wrapped C++ functions.

- -

keyword-expressions

- -

A keyword-expression results in an object which holds a - sequence of ntbses, and whose type - encodes the number of keywords specified.

- -

Functions

- -

args(...)

-
-unspecified1 args(char const*);
-unspecified2 args(char const*, char const*);
-   .
-   .
-   .
-unspecifiedN args(char const*, char const*, ... char const*);
-
- -
-
Requires: Every argument must be a ntbs.
- -
Returns: an object representing a keyword-expression encapsulating the - arguments passed.
-
- -

Example

-
-#include <boost/python/def.hpp>
-using namespace boost::python;
-
-int f(int x, int y, int z);
-
-BOOST_PYTHON_MODULE(xxx)
-{
-   def("f", f, args("x", "y", "z"));
-}
-
- -

Revised 05 November, 2001

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/bibliography.html b/doc/v2/bibliography.html deleted file mode 100644 index 7ebd477b..00000000 --- a/doc/v2/bibliography.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -Boost.Python - Bibliography - - - - - - - -
-

-

-
-

Boost.Python

-

Bibliography

-
-
-{{bibliographical information}} -
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/call.html b/doc/v2/call.html deleted file mode 100644 index b5478a4b..00000000 --- a/doc/v2/call.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - -Boost.Python - <call.hpp> - - - - - - - -
-

-

-
-

Boost.Python

-

Header <call.hpp>

-
-
-

Contents

-
-
Introduction
-
Functions
-
-
call
-
- -
Example(s)
- -
-
-

Introduction

-

- <boost/python/call.hpp> defines the call family of overloaded function - templates, used to invoke Python callable objects from C++. - -

Functions

-
-template <class R, class A1, class A2, ... class An>
-R call(PyObject* callable, A1 const&, A2 const&, ... An const&)
-
-
-
Requires: R is a pointer type, reference - type, or a complete type with an accessible copy constructor
- -
Effects: Invokes callable(a1, a2, ...an) in - Python, where a1...an are the arguments to - call(), converted to Python objects. -
Returns: The result of the Python call, converted to the C++ type R.
- - -
Rationale: For a complete semantic description and - rationale, see this page. -
-
- -

Example(s)

- -The following C++ function applies a Python callable object to its two -arguments and returns the result. If a Python exception is raised or -the result can't be converted to a double, an exception -is thrown. - -
-double apply2(PyObject* func, double x, double y)
-{
-   return boost::python::call<double>(func, x, y);
-}
-
- -

Revised - - 9 May, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html deleted file mode 100644 index eaa91ec9..00000000 --- a/doc/v2/call_method.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - Boost.Python - <call_method.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <call_method.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
call_method
-
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/call_method.hpp> defines the call_method family of overloaded - function templates, used to invoke callable attributes of Python objects - from C++.

- -

Functions

-
-template <class R, class A1, class A2, ... class An>
-R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... An const&)
-
- -
-
Requires: R is a pointer type, reference type, - or a complete type with an accessible copy constructor
- -
Effects: Invokes - self.method(a1, a2, ...an) in - Python, where a1...an are the - arguments to call_method(), converted to Python objects. - For a complete semantic description, see this - page.
- -
Returns: The result of the Python call, converted to the C++ - type R.
- -
Rationale: call_method is critical to - implementing C++ virtual functions which are overridable in Python, as - shown by the example below.
-
- -

Example(s)

- The following C++ illustrates the use of call_method in - wrapping a class with a virtual function that can be overridden in - Python: - -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/utility.hpp>
-#include <cstring>
-
-// class to be wrapped
-class Base
-{
- public:
-   virtual char const* class_name() const { return "Base"; }
-   virtual ~Base();
-};
-
-bool is_base(Base* b)
-{
-   return !std::strcmp(b->class_name(), "Base");
-}
-
-// Wrapper code begins here
-using namespace boost::python;
-
-// Callback class
-class Base_callback : public Base
-{
- public:
-   Base_callback(PyObject* self) : m_self(self) {}
-
-   char const* class_name() const { return call_method<char const*>(m_self, "class_name"); }
-   char const* Base_name() const { return Base::class_name(); }
- private:
-   PyObject* const m_self;
-};
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    def("is_base", is_base);
-
-    class_<Base,Base_callback, noncopyable>("Base")
-        .def("class_name", &Base_callback::Base_name)
-        ;
-
-}
-
- -

Python Code

-
->>> from my_module import *
->>> class Derived(Base):
-...    def __init__(self):
-...       Base.__init__(self)
-...    def class_name(self):
-...       return self.__class__.__name__
-...
->>> is_base(Base()) # calls the class_name() method from C++
-1
->>> is_base(Derived())
-0
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/callbacks.html b/doc/v2/callbacks.html deleted file mode 100644 index 1d215801..00000000 --- a/doc/v2/callbacks.html +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - - - - Boost.Python - Calling Python Functions and Methods - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Calling Python Functions and Methods

-
-
- -

Contents

- -
-
Introduction
- -
Argument Handling
- -
Result Handling
- -
Rationale
-
-
- -

Introduction

- The simplest way to call a Python function from C++, given an object instance f - holding the function, is simply to invoke its function call operator. -
-f("tea", 4, 2) // In Python: f('tea', 4, 2)
-
- And of course, a method of an object instance x can - be invoked by using the function-call operator of the corresponding - attribute: -
-x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
-
- -

If you don't have an object instance, Boost.Python - provides two families of function templates, call and call_method, for invoking - Python functions and methods respectively on PyObject*s. The - interface for calling a Python function object (or any Python callable - object) looks like:

-
-call<ResultType>(callable_object, a1, a2... aN);
-
- Calling a method of a Python object is similarly easy: -
-call_method<ResultType>(self_object, "method-name", a1, a2... aN);
-
- This comparitively low-level interface is the one you'll use when - implementing C++ virtual functions that can be overridden in Python. - -

Argument Handling

- -

Arguments are converted to Python according to their type. By default, - the arguments a1...aN are copied into - new Python objects, but this behavior can be overridden by the use of - ptr() and ref():

-
-class X : boost::noncopyable
-{
-   ...
-};
-
-void apply(PyObject* callable, X& x)
-{
-   // Invoke callable, passing a Python object which holds a reference to x
-   boost::python::call<void>(callable, boost::ref(x));
-}
-
- In the table below, x denotes the actual argument - object and cv denotes an optional - cv-qualification: "const", "volatile", - or "const volatile". - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Argument TypeBehavior
T cv&
- T cv
The Python argument is created by the same means used for the - return value of a wrapped C++ function returning T. When - T is a class type, that normally means *x - is copy-constructed into the new Python object.
T*If x == 0, the Python argument will be - None. - Otherwise, the Python argument is created by the same means used for - the return value of a wrapped C++ function returning T. - When T is a class type, that normally means - *x is copy-constructed into the new Python object.
boost::reference_wrapper<T>The Python argument contains a pointer to, rather than a copy of, - x.get(). Note: failure to ensure that no Python code - holds a reference to the resulting object beyond the lifetime of - *x.get() may result in a crash!
pointer_wrapper<T>If x.get() == 0, the Python argument will - be None. - Otherwise, the Python argument contains a pointer to, rather than a - copy of, *x.get(). Note: failure to ensure that no - Python code holds a reference to the resulting object beyond the - lifetime of *x.get() may result in a crash!
- -

Result Handling

- In general, call<ResultType>() and - call_method<ResultType>() return - ResultType by exploiting all lvalue and rvalue - from_python converters registered for ResultType and - returning a copy of the result. However, when ResultType is - a pointer or reference type, Boost.Python searches only for lvalue - converters. To prevent dangling pointers and references, an exception - will be thrown if the Python result object has only a single reference - count. - -

Rationale

- In general, to get Python arguments corresponding to - a1...aN, a new Python object must be - created for each one; should the C++ object be copied into that Python - object, or should the Python object simply hold a reference/pointer to - the C++ object? In general, the latter approach is unsafe, since the - called function may store a reference to the Python object somewhere. If - the Python object is used after the C++ object is destroyed, we'll crash - Python. - -

In keeping with the philosophy that users on the Python side shouldn't - have to worry about crashing the interpreter, the default behavior is to - copy the C++ object, and to allow a non-copying behavior only if the user - writes boost::ref(a1) - instead of a1 directly. At least this way, the user doesn't get dangerous - behavior "by accident". It's also worth noting that the non-copying - ("by-reference") behavior is in general only available for class types, - and will fail at runtime with a Python exception if used otherwise[1].

- -

However, pointer types present a problem: one approach is to refuse to - compile if any aN has pointer type: after all, a user can always pass - *aN to pass "by-value" or ref(*aN) to indicate - a pass-by-reference behavior. However, this creates a problem for the - expected null pointer to None conversion: it's illegal to - dereference a null pointer value.

- -

The compromise I've settled on is this:

- -
    -
  1. The default behavior is pass-by-value. If you pass a non-null - pointer, the pointee is copied into a new Python object; otherwise the - corresponding Python argument will be None.
  2. - -
  3. if you want by-reference behavior, use ptr(aN) if - aN is a pointer and ref(aN) otherwise. If a - null pointer is passed to ptr(aN), the corresponding - Python argument will be None.
  4. -
- -

As for results, we have a similar problem: if ResultType - is allowed to be a pointer or reference type, the lifetime of the object - it refers to is probably being managed by a Python object. When that - Python object is destroyed, our pointer dangles. The problem is - particularly bad when the ResultType is char const* - the - corresponding Python String object is typically uniquely-referenced, - meaning that the pointer dangles as soon as call<char - const*>(...) returns.

- -

The old Boost.Python v1 deals with this issue by refusing to compile - any uses of call<char const*>(), but this goes both - too far and not far enough. It goes too far because there are cases where - the owning Python string object survives beyond the call (just for - instance, when it's the name of a Python class), and it goes not far - enough because we might just as well have the same problem with a - returned pointer or reference of any other type.

- -

In Boost.Python v2 this is dealt with by:

- -
    -
  1. lifting the compile-time restriction on const char* callback - returns
  2. - -
  3. detecting the case when the reference count on the result Python - object is 1 and throwing an exception inside of - call<U>(...) when U is a pointer or - reference type.
  4. -
- This should be acceptably safe because users have to explicitly specify a - pointer/reference for U in call<U>, and - they will be protected against dangles at runtime, at least long enough - to get out of the call<U>(...) invocation. -
- [1] It would be possible to make it fail at compile-time - for non-class types such as int and char, but I'm not sure it's a good - idea to impose this restriction yet. - -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/callbacks.txt b/doc/v2/callbacks.txt deleted file mode 100644 index a58ca0ea..00000000 --- a/doc/v2/callbacks.txt +++ /dev/null @@ -1,88 +0,0 @@ -Here's the plan: - -I aim to provide an interface similar to that of Boost.Python v1's -callback<>::call(...) for dealing with callbacks. The interface will -look like: - - returning::call("method_name", self_object, a1, a2...); - -or - - returning::call(callable_object, a1, a2...); - -ARGUMENT HANDLING - -There is an issue concerning how to make Python objects from the -arguments a1...aN. A new Python object must be created; should the C++ -object be copied into that Python object, or should the Python object -simply hold a reference/pointer to the C++ object? In general, the -latter approach is unsafe, since the called function may store a -reference to the Python object somewhere. If the Python object is used -after the C++ object is destroyed, we'll crash Python. - -I plan to make the copying behavior the default, and to allow a -non-copying behavior if the user writes boost::ref(a1) instead of a1 -directly. At least this way, the user doesn't get dangerous behavior "by -accident". It's also worth noting that the non-copying ("by-reference") -behavior is in general only available for class types, and will fail at -runtime with a Python exception if used otherwise** - -However, pointer types present a problem: My first thought is to refuse -to compile if any aN has pointer type: after all, a user can always pass -*aN to pass "by-value" or ref(*aN) to indicate a pass-by-reference -behavior. However, this creates a problem for the expected NULL pointer -=> None conversion: it's illegal to dereference a null pointer value. - -We could use another construct, say "ptr(aN)", to deal with null -pointers, but then what does it mean? We know what it does when aN is -NULL, but it might either have by-value or by-reference behavior when aN -is non-null. - -The compromise I've settled on is this: - -1. The default behavior is pass-by-value. If you pass a non-null - pointer, the pointee is copied into a new Python object; otherwise - the corresponding Python argument will be None. - -2. if you want by-reference behavior, use ptr(aN) if aN is a pointer - and ref(aN) otherwise. If a null pointer is passed to ptr(aN), the - corresponding Python argument will be None. - -RESULT HANDLING - -As for results, we have a similar problem: if ResultType is allowed to -be a pointer or reference type, the lifetime of the object it refers to -is probably being managed by a Python object. When that Python object is -destroyed, our pointer dangles. The problem is particularly bad when the -ResultType is char const* - the corresponding Python String object is -typically uniquely-referenced, meaning that the pointer dangles as soon -as returning::call() returns. - -Boost.Python v1 deals with this issue by refusing to compile any uses of -callback::call(), but IMO this goes both too far and not -far enough. It goes too far because there are cases where the owning -String object survives beyond the call (just for instance when it's the -name of a Python class), and it goes not far enough because we might -just as well have the same problem with any returned pointer or -reference. - -I propose to address this in Boost.Python v2 by - - 1. lifting the compile-time restriction on const - char* callback returns - - 2. detecting the case when the reference count on the - result Python object is 1 and throwing an exception - inside of returning::call() when U is a pointer or - reference type. - -I think this is acceptably safe because users have to explicitly specify -a pointer/reference for U in returning, and they will be protected -against dangles at runtime, at least long enough to get out of the -returning::call() invocation. - --Dave - -**It would be possible to make it fail at compile-time for non-class -types such as int and char, but I'm not sure it's a good idea to impose -this restriction yet. diff --git a/doc/v2/class.html b/doc/v2/class.html deleted file mode 100644 index 85eda64e..00000000 --- a/doc/v2/class.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/class.hpp>, - <boost/python/class_fwd.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Headers <boost/python/class.hpp>, - <boost/python/class_fwd.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - class_
- -
-
-
Class class_ - synopsis
- -
Class class_ - constructors
- -
Class class_ - modifier functions
-
-
- -
Class template - bases
- -
-
-
Class template - bases synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/class.hpp> defines the interface - through which users expose their C++ classes to Python. It declares the - class_ class template, which is parameterized on the class - type being exposed. It also exposes the init, - optional and bases utility class templates, - which are used in conjunction with class_.

- -

<boost/python/class_fwd.hpp> contains a forward - declaration of the class_ class template.

- -

Classes

- -

Class template - class_<T, Bases, HeldType, - NonCopyable>

- -

Creates a Python class associated with the C++ type passed as its - first parameter. Although it has four template parameters, only the first - one is required. The three optional arguments can actually be supplied - in any order; Boost.Python determines - the role of the argument from its type.
-
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Template ParameterRequirementsSemanticsDefault
TA class type.The class being wrapped
BasesA specialization of bases<...> which - specifies previously-exposed C++ base classes of T[1].Registers from_python conversions from wrapped - T instances to each of its exposed direct and indirect - bases. For each polymorphic base B, registers - conversions from indirectly-held wrapped B instances to - T.bases<>
HeldTypeMust be T, a class derived from T, or a - Dereferenceable type for which - pointee<HeldType>::type - is T or a class derived from T.Specifies the type which is actually embedded in a Python object - wrapping a T instance. More details below.T
NonCopyableIf supplied, must be boost::noncopyable.Suppresses automatic registration of to_python - conversions which copy T instances. Required when - T has no publicly-accessible copy constructor.An unspecified type other than - boost::noncopyable.
- -

HeldType Semantics

- -
    -
  1. If HeldType is derived from T, its exposed - constructor(s) must accept an initial PyObject* argument - which refers back to the Python object that contains the - HeldType instance, as shown in this example. This argument is not - included in the init-expression passed to def(init_expr), below, - nor is it passed explicitly by users when Python instances of - T are created. This idiom allows C++ virtual functions - which will be overridden in Python to access the Python object so the - Python method can be invoked. Boost.Python automatically registers - additional converters which allow wrapped instances of T - to be passed to wrapped C++ functions expecting HeldType - arguments.
  2. - -
  3. Because Boost.Python will always allow wrapped instances of - T to be passed in place of HeldType - arguments, specifying a smart pointer for HeldType allows - users to pass Python T instances where a smart - pointer-to-T is expected. Smart pointers such as - std::auto_ptr<> or boost::shared_ptr<> - which contain a nested type element_type designating the - referent type are automatically supported; additional smart pointer - types can be supported by specializing pointee<HeldType>.
  4. - -
  5. As in case 1 above, when HeldType is a smart pointer - to a class derived from T, the initial - PyObject* argument must be supplied by all of - HeldType's exposed constructors.
  6. - -
  7. Except in cases 1 and 3, users may optionally specify that T itself - gets initialized with a similar initial PyObject* argument - by specializing has_back_reference<T>.
  8. -
- -

Class template class_ - synopsis

-
-namespace boost { namespace python
-{
-  template <class T
-        , class Bases = bases<>
-            , class HeldType = T
-            , class NonCopyable = unspecified
-           >
-  class class_ : public object
-  {
-    // Constructors with default __init__
-    class_(char const* name);
-    class_(char const* name, char const* docstring);
-
-    // Constructors, specifying non-default __init__
-    template <class Init>
-    class_(char const* name, Init);
-    template <class Init>
-    class_(char const* name, char const* docstring, Init);
-
-    // Exposing additional __init__ functions
-    template <class Init>
-    class_& def(Init);
-
-    // defining methods
-    template <class F>
-    class_& def(char const* name, F f);
-    template <class Fn, class A1>
-    class_& def(char const* name, Fn fn, A1 const&);
-    template <class Fn, class A1, class A2>
-    class_& def(char const* name, Fn fn, A1 const&, A2 const&);
-    template <class Fn, class A1, class A2, class A3>
-    class_& def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
-
-    // declaring method as static
-    class_& staticmethod(char const* name);
-    
-    // exposing operators
-    template <unspecified>
-    class_& def(detail::operator_<unspecified>);
-
-    // Raw attribute modification
-    template <class U>
-    class_& setattr(char const* name, U const&);
-
-    // exposing data members
-    template <class D>
-    class_& def_readonly(char const* name, D T::*pm);
-
-    template <class D>
-    class_& def_readwrite(char const* name, D T::*pm);
-
-    // property creation
-    template <class Get>
-    void add_property(char const* name, Get const& fget);
-    template <class Get, class Set>
-    void add_property(char const* name, Get const& fget, Set const& fset);
-
-    // pickle support
-    template <typename PickleSuite>
-    self& def_pickle(PickleSuite const&);
-  };
-}}
-
- -

Class template class_ - constructors

-
-class_(char const* name);
-class_(char const* name, char const* docstring);
-template <class Init>
-class_(char const* name, Init init_spec);
-template <class Init>
-class_(char const* name, char const* docstring, Init init_spec);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules. If docstring is supplied, it must be an - ntbs. If init_spec is - supplied, it must be either the special enumeration constant - no_init or an init-expression compatible with - T.
- -
Effects: Constructs a class_ object holding a - Boost.Python extension class named name. The - named attribute of the current scope is bound to the new - extension class.
- -
-
    -
  • If supplied, the value of docstring is bound to - the __doc__ attribute of the extension class.
  • - -
  • If init_spec is no_init, a special - __init__ function is generated which always raises a - Python exception. Otherwise, this->def(init_spec) - is called.
  • - -
  • If init_spec is not supplied, - this->def(init<>()) is called.
  • -
-
- -
Rationale:Allowing the user to specify constructor arguments - in the class_<> constructor helps her to avoid the - common run-time errors which result from invoking wrapped member - functions without having exposed an __init__ function - which creates the requisite T instance. Types which are - not default-constructible will cause a compile-time error unless - Init is supplied. The user must always supply - name as there is currently no portable method to derive - the text of the class name from its type.
-
- -

Class template - class_ modifier functions

-
-template <class Init>
-class_& def(Init init_expr);
-
- -
-
Requires: init_expr is the result of an init-expression compatible with - T.
- -
Effects: For each valid - prefix P of Init, adds an - __init__(...) function overload to the - extension class accepting P as arguments. Each overload - generated constructs an object of HeldType according to - the semantics described above, using a copy of - init_expr's call policies. - If the longest valid prefix of - Init contains N types and init_expr - holds M keywords, an initial sequence of the keywords are used - for all but the first N - M arguments of - each overload.
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' - constructor to Python.
-
-
- -
-template <class F>
-class_& def(char const* name, Fn fn);
-template <class Fn, class A1>
-class_& def(char const* name, Fn fn, A1 const& a1);
-template <class Fn, class A1, class A2>
-class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2);
-template <class Fn, class A1, class A2, class A3>
-class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
-
    -
  • - If a1 is the result of an overload-dispatch-expression, - only the second form is allowed and fn must be a pointer to - function or pointer to member function whose arity is the same as A1's maximum - arity. - -
    -
    Effects: For each prefix P of - Fn's sequence of argument types, beginning with - the one whose length is A1's minimum - arity, adds a - name(...) method overload to - the extension class. Each overload generated invokes - a1's call-expression with P, using a copy - of a1's call - policies. If the longest valid prefix of A1 - contains N types and a1 holds M - keywords, an initial sequence of the keywords are used for all - but the first N - M arguments of - each overload.
    -
    -
    -
  • - -
  • - Otherwise, a single method overload is built around fn, which - must not be null: - -
      -
    • If fn is a function pointer, its first argument must be of - the form U, cv&, - cv*, or - cv* const&, where - T* is convertible to U*, and - a1-a3, if supplied, may be selected - in any order from the table below.
    • - -
    • Otherwise, if fn is a member function pointer, its target - must be T or one of its public base classes, and - a1-a3, if supplied, may be selected - in any order from the table below.
    • - -
    • Otherwise, Fn must be [derived from] object, and - a1-a2, if supplied, may be selcted in any order - from the first two rows of the table below. To be useful, - fn should be - callable.
    • -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Memnonic NameRequirements/Type propertiesEffects
    docstringAny ntbs.Value will be bound to the __doc__ attribute - of the resulting method overload.
    policiesA model of CallPoliciesA copy will be used as the call policies of the resulting - method overload.
    keywordsThe result of a keyword-expression - specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting - method overload.
    -
  • -
-
- -
Returns: *this
-
-
-class_& staticmethod(char const* name);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules, and corresponds to a method whose overloads have all - been defined.
- -
Effects: Replaces the existing named attribute x with - the result of invoking staticmethod(x) - in Python. Specifies that the corresponding method is static and - therefore no object instance will be passed to it. This is equivalent - to the Python statement:
- -
-
-setattr(self, name, staticmethod(getattr(self, name)))
-
-
- -
Note: Attempting to invoke def(name,...) after - invoking staticmethod(name) will raise a RuntimeError.
- -
Returns: *this
-
-
- -
-template <unspecified>
-class_& def(detail::operator_<unspecified>);
-
- -
-
Effects: Adds a Python special method as - described here.
- -
Returns: *this
-
-
-template <class U>
-class_& setattr(char const* name, U const& u);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
Effects: Converts u to Python and adds it to the attribute - dictionary of the extension class:
- -
-
- PyObject_SetAttrString(this->ptr(), name, object(u).ptr()); -
-
- -
Returns: *this
-
-
- -
-template <class Get>
-void add_property(char const* name, Get const& fget);
-template <class Get, class Set>
-void add_property(char const* name, Get const& fget, Set const& fset);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
Effects: Creates a new Python property - class instance, passing object(fget) (and object(fset) in the - second form) to its constructor, then adds that property to the Python - class object under construction with the given attribute - name.
- -
Returns: *this
- -
Rationale: Allows users to easily expose functions that can - be invoked from Python with attribute access syntax.
-
-
-
-template <class D>
-class_& def_readonly(char const* name, D T::*pm);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
Effects:
- -
-
-this->add_property(name, make_getter(pm));
-
-
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' data - member such that it can be inspected from Python with a natural - syntax.
-
-
-template <class D>
-class_& def_readwrite(char const* name, D T::*pm);
-
- -
-
Effects:
- -
-
-this->add_property(name, make_getter(pm), make_setter(pm));
-
-
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' data - member such that it can be inspected and set from Python with a natural - syntax.
-
-
-template <typename PickleSuite>
-class_& def_pickle(PickleSuite const&);
-
- -
-
Requires: PickleSuite must be publically derived from pickle_suite.
- -
Effects: Defines a legal combination of the special - attributes and methods: __getinitargs__, - __getstate__, __setstate__, - __getstate_manages_dict__, - __safe_for_unpickling__, __reduce__
- -
Returns: *this
- -
Rationale: Provides an easy to use - high-level interface for establishing complete pickle support for - the wrapped class. The user is protected by compile-time consistency - checks.
-
-
- - -

Class template - bases<T1, T2,...TN>

- -

An MPL sequence - which can be used in class_<...> - instantiations indicate a list of base classes.

- -

Class template bases - synopsis

-
-namespace boost { namespace python
-{
-  template <T1 = unspecified,...Tn = unspecified>
-  struct bases
-  {};
-}}
-
- -

Example(s)

- -

Given a C++ class declaration:

-
-class Foo : public Bar, public Baz
-{
- public:
-   Foo(int x, char const* y);
-   Foo(double);
-
-   std::string const& name() { return m_name; }
-   void name(char const*);
-
-   double value; // public data
- private:
-   ...
-};
-
- A corresponding Boost.Python extension class can be created with: -
-using namespace boost::python;
-
-class_<Foo,bases<Bar,Baz> >("Foo",
-          "This is Foo's docstring."
-          "It describes our Foo extension class",
-
-          init<int,char const*>(args("x","y"), "__init__ docstring")
-          )
-   .def(init<double>())
-   .def("get_name", &Foo::get_name, return_internal_reference<>())
-   .def("set_name", &Foo::set_name)
-   .def_readwrite("value", &Foo::value)
-   ;
-
-
- [1] By "previously-exposed" we mean that the for - each B in bases, an instance of - class_<B, ...> must have - already been constructed. -
-class_<Base>("Base");
-class_<Derived, bases<Base> >("Derived");
-
- Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/configuration.html b/doc/v2/configuration.html deleted file mode 100644 index feee4a05..00000000 --- a/doc/v2/configuration.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - Boost.Python - Configuration - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Configuration

-
-
- -
-
Introduction
- -
Application Defined Macros
- -
Library Defined Implementation - Macros
-
- -

Introduction

- -

Boost.Python uses several configuration macros in <boost/config.hpp>, - as well as configuration macros meant to be supplied by the application. - These macros are documented here.

- -

Application Defined Macros

- -

These are the macros that may be defined by an application using - Boost.Python. Note that if you extend a strict interpretation of - the C++ standard to cover dynamic libraries, using different values of - these macros when compiling different libraries (including extension - modules and the Boost.Python library itself) is a violation of the - ODR. However, we know of no C++ - implementations on which this particular violation is detectable or - causes any problems.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MacroDefaultMeaning
BOOST_PYTHON_MAX_ARITY15The maximum arity of any function, member function, - or constructor to be wrapped, invocation of a Boost.Python - function wich is specified as taking arguments - x1, x2,...Xn. This includes, in - particular, callback mechanisms such as object::operator()(...) - or call_method<R>(... - ).
BOOST_PYTHON_MAX_BASES10The maximum number of template arguments to the - bases<...> - class template, which is used to specify the bases of a wrapped C++ - class..
BOOST_PYTHON_STATIC_MODULEnot definedIf defined, prevents your module initialization - function from being treated as an exported symbol on platforms which - support that distinction in-code
- -

Library Defined Implementation - Macros

- -

These macros are defined by Boost.Python and are implementation - details of interest only to implementors and those porting to new - platforms.

- - - - - - - - - - - - - - - - - -
MacroDefaultMeaning
BOOST_PYTHON_TYPE_ID_NAMEnot definedIf defined, this indicates that the type_info - comparison across shared library boundaries does not work on this - platform. In other words, if shared-lib-1 passes - typeid(T) to a function in shared-lib-2 which compares - it to typeid(T), that comparison may return - false. If this macro is #defined, Boost.Python uses and - compares typeid(T).name() instead of using and comparing - the std::type_info objects directly.
-
- -

Revised - - 7 January, 2003 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html deleted file mode 100644 index c65fc21c..00000000 --- a/doc/v2/copy_const_reference.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/copy_const_reference.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/copy_const_reference.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - copy_const_reference
- -
-
-
Class - copy_const_reference synopsis
- -
Class - copy_const_reference metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - copy_const_reference

- -

copy_const_reference is a model of ResultConverterGenerator - which can be used to wrap C++ functions returning a reference-to-const - type such that the referenced value is copied into a new Python - object.

- -

Class - copy_const_reference synopsis

-
-namespace boost { namespace python
-{
-    struct copy_const_reference
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - copy_const_reference metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U const& for - some U.
- -
Returns: typedef to_python_value<T> - type;
-
- -

Example

- -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/copy_const_reference.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { int x; }
-
-struct Foo {
-   Foo(int x) : { b.x = x; }
-   Bar const& get_bar() const { return b; }
- private:
-   Bar b;
-};
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    class_<Bar>("Bar");
-
-     class_<Foo>("Foo", init<int>())
-        .def("get_bar", &Foo::get_bar
-            , return_value_policy<copy_const_reference>())
-       ;
-}
-
- -

Python Code

-
->>> from my_module import *
->>> f = Foo(3)         # create a Foo object
->>> b = f.get_bar()    # make a copy of the internal Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html deleted file mode 100644 index 9cce0e74..00000000 --- a/doc/v2/copy_non_const_reference.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/copy_non_const_reference.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/copy_non_const_reference.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - copy_non_const_reference
- -
-
-
Class - copy_non_const_reference synopsis
- -
Class - copy_non_const_reference metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - copy_non_const_reference

- -

copy_non_const_reference is a model of ResultConverterGenerator - which can be used to wrap C++ functions returning a - reference-to-non-const type such that the referenced value is copied into - a new Python object.

- -

Class - copy_non_const_reference synopsis

-
-namespace boost { namespace python
-{
-    struct copy_non_const_reference
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - copy_non_const_reference metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U& for some - non-const U.
- -
Returns: typedef to_python_value<T> - type;
-
- -

Example

- -

C++ code:

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/copy_non_const_reference.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { int x; }
-
-struct Foo {
-   Foo(int x) : { b.x = x; }
-   Bar& get_bar() { return b; }
- private:
-   Bar b;
-};
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    class_<Bar>("Bar");
-
-     class_<Foo>("Foo", init<int>())
-        .def("get_bar", &Foo::get_bar
-            , return_value_policy<copy_non_const_reference>())
-       ;
-}
-
- Python Code: -
->>> from my_module import *
->>> f = Foo(3)         # create a Foo object
->>> b = f.get_bar()    # make a copy of the internal Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html deleted file mode 100644 index 0f015780..00000000 --- a/doc/v2/data_members.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/data_members.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/data_members.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
make_getter
- -
make_setter
-
-
- -
Example
-
-
- -

Introduction

- -

make_getter() and - make_setter() are the - functions used internally by class_<>::def_readonly and - class_<>::def_readwrite to produce - Python callable objects which wrap C++ data members.

- -

Functions

-
-template <class C, class D>
-object make_getter(D C::*pm);
-
-template <class C, class D, class Policies>
-object make_getter(D C::*pm, Policies const& policies);
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Creates a Python callable object which accepts a - single argument that can be converted from_python to - C*, and returns the corresponding member D - member of the C object, converted to_python. - If policies is supplied, it will be applied to the - function as described here. Otherwise, - the library attempts to determine whether D is a - user-defined class type, and if so uses return_internal_reference<>
- -
for Policies. Note that this test may inappropriately - choose return_internal_reference<> in some cases - when D is a smart pointer type. This is a known - defect.
- -
Returns: An instance of object which holds the new Python - callable object.
-
-
-template <class C, class D>
-object make_setter(D C::*pm);
-
-template <class C, class D, class Policies>
-object make_setter(D C::*pm, Policies const& policies);
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Creates a Python callable object which, when called - from Python, expects two arguments which can be converted - from_python to C* and - D const&, respectively, and sets the - corresponding D member of the C object. If - policies is supplied, it will be applied to the function - as described here.
- -
Returns: An instance of object which holds the new Python - callable object.
-
- -

Example

- -

The code below uses make_getter and make_setter to expose a data - member as functions:

-
-#include <boost/python/data_members.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-
-struct X
-{
-    X(int x) : y(x) {}
-    int y;
-};
-
-using namespace boost::python;
-
-BOOST_PYTHON_MODULE_INIT(data_members_example)
-{
-    class_<X>("X", init<int>())
-       .def("get", make_getter(&X::y))
-       .def("set", make_setter(&X::y))
-       ;
-}
-
- It can be used this way in Python: -
->>> from data_members_example import *
->>> x = X(1)
->>> x.get()
-1
->>> x.set(2)
->>> x.get()
-2
-
- -

- - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/def.html b/doc/v2/def.html deleted file mode 100644 index 80978a87..00000000 --- a/doc/v2/def.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/def.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/def.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
def
-
-
- -
Example
-
-
- -

Introduction

- -

def() is the function which can - be used to expose C++ functions and callable objects as Python functions - in the current scope.

- -

Functions

- def -
-template <class F>
-void def(char const* name, F f);
-
-template <class Fn, class A1>
-void def(char const* name, Fn fn, A1 const&);
-
-template <class Fn, class A1, class A2>
-void def(char const* name, Fn fn, A1 const&, A2 const&);
-
-template <class Fn, class A1, class A2, class A3>
-void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
-
    -
  • If Fn is [derived from] object, it will be added to - the current scope as a single overload. To be useful, - fn should be callable.
  • - -
  • - If a1 is the result of an overload-dispatch-expression, - only the second form is allowed and fn must be a pointer to - function or pointer to member function whose arity is the same as A1's maximum - arity. - -
    -
    Effects: For each prefix P of - Fn's sequence of argument types, beginning with - the one whose length is A1's minimum - arity, adds a - name(...) function overload - to the current scope. Each overload - generated invokes a1's call-expression with - P, using a copy of a1's call policies. If the longest valid - prefix of A1 contains N types and - a1 holds M keywords, an initial sequence - of the keywords are used for all but the first - N - M arguments of each - overload.
    -
    -
    -
  • - -
  • Otherwise, fn must be a non-null function or member function - pointer, and a single function overload built around fn is added to - the current scope. If any of - a1-a3 are supplied, they may be selected - in any order from the table below.
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Memnonic NameRequirements/Type propertiesEffects
docstringAny ntbs.Value will be bound to the __doc__ attribute of - the resulting method overload.
policiesA model of CallPoliciesA copy will be used as the call policies of the resulting - method overload.
keywordsThe result of a keyword-expression - specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting - method overload.
-
-
- -

Example

-
-#include <boost/python/def.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/args.hpp>
-
-using namespace boost::python;
-
-char const* foo(int x, int y) { return "foo"; }
-
-BOOST_PYTHON_MODULE(def_test)
-{
-    def("foo", foo, args("x", "y"), "foo's docstring");
-}
-
- -

- - 7 March, 2003 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/default_call_policies.html b/doc/v2/default_call_policies.html deleted file mode 100644 index 90f816fa..00000000 --- a/doc/v2/default_call_policies.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - Boost.Python - - <boost/python/default_call_policies.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header - <boost/python/default_call_policies.hpp>

-
-
- -

Contents

- -
-
Classes - -
-
-
Class - default_call_policies - -
-
-
Class - default_call_policies synopsis - -
Class - default_call_policies static functions -
- -
Class - default_result_converter - -
-
-
Class - default_result_converter synopsis - -
Class - default_result_converter metafunctions -
-
- -
Example -
-
- -

Classes

- -

Class - default_call_policies

- -

default_call_policies is a model of CallPolicies with no precall or - postcall behavior and a result_converter which - handles by-value returns. Wrapped C++ functions and member functions use - default_call_policies unless otherwise specified. You may find - it convenient to derive new models of CallPolicies from - default_call_policies. - -

Class - default_call_policies synopsis

-
-namespace boost { namespace python
-{
-    struct default_call_policies
-    {
-        static bool precall(PyObject*);
-        static PyObject* postcall(PyObject*, PyObject* result);
-        typedef default_result_converter result_converter;
-    };
-}}
-
- -

Class - default_call_policies static functions

-
-bool precall(PyObject*);
-
- -
-
Returns: true - -
Throws: nothing -
-
-PyObject* postcall(PyObject*, PyObject* result);
-
- -
-
Returns: result - -
Throws: nothing -
- -

Class - default_result_converter

- -

default_result_converter is a model of ResultConverterGenerator which can be - used to wrap C++ functions returning non-pointer types, char - const*, and PyObject*, by-value. - -

Class - default_result_converter synopsis

-
-namespace boost { namespace python
-{
-    struct default_result_converter
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - default_result_converter metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is not a reference type. If - T is a pointer type, T is const - char* or PyObject*. - -
Returns: typedef to_python_value<T - const&> type; -
- -

Example

- -

This example comes from the Boost.Python implementation itself. Because - the return_value_policy - class template does not implement precall or - postcall behavior, its default base class is - default_call_policies: -

-template <class Handler, class Base = default_call_policies>
-struct return_value_policy : Base
-{
-   typedef Handler result_converter;
-};
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html deleted file mode 100644 index 625e9b74..00000000 --- a/doc/v2/definitions.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - Boost.Python - Definitions - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Definitions

-
-


- -
-
arity: The number of arguments accepted - by a function or member function. Unless otherwise specified, the - hidden "this" argument to member functions is not counted - when specifying arity
- -

-
- -
ntbs: Null-Terminated Byte String, or - `C'-string. C++ string literals are ntbses. An - ntbs must never be null.
- -

-
- -
raise: Exceptions in Python are - "raised", not "thrown", as they are in C++. When this documentation - says that some Python exception is "raised" in the context of C++ code, - it means that the corresponding Python exception is set via the Python/'C' - API, and throw_error_already_set() - is called.
- -

-
- -
POD: A technical term from the C++ - standard. Short for "Plain Ol'Data": A POD-struct is an aggregate class - that has no non-static data members of type pointer to member, - non-POD-struct, non-POD-union (or array of such types) or reference, - and has no user-defined copy assign- ment operator and no user-defined - destructor. Similarly, a POD-union is an aggregate union that has no - non-static data members of type pointer to member, non-POD-struct, - non-POD-union (or array of such types) or reference, and has no - user-defined copy assignment operator and no user-defined destructor. A - POD class is a class that is either a POD-struct or a POD-union. An - aggregate is an array or a class (clause 9) with no user-declared - constructors (12.1), no private or protected non-static data members - (clause 11), no base classes (clause 10), and no virtual functions - (10.3).
- -

-
- -
ODR: The "One Definition - Rule", which says that any entity in a C++ program must have the same definition in all translation units (object files) which make up a program. -
- -

-
- - -
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/dict.html b/doc/v2/dict.html deleted file mode 100644 index 3b4dc211..00000000 --- a/doc/v2/dict.html +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/dict.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/dict.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class dict
- -
-
-
Class dict - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - dict - type.

- -

Classes

- -

Class dict

- -

Exposes the mapping - protocol of Python's built-in dict type. The semantics - of the constructors and member functions defined below can be fully - understood by reading the TypeWrapper concept - definition. Since dict is publicly derived from object, the public object - interface applies to dict instances as well.

- -

Class dict - synopsis

-
-namespace boost { namespace python
-{
-   class dict : public object
-   {
-      dict();
-
-      template< class T >
-      dict(T const & data);
-
-      // modifiers
-      void clear();
-      dict copy();
-
-      template <class T1, class T2>
-      tuple popitem();
-
-      template <class T>
-      object setdefault(T const &k);
-
-      template <class T1, class T2>
-      object setdefault(T1 const & k, T2 const & d);
-
-      void update(object_cref E);
- 
-      template< class T >
-      void update(T const & E);
-
-      // observers
-      list values() const;
-    
-      object get(object_cref k) const;
-
-      template<class T>
-      object get(T const & k) const;
-
-      object get(object_cref k, object_cref d) const;
-      object get(T1 const & k, T2 const & d) const;
-
-      bool has_key(object_cref k) const;
-
-      template< class T >
-      bool has_key(T const & k) const;
-
-      list items() const;
-      object iteritems() const;
-      object iterkeys() const;
-      object itervalues() const;
-      list keys() const;
-  };
-}}
-
- -

Example

-
-using namespace boost::python;
-dict swap_object_dict(object target, dict d)
-{
-    dict result = extract<dict>(target.attr("__dict__"));
-    target.attr("__dict__") = d;
-    return result;
-}
-
- -

Revised 30 September, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/enum.html b/doc/v2/enum.html deleted file mode 100644 index 57926794..00000000 --- a/doc/v2/enum.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/enum.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/enum.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - enum_
- -
-
-
Class template enum_ - synopsis
- -
Class template enum_ - constructors
- -
Class template enum_ - modifier functions
-
-
- -
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/enum.hpp> defines the - interface through which users expose their C++ enumeration types - to Python. It declares the - enum_ class template, which is parameterized on the - enumeration type being exposed.

- - -

Classes

- -

Class template - enum_<T>

- -

Creates a Python class derived from Python's int - type which is associated with the C++ type passed as its first - parameter. - -

Class template enum_ - synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  class enum_ : public object
-  {
-    enum_(char const* name);
-    enum_<T>& value(char const* name, T);
-    enum_<T>& export_values();
-  };
-}}
-
- -

Class template enum_ - constructors

-
-enum_(char const* name);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules. - -
Effects: Constructs an enum_ object - holding a Python extension type derived from int - which is named name. The - named attribute of the current scope is bound to the new - extension type.
-
- -

Class template - enum_ modifier functions

-
-inline enum_<T>& value(char const* name, T x);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules. - -
Effects: adds an instance of the wrapped enumeration - type with value x to the type's dictionary as the - named attribute
. - -
Returns: *this
- -
- -
-inline enum_<T>& export_values();
-
- -
- -
Effects: sets attributes in the current scope with the - same names and values as all enumeration values exposed so far - by calling value()
. - -
Returns: *this
- -
- -

Example(s)

- -

C++ module definition -

-#include <boost/python/enum.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/module.hpp>
-
-using namespace boost::python;
-
-enum color { red = 1, green = 2, blue = 4 };
-
-color identity_(color x) { return x; }
-
-BOOST_PYTHON_MODULE(enums)
-{
-    enum_<color>("color")
-        .value("red", red)
-        .value("green", green)
-        .export_values()
-        .value("blue", blue)
-        ;
-    
-    def("identity", identity_);
-}
-
-

Interactive Python: -

->>> from enums import *
-
->>> identity(red)
-enums.color.red
-
->>> identity(color.red)
-enums.color.red
-
->>> identity(green)
-enums.color.green
-
->>> identity(color.green)
-enums.color.green
-
->>> identity(blue)
-Traceback (most recent call last):
-  File "<stdin>", line 1, in ?
-NameError: name blue' is not defined
-
->>> identity(color.blue)
-enums.color.blue
-
->>> identity(color(1))
-enums.color.red
-
->>> identity(color(2))
-enums.color.green
-
->>> identity(color(3))
-enums.color(3)
-
->>> identity(color(4))
-enums.color.blue
-
->>> identity(1)
-Traceback (most recent call last):
-  File "<stdin>", line 1, in ?
-TypeError: bad argument type for built-in operation
-
-
- - Revised - - 13 December, 2002 - - - -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/errors.html b/doc/v2/errors.html deleted file mode 100644 index 940c30fd..00000000 --- a/doc/v2/errors.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/errors.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/errors.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class - error_already_set
- -
-
-
Class - error_already_set synopsis
-
-
-
-
- -
Functions
- -
-
-
handle_exception
- -
expect_non_null
- -
throw_error_already_set
-
-
- -
Examples
-
-
- -

Introduction

- -

<boost/python/errors.hpp> provides types and - functions for managing and translating between Python and C++ exceptions. - This is relatively low-level functionality that is mostly used internally - by Boost.Python. Users should seldom need it.

- -

Classes

- -

Class - error_already_set

- -

error_already_set is an exception type which can be - thrown to indicate that a Python error has occurred. If thrown, the - precondition is that PyErr_Occurred() - returns a value convertible to true. Portable code shouldn't - throw this exception type directly, but should instead use throw_error_already_set(), - below.

- -

Class error_already_set - synopsis

-
-namespace boost { namespace python
-{
-    class error_already_set {};
-}}
-
- -

Functions

-
-template <class T> bool handle_exception(T f) throw();
-
-void handle_exception() throw();
-
- -
-
Requires: The first form requires that the expression - function0<void>(f) - is valid. The second form requires that a C++ exception is currently - being handled (see section 15.1 in the C++ standard).
- -
Effects: The first form calls f() inside a - try block which first attempts to use all registered exception translators. If none of - those translates the exception, the catch clauses then set - an appropriate Python exception for the C++ exception caught, returning - true if an exception was thrown, false - otherwise. The second form passes a function which rethrows the - exception currently being handled to the first form.
- -
Postconditions: No exception is being handled
- -
Throws: nothing
- -
Rationale: At inter-language boundaries it is important to - ensure that no C++ exceptions escape, since the calling language - usually doesn't have the equipment neccessary to properly unwind the - stack. Use handle_exception to manage exception - translation whenever your C++ code is called directly from the Python - API. This is done for you automatically by the usual function wrapping - facilities: make_function(), - make_constructor(), - def() and class_::def(). The second form can be - more convenient to use (see the example below), - but various compilers have problems when exceptions are rethrown from - within an enclosing try block.
-
-
-template <class T> T* expect_non_null(T* x);
-
- -
-
Returns: x
- -
Throws: error_already_set() iff x == - 0.
- -
Rationale: Simplifies error-handling when calling functions - in the Python/C - API which return 0 on error.
-
-
-void throw_error_already_set();
-
- -
-
Effects: throw error_already_set();
-
- -
-
Rationale: Many platforms and compilers are not able to - consistently catch exceptions thrown across shared library boundaries. - Using this function from the Boost.Python library ensures that the - appropriate catch block in handle_exception() can catch the - exception.
-
- -

Examples

-
-#include <string>
-#include <boost/python/errors.hpp>
-#include <boost/python/object.hpp>
-#include <boost/python/handle.hpp>
-
-// Returns a std::string which has the same value as obj's "__name__"
-// attribute.
-std::string get_name(boost::python::object obj)
-{
-   // throws if there's no __name__ attribute
-   PyObject* p = boost::python::expect_non_null(
-      PyObject_GetAttrString(obj.ptr(), "__name__"));
-
-   char const* s = PyString_AsString(p);
-   if (s != 0) 
-        Py_DECREF(p);
-
-   // throws if it's not a Python string
-   std::string result(
-      boost::python::expect_non_null(
-         PyString_AsString(p)));
-
-   Py_DECREF(p); // Done with p
-   
-   return result;
-}
-
-//
-// Demonstrate form 1 of handle_exception
-//
-
-// Place into result a Python Int object whose value is 1 if a and b have
-// identical "__name__" attributes, 0 otherwise.
-void same_name_impl(PyObject*& result, boost::python::object a, boost::python::object b)
-{
-   result = PyInt_FromLong(
-      get_name(a) == get_name(a2));
-}
-
-object borrowed_object(PyObject* p)
-{
-   return boost::python::object(
-        boost::python::handle<>(
-             boost::python::borrowed(a1)));
-}
-
-// This is an example Python 'C' API interface function
-extern "C" PyObject*
-same_name(PyObject* args, PyObject* keywords)
-{
-   PyObject* a1;
-   PyObject* a2;
-   PyObject* result = 0;
-
-   if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
-      return 0;
-   
-   // Use boost::bind to make an object compatible with
-   // boost::Function0<void>
-   if (boost::python::handle_exception(
-         boost::bind<void>(same_name_impl, boost::ref(result), borrowed_object(a1), borrowed_object(a2))))
-   {
-      // an exception was thrown; the Python error was set by
-      // handle_exception()
-      return 0;
-   }
-
-   return result;
-}
-
-//
-// Demonstrate form 2 of handle_exception. Not well-supported by all
-// compilers.
-//
-extern "C" PyObject*
-same_name2(PyObject* args, PyObject* keywords)
-{
-   PyObject* a1;
-   PyObject* a2;
-   PyObject* result = 0;
-
-   if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
-      return 0;
-
-   try {
-      return PyInt_FromLong(
-         get_name(borrowed_object(a1)) == get_name(borrowed_object(a2)));
-   }
-   catch(...)
-   {
-      // If an exception was thrown, translate it to Python
-      boost::python::handle_exception();
-      return 0;
-   }
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/exception_translator.html b/doc/v2/exception_translator.html deleted file mode 100644 index 8aa0fe3b..00000000 --- a/doc/v2/exception_translator.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/exception_translator.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/exception_translator.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
register_exception_translator
-
-
- -
Example(s)
-
-
- -

Introduction

- -

As described here, it - is important to make sure that exceptions thrown by C++ code do not pass - into the Python interpreter core. By default, Boost.Python translates all - C++ exceptions thrown by wrapped functions and module init functions into - Python, but the default translators are extremely limited: most C++ - exceptions will appear in Python as a RuntimeError - exception whose representation is - 'Unidentifiable C++ Exception'. To produce better - error messages, users can register additional exception translators as - described below.

- -

Functions

- -

register_exception_translator

- -
-template<class ExceptionType, class Translate>
-void register_exception_translator(Translate const& translate);
-
- -
-
Requires:
- -
- Translate is Copyconstructible, and - the following code must be well-formed: -
-void f(ExceptionType x) { translate(x); }
-
- The expression translate(x) must either throw a C++ - exception, or a subsequent call to PyErr_Occurred() - must return 1. -
- -

- -

Effects: Adds a copy of translate to the sequence of - exception translators tried when Boost.Python catches an exception that - is about to pass into Python's core interpreter. The new translator - will get "first shot" at translating all exceptions matching the catch - clause shown above. Any subsequently-registered translators will be - allowed to translate the exception earlier. A translator which cannot - translate a given C++ exception can re-throw it, and it will be handled - by a translator which was registered earlier (or by the default - translator).
-
- -

Example

-
-#include <boost/python/module.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/exception_translator.hpp>
-#include <exception>
-
-struct my_exception : std::exception
-{
-  char const* what() throw() { return "One of my exceptions"; }
-};
-
-void translate(my_exception const& e)
-{
-    // Use the Python 'C' API to set up an exception object
-    PyErr_SetString(PyExc_RuntimeError, e.what());
-}
-
-void something_which_throws()
-{
-    ...
-    throw my_exception();
-    ...
-}
-
-BOOST_PYTHON_MODULE(exception_translator_ext)
-{
-  using namespace boost::python;
-  register_exception_translator<my_exception>(&translate);
-  
-  def("something_which_throws", something_which_throws);
-}
-
-
-
- -
- -

Revised 03 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/extract.html b/doc/v2/extract.html deleted file mode 100644 index bec97f28..00000000 --- a/doc/v2/extract.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/extract.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/extract.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class extract
- -
-
-
Class extract - synopsis
- -
Class extract - constructors and destructor
- -
Class - extract observer functions
-
-
-
-
- - -
Example
-
-
- -

Introduction

- -

Exposes a mechanism for extracting C++ object values from - generalized Python objects. Note that - extract<...> can also be used to - "downcast" an object to some specific ObjectWrapper. Because - invoking a mutable python type with an argument of the same type - (e.g. list([1,2]) typically makes a copy of - the argument object, this may be the only way to access the ObjectWrapper's - interface on the original object. - -

Classes

- -

Class template extract

- -

extract<T> can be used to extract a value of - an arbitrary C++ type from an instance of object. Two usages are supported: -

    -
  1. extract<T>(o) is a temporary object -which is implicitly convertible to T (explicit conversion -is also available through the object's function-call -operator). However, if no conversion is available which can convert -o to an object of type T, a Python -TypeError exception will be raised. - -
  2. extract<T> x(o); constructs an extractor -whose check() member function can be used to ask whether -a conversion is available without causing an exception to be thrown. -
- -

Class template extract - synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  struct extract
-  {
-      typedef unspecified result_type;
-
-      extract(PyObject*);
-      extract(object const&);
-
-      result_type operator()() const;
-      operator result_type() const;
-
-      bool check() const;
-  };
-}}
-
- -

Class extract - constructors and destructor

-
-extract(PyObject* p);
-extract(object const&);
-
- -
-
Requires: The first form requires that p is non-null.
- -
Effects:Stores a pointer to the Python object managed - by its constructor argument. In particular, the reference - count of the object is not incremented. The onus is on the user - to be sure it is not destroyed before the extractor's conversion - function is called.
-
- -

Class extract - observer functions

-
-result_type operator()() const;
-operator result_type() const;
-
- -
-
Effects: Converts the stored pointer to - result_type, which is either T or - T const&. -
- -
Returns: An object of result_type - corresponding to the one referenced by the stored pointer.
- -
Throws: error_already_set - and sets a TypeError if no such conversion is - available. May also emit other unspecified exceptions thrown by - the converter which is actually used.
-
- -
-bool check() const;
-
- -
- -
Postconditions: None. In particular, note that a - return value of true does not preclude an exception - being thrown from operator result_type() or - operator()().
- -
Returns: false only if no conversion from the - stored pointer to T is available.
- -
- - -

Examples

- -
-#include <cstdio>
-using namespace boost::python;
-int Print(str s)
-{ 
-   // extract a C string from the Python string object
-   char const* c_str = extract<char const*>(s);
-
-   // Print it using printf
-   std::printf("%s\n", c_str);
-
-   // Get the Python string's length and convert it to an int
-   return extract<int>(s.attr("__len__")())
-}
-
- -The following example shows how extract can be used along with -class_<...> -to create and access an instance of a wrapped C++ class. - -
-struct X
-{
-   X(int x) : v(x) {}
-   int value() { return v; }
- private:
-   int v;
-};
-
-BOOST_PYTHON_MODULE(extract_ext)
-{
-    object x_class(
-       class_<X>("X", init<int>())
-          .def("value", &X::value))
-          ;
-        
-    // Instantiate an X object through the Python interface. 
-    // Its lifetime is now managed by x_obj.
-    object x_obj = x_class(3);
-
-    // Get a reference to the C++ object out of the Python object
-    X& x = extract<X&>(x_obj);
-    assert(x.value() == 3);
-}
-
-

Revised 15 November, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/faq.html b/doc/v2/faq.html deleted file mode 100644 index 4a6448cb..00000000 --- a/doc/v2/faq.html +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - - - - Boost.Python - FAQ - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Frequently Asked Questions (FAQs)

-
-
- -
-
I'm getting the "attempt to return dangling - reference" error. What am I doing wrong?
- -
Is return_internal_reference - efficient?
- -
How can I wrap functions which take C++ - containers as arguments?
- -
fatal error C1204:Compiler limit:internal - structure overflow
- -
How do I debug my Python extensions?
- -
Why doesn't my *= operator - work?
- -
Does Boost.Python work with Mac OS X?
- -
How can I find the existing PyObject that holds a - C++ object?
- -
How can I wrap a function which needs to take - ownership of a raw pointer?
-
-
- -

I'm getting the "attempt to return dangling - reference" error. What am I doing wrong?

- That exception is protecting you from causing a nasty crash. It usually - happens in response to some code like this: -
-period const& get_floating_frequency() const
-{
-  return boost::python::call_method<period const&>(
-      m_self,"get_floating_frequency");
-}
-
- And you get: -
-ReferenceError: Attempt to return dangling reference to object of type:
-class period
-
- -

In this case, the Python method invoked by call_method - constructs a new Python object. You're trying to return a reference to a - C++ object (an instance of class period) contained within - and owned by that Python object. Because the called method handed back a - brand new object, the only reference to it is held for the duration of - get_floating_frequency() above. When the function returns, - the Python object will be destroyed, destroying the instance of - class period, and leaving the returned reference dangling. - That's already undefined behavior, and if you try to do anything with - that reference you're likely to cause a crash. Boost.Python detects this - situation at runtime and helpfully throws an exception instead of letting - you do that.
-  

-
- -

Is return_internal_reference efficient?

- -
- Q: I have an object composed of 12 doubles. A const& to - this object is returned by a member function of another class. From the - viewpoint of using the returned object in Python I do not care if I get - a copy or a reference to the returned object. In Boost.Python Version 2 - I have the choice of using copy_const_reference or - return_internal_reference. Are there considerations that would lead me - to prefer one over the other, such as size of generated code or memory - overhead? - -

A: copy_const_reference will make an instance with storage - for one of your objects, size = base_size + 12 * sizeof(double). - return_internal_reference will make an instance with storage for a - pointer to one of your objects, size = base_size + sizeof(void*). - However, it will also create a weak reference object which goes in the - source object's weakreflist and a special callback object to manage the - lifetime of the internally-referenced object. My guess? - copy_const_reference is your friend here, resulting in less overall - memory use and less fragmentation, also probably fewer total - cycles.

-
-
- -

How can I wrap functions which take C++ - containers as arguments?

- -

Ralf W. Grosse-Kunstleve provides these notes:

- -
    -
  1. - Using the regular class_<> wrapper: -
    -class_<std::vector<double> >("std_vector_double")
    -  .def(...)
    -  ...
    -  ;
    -
    - This can be moved to a template so that several types (double, int, - long, etc.) can be wrapped with the same code. This technique is used - in the file - -
    - scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h -
    - in the "scitbx" package. The file could easily be modified for - wrapping std::vector<> instantiations. - -

    This type of C++/Python binding is most suitable for containers - that may contain a large number of elements (>10000).

    -
  2. - -
  3. - Using custom rvalue converters. Boost.Python "rvalue converters" - match function signatures such as: -
    -void foo(std::vector<double> const& array); // pass by const-reference
    -void foo(std::vector<double> array); // pass by value
    -
    - Some custom rvalue converters are implemented in the file - -
    - scitbx/include/scitbx/boost_python/container_conversions.h -
    - This code can be used to convert from C++ container types such as - std::vector<> or std::list<> to Python tuples and vice - versa. A few simple examples can be found in the file - -
    - scitbx/array_family/boost_python/regression_test_module.cpp -
    - Automatic C++ container <-> Python tuple conversions are most - suitable for containers of moderate size. These converters generate - significantly less object code compared to alternative 1 above. -
  4. -
- A disadvantage of using alternative 2 is that operators such as - arithmetic +,-,*,/,% are not available. It would be useful to have custom - rvalue converters that convert to a "math_array" type instead of tuples. - This is currently not implemented but is possible within the framework of - Boost.Python V2 as it will be released in the next couple of weeks. [ed.: - this was posted on 2002/03/10] - -

It would also be useful to also have "custom lvalue converters" such - as std::vector<> <-> Python list. These converters would - support the modification of the Python list from C++. For example:

- -

C++:

-
-void foo(std::vector<double>& array)
-{
-  for(std::size_t i=0;i<array.size();i++) {
-    array[i] *= 2;
-  }
-}
-
- Python: -
->>> l = [1, 2, 3]
->>> foo(l)
->>> print l
-[2, 4, 6]
-
- Custom lvalue converters require changes to the Boost.Python core library - and are currently not available. - -

P.S.:

- -

The "scitbx" files referenced above are available via anonymous - CVS:

-
-cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
-cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
-
-
- -

fatal error C1204:Compiler limit:internal - structure overflow

- -
- Q: I get this error message when compiling a large source - file. What can I do? - -

A: You have two choices:

- -
    -
  1. Upgrade your compiler (preferred)
  2. - -
  3. - Break your source file up into multiple translation units. - -

    my_module.cpp:

    -
    -...
    -void more_of_my_module();
    -BOOST_PYTHON_MODULE(my_module)
    -{
    -   def("foo", foo);
    -   def("bar", bar);
    -   ...
    -   more_of_my_module();
    -}
    -
    - more_of_my_module.cpp: -
    -void more_of_my_module()
    -{
    -   def("baz", baz);
    -   ...
    -}
    -
    - If you find that a class_<...> declaration - can't fit in a single source file without triggering the error, you - can always pass a reference to the class_ object to a - function in another source file, and call some of its member - functions (e.g. .def(...)) in the auxilliary source - file: - -

    more_of_my_class.cpp:

    -
    -void more_of_my_class(class<my_class>& x)
    -{
    -   x
    -     .def("baz", baz)
    -     .add_property("xx", &my_class::get_xx, &my_class::set_xx)
    -     ;
    -
    -   ...
    -}
    -
    -
  4. -
-
-
- -

How do I debug my Python extensions?

- -

Greg Burley gives the following answer for Unix GCC users:

- -
- Once you have created a boost python extension for your c++ library or - class, you may need to debug the code. Afterall this is one of the - reasons for wrapping the library in python. An expected side-effect or - benefit of using BPL is that debugging should be isolated to the c++ - library that is under test, given that python code is minimal and - boost::python either works or it doesn't. (ie. While errors can occur - when the wrapping method is invalid, most errors are caught by the - compiler ;-). - -

The basic steps required to initiate a gdb session to debug a c++ - library via python are shown here. Note, however that you should start - the gdb session in the directory that contains your BPL my_ext.so - module.

-
-(gdb) target exec python
-(gdb) run
- >>> from my_ext import *
- >>> [C-c]
-(gdb) break MyClass::MyBuggyFunction
-(gdb) cont
- >>> pyobj = MyClass()
- >>> pyobj.MyBuggyFunction()
-Breakpoint 1, MyClass::MyBuggyFunction ...
-Current language:  auto; currently c++
-(gdb) do debugging stuff
-
-
- -

Greg's approach works even better using Emacs' "gdb" - command, since it will show you each line of source as you step through - it.

- -

On Windows, my favorite debugging solution is the debugger that - comes with Microsoft Visual C++ 7. This debugger seems to work with code - generated by all versions of Microsoft and Metrowerks toolsets; it's rock - solid and "just works" without requiring any special tricks from the - user.

- -

Unfortunately for Cygwin and MinGW users, as of this writing gdb on - Windows has a very hard time dealing with shared libraries, which could - make Greg's approach next to useless for you. My best advice for you is - to use Metrowerks C++ for compiler conformance and Microsoft Visual - Studio as a debugger when you need one.

- -

Debugging extensions through Boost.Build

- If you are launching your extension module tests with Boost.Build using the - boost-python-runtest rule, you can ask it to launch your - debugger for you by adding "-sPYTHON_LAUNCH=debugger" to your bjam - command-line: -
-bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
-bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
-
- It can also be extremely useful to add the -d+2 option when - you run your test, because Boost.Build will then show you the exact - commands it uses to invoke it. This will invariably involve setting up - PYTHONPATH and other important environment variables such as - LD_LIBRARY_PATH which may be needed by your debugger in order to get - things to work right. -
- -

Why doesn't my *= operator work?

- -
- Q: I have exported my class to python, with many overloaded - operators. it works fine for me except the *= - operator. It always tells me "can't multiply sequence with non int - type". If I use p1.__imul__(p2) instead of - p1 *= p2, it successfully executes my code. What's - wrong with me? - -

A: There's nothing wrong with you. This is a bug in Python - 2.2. You can see the same effect in Pure Python (you can learn a lot - about what's happening in Boost.Python by playing with new-style - classes in Pure Python).

-
->>> class X(object):
-...     def __imul__(self, x):
-...         print 'imul'
-...
->>> x = X()
->>> x *= 1
-
- To cure this problem, all you need to do is upgrade your Python to - version 2.2.1 or later. -
-
- -

Does Boost.Python work with Mac OS X?

- -
-

The short answer: as of January 2003, unfortunately not.

- -

The longer answer: using Mac OS 10.2.3 with the December Developer's - Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles - fine, including the examples. However, there are problems at runtime - (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). - Solutions are currently unknown.

- -

It is known that under certain circumstances objects are - double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html - for details. It is not clear however if this problem is related to the - Boost.Python runtime issues.

-
-
- -

How can I find the existing PyObject that holds a C++ - object?

- -
- "I am wrapping a function that always returns a pointer to an - already-held C++ object." -
- One way to do that is to hijack the mechanisms used for wrapping a class - with virtual functions. If you make a wrapper class with an initial - PyObject* constructor argument and store that PyObject* as "self", you - can get back to it by casting down to that wrapper type in a thin wrapper - function. For example: -
-class X { X(int); virtual ~X(); ... };
-X* f();  // known to return Xs that are managed by Python objects
-
-
-// wrapping code
-
-struct X_wrap : X
-{
-    X_wrap(PyObject* self, int v) : self(self), X(v) {}
-    PyObject* self;
-};
-
-handle<> f_wrap()
-{
-    X_wrap* xw = dynamic_cast<X_wrap*>(f());
-    assert(xw != 0);
-    return handle<>(borrowed(xw->self));
-}
-
-...
-
-def("f", f_wrap());
-class_<X,X_wrap>("X", init<int>())
-   ...
-   ;
-
- Of course, if X has no virtual functions you'll have to use - static_cast instead of dynamic_cast with no - runtime check that it's valid. This approach also only works if the - X object was constructed from Python, because - Xs constructed from C++ are of course never - X_wrap objects. - -

Another approach to this requires you to change your C++ code a bit; - if that's an option for you it might be a better way to go. work we've - been meaning to get to anyway. When a shared_ptr<X> is - converted from Python, the shared_ptr actually manages a reference to the - containing Python object. When a shared_ptr<X> is converted back to - Python, the library checks to see if it's one of those "Python object - managers" and if so just returns the original Python object. So you could - just write object(p) to get the Python object back. To - exploit this you'd have to be able to change the C++ code you're wrapping - so that it deals with shared_ptr instead of raw pointers.

- -

There are other approaches too. The functions that receive the Python - object that you eventually want to return could be wrapped with a thin - wrapper that records the correspondence between the object address and - its containing Python object, and you could have your f_wrap function - look in that mapping to get the Python object out.

- -

How can I wrap a function which needs to take - ownership of a raw pointer?

- -
- Part of an API that I'm wrapping goes something like this: -
-struct A {}; struct B { void add( A* ); }
-where B::add() takes ownership of the pointer passed to it.
-
- -

However:

-
-a = mod.A()
-b = mod.B()
-b.add( a )
-del a         
-del b
-# python interpreter crashes 
-# later due to memory corruption.
-
- -

Even binding the lifetime of a to b via - with_custodian_and_ward doesn't prevent the python object a from - ultimately trying to delete the object it's pointing to. Is there a way - to accomplish a 'transfer-of-ownership' of a wrapped C++ object?

- -

--Bruce Lowery

-
- Yes: Make sure the C++ object is held by auto_ptr: -
-class_<A, std::auto_ptr<A> >("A")
-    ...
-    ;
-
- Then make a thin wrapper function which takes an auto_ptr parameter: -
-void b_insert(B& b, std::auto_ptr<A> a)
-{
-    b.insert(a.get());
-    a.release();
-}
-
- Wrap that as B.add. Note that pointers returned via manage_new_object - will also be held by auto_ptr, so this transfer-of-ownership - will also work correctly. -
- -

Revised - - 23 January, 2003 - -

- -

© Copyright Dave Abrahams 2002-2003. All - Rights Reserved.

- - - diff --git a/doc/v2/feb2002.html b/doc/v2/feb2002.html deleted file mode 100644 index bc305a47..00000000 --- a/doc/v2/feb2002.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - Boost.Python - February 2002 Progress Report - - - - -
-

-

- -
-

Boost.Python

- -

February 2002 Progress Report

-
-
- -

Contents

- -
-
Python10 Conference Report - -
Boost.Python v2 Progress - -
-
-
Documentation - -
Overhaul of - to_python/from_python - conversion mechanism - -
Miscellaneous -
-
- -

Python10 Conference Report

- I spent the first week of February at the Python10 conference - in Alexandria, VA. I'm including this experience report - for two reasons: firstly, it documents where my time was - used. Secondly, a public presence for Boost.Python and - interaction between the Python and C++ communities is - important to the future of Boost.Python, which in turn is - important to the Kull Project. - -

Andy Koenig, of all people, was the keynote speaker of - this year's opening plenary session. He presented his - "impressions of a polyglot outsider", which - studiously avoided any mention of C++ until the end of his - talk, when he was asked about standardization. I was - surprised to learn that the C++ community at large wanted a - few more years before beginning but when ANSI accepted - HP's request for a standard, the process was forced to - start: it was a matter of participating or having - standardization proceed without one's input. Andy managed - to highlight very effectively the balance of strengths in - Python, one of the most important being its support for - extension via libraries. In many ways that makes Python a - good analogue for C++ in the interpreted world - -

There were several kind mentions of the Boost.Python - library from people who found it indispensable. I was - particularly happy that Karl MacMillan, Michael Droettboom, - and Ichiro Fujinaga from Johns Hopkins is using it to do OCR - on a vast library of music notation, since in a previous life - I was an author of music notation software. These guys are - also drawing on Ullrich Koethe's VIGRA library for image - manipulation (Ullrich has been a major contributor to - Boost.Python). They also have a system for writing the - Boost.Python wrapper code in C++ comments, which allows them - to keep all of the code in one place. I've asked them to - send me some information on that. - -

The development of Swig has been gaining momentum again - (the basic description at - www.boost.org/libs/python/doc/comparisons.html still - applies). The talk given about it by David Beazly was very - well-attended, and they appear to have quite a few users. - Swig's strengths (coverage of many langauages) and - weaknesses (incomplete C++ language support) haven't - changed, although the C++ support seems to have improved - considerably - they now claim to have a complete model of the - C++ type system. It seems to be mostly geared at wrapping - what Walter Landry calls "C-Tran": C++ code which - traffics in built-in types with little use of abstraction. - I'm not knocking that, either: I'm sure a lot of that - code exists, so it's a valuable service. One feature Swig - has which I'd like to steal is the ability to unwrap a - single Python argument into multiple C++ arguments, for - example, by converting a Python string into a pointer and - length. When his talk was over, David approached me about a - possible joint workshop on language binding, which sounds - like a fun idea to me. - -

I spent some considerable time talking with Steven Knight, - the leader of the Scons build tool effort. We had a lot to - share with one another, and I gained a much better - appreciation for many of the Scons design decisions. Scons - seems to be concentrating on being the ultimate build system - substrate, and Steve seemed to think that we were on the - right track with our high-level design. We both hope that the - Boost.Build V2 high-level architecture can eventually be - ported to run on top of Scons. - -

They also have a highly-refined and successful development - procedure which I'd like to emulate for Boost.Build V2. - Among many other things they do, their source-control system - automatically ensures that when you check in a new test, it - is automatically run on the currently checked-in state of the - code, and is expected to fail -- a relatively obvious good - idea which I've never heard before. - -

Guido Van Rossum's "State of the Python - Union" address was full of questions for the community - about what should be done next, but the one idea Guido seemed - to stress was that core language stability and continuing - library development would be a good idea (sound familiar?) I - mentioned the Boost model as a counterpoint to the idea of - something like CPAN (the massive Perl library archives), and - it seemed to generate some significant interest. I've - offered to work with anyone from the Python community who - wants to set up something like Boost. - -

There was some discussion of "string - interpolation" (variable substitution in strings), and - Guido mentioned that he had some thoughts about the - strengths/weaknesses of Python's formatting interface. It - might be useful for those working on formatting for boost to - contact him and find out what he has to say. - -

Ka-Ping Yee demoed a Mailman discussion thread weaver. - This tool weaves the various messages in a discussion thread - into a single document so you can follow the entire - conversation. Since we're looking very seriously at - moving Boost to Mailman, this could be a really useful thing - for us to have. If we do this, we'll move the yahoogroups - discussions into the mailman archive so old discussions can - be easily accessed in the same fashion. - -

And, just because it's cool, though perhaps not - relevant: http://homepages.ulb.ac.be/~arigo/psyco/ is a - promising effort to accelerate the execution of Python code - to speeds approaching those of compiled languages. It - reminded me a lot of Todd Veldhuizen's research into - moving parts of C++ template compilation to runtime, only - coming from the opposite end of things. - -

Boost.Python v2 Progress

- Here's what actually got accomplished. - -

Documentation

- -

My first priority upon returning from Python10 was to get - some documentation in place. After wasting an unfortunate - amount of time looking at automatic documentation tools which - don't quite work, I settled down to use Bill Kempf's - HTML templates designed to be a boost standard. While they - are working well, it is highly labor-intensive. - -

I decided to begin with the high-level reference material, - as opposed to tutorial, narrative, or nitty-gritty details of - the framework. It seemed more important to have a precise - description of the way the commonly-used components work than - to have examples in HTML (since we already have some test - modules), and since the low-level details are much - less-frequently needed by users it made sense for me to - simply respond to support requests for the time being. - -

After completing approximately 60% of the high-level docs - (currently checked in to libs/python/doc/v2), I found myself - ready to start documenting the mechanisms for creating - to-/from-python converters. This caused a dilemma: I had - realized during the previous week that a much simpler, - more-efficient, and easier-to-use implementation was - possible, but I hadn't planned on implementing it right - away, since what was already in place worked adequately. I - had also received my first query on the C++-sig about how to - write such a converter - -

Given the labor-intensive nature of documentation writing, - I decided it would be a bad idea to document the conversion - mechanism if I was just going to rewrite it. Often the best - impetus for simplifying a design is the realization that - understandably documenting its current state would be too - difficult, and this was no exception. - -

Overhaul of - to_python/from_python conversion - mechanism

- -

There were two basic realizations involved here: - -

    -
  1. to_python conversion could be a one-step - process, once an appropriate conversion function is found. - This allows elimination of the separate indirect - convertibility check - -
  2. There are basically two categories of from_python - conversions: those which lvalues stored within or held by - the Python object (essentially extractions), like what - happens when an instance of a C++ class exposed with class_ - is used as the target of a wrapped member function), and - those in which a new rvalue gets created, as when a Python - Float is converted to a C++ - complex<double> or a Python tuple is - converted to a C++ std::vector<>. From - the client side, there are two corresponding categories of - conversion: those which demand an lvalue conversion and - those which can accept an lvalue or an rvalue conversion. -
- The latter realization allowed the following collapse, which - considerably simplified things: - -
- - - - - - - - - - - - - - - - - -
Target Type - - Eligible Converters - -
T - - T rvalue or lvalue - -
T const - -
T volatile - -
T const volatile - -
T const& - -
T const* - - T lvalue - -
T volatile* - -
T const volatile* - -
T& - -
T volatile& - -
T const volatile& - -
T* const& - -
T const* const& - -
T volatile*const& - -
T const volatile*const& -
-
- This job included the following additional enhancements: - -
    -
  • Elimination of virtual functions, which cause object - code bloat - -
  • Registration of a single converter function for all - lvalue conversions, two for all rvalue conversions - -
  • Killed lots of unneeded code - -
  • Increased opacity of registry interface - -
  • Eliminated all need for decorated runtime type - identifiers - -
  • Updated test modules to reflect new interface - -
  • Eliminated the need for users to worry about converter - lifetime issues Additional Builtin Conversion Enhancements - -
  • Support for complex<float>, - complex<double>, and complex<long double> - conversions - -
  • Support for bool conversions - -
  • NULL pointers representable by None in Python - -
  • Support for conversion of Python classic classes to - numeric types -
- -

Miscellaneous

- These don't fit easily under a large heading: - -
    -
  • Support CallPolicies for class member functions - -
  • from_python_data.hpp: revamped type alignment - metaprogram so that it's fast enough for KCC - -
  • classfwd.hpp header forward-declares class_<T> - -
  • indirect_traits.hpp: - -
  • added is_pointer_to_reference - -
  • fixed bugs - -
  • Reduced recompilation dependencies - -
  • msvc_typeinfo works around broken MS/Intel typeid() - implementation - -
  • Many fixes and improvements to the type_traits library - in order to work around compiler bugs and suppress warnings - -
  • Eliminated the need for explicit acquisition of - converter registrations - -
  • Expanded constructor support to 6 arguments - -
  • Implemented generalized pointer lifetime support - -
  • Updated code generation for returning.hpp - -
  • Tracked down and fixed cycle GC bugs - -
  • Added comprehensive unit tests for destroy_reference, - pointer_type_id, select_from_python, complex<T>, - bool, and classic class instance conversions -
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams - 2002. All Rights Reserved. - diff --git a/doc/v2/from_python.html b/doc/v2/from_python.html deleted file mode 100644 index 6d08f733..00000000 --- a/doc/v2/from_python.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Boost.Python - <boost/python/from_python.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/from_python.hpp>

-
-


- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class - Templatefrom_python - -
-
-
Class Template - from_python synopsis - -
Class Template - from_python constructor - -
Class Template - from_python observer functions -
-
- -
Example -
-
- -

Introduction

- -

<boost/python/from_python.hpp> introduces a class - template from_python<T> for extracting a C++ object of - type T from a Python object. - -

Classes

- -

Class Template - from_python<class T>

- -

from_python<T> is the type used internally by - Boost.Python to extract C++ function arguments from a Python argument tuple - when calling a wrapped function. It can also be used directly to make - similar conversions in other contexts. - -

Class Template - from_python synopsis

-
-namespace boost { namespace python
-{
-   template <class T>
-   struct from_python : private boost::noncopyable // Exposition only.
-       // from_python<T> meets the NonCopyable requirements
-   {
-      from_python(PyObject*);
-      bool convertible() const;
-      convertible-to-T operator()(PyObject*) const;
-   };
-}
-
- -

Class Template - from_python constructor

-
-from_python(PyObject* p);
-
- -
-
Requires: p != 0 - -
Effects: Constructs a from_python object suitable - for extracting a C++ object of type T from p. -
- -

Class Template - from_python observer functions

-
-bool convertible() const;
-
- -
-
Returns: false if the conversion cannot succeed. - This indicates that either: - -
-
    -
  1. No from_python_converter was registered for - T, or - -
  2. any such converter rejected the constructor argument - p by returning 0 from its - convertible() function -
- Note that conversion may still fail in operator() due to - an exception. - -
Throws: nothing - -
Rationale: Because from_python<> is used in - overload resolution, and throwing an exception can be slow, it is useful - to be able to rule out a broad class of unsuccessful conversions without - throwing an exception. -
-
-convertible-to-T operator()(PyObject* p) const;
-
- -
-
Requires: *p refers to the same object which was - passed to the constructor, and convertible() returns - true. - -
Effects: performs the conversion - -
Returns: an object convertible to T. -
- -

Example

-
-#include <string>
-#include <boost/python/from_python.hpp>
-
-// If a std::string can be extracted from p, return its
-// length. Otherwise, return 0.
-std::size_t length_if_string(PyObject* p)
-{
-   from_python<std::string> converter(p);
-   if (!converter.convertible())
-      return 0;
-   else
-      return converter(p).size();
-}
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/handle.html b/doc/v2/handle.html deleted file mode 100644 index 947bc82c..00000000 --- a/doc/v2/handle.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/handle.hpp> - - - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/handle.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - handle
- -
-
-
Class handle - synopsis
- -
Class handle - constructors and destructor
- -
Class handle - modifier functions
- -
Class handle - observer functions
-
-
-
-
- -
Functions
- -
-
-
borrowed
- -
allow_null
-
-
-
-
- -

Introduction

- -

<boost/python/handle.hpp> provides - class template handle, a smart pointer for - managing reference-counted Python objects.

- -

Classes

- -

Class template handle

- -

handle is a smart pointer to a Python object type; it - holds a pointer of type T*, where T is its template - parameter. T must be either a type derived from - PyObject or a POD type - whose initial sizeof(PyObject) bytes are layout-compatible - with PyObject. Use handle<> at the - boundary between the Python/'C' API and high-level code; prefer object for a generalized - interface to Python objects.

- -

In this document, the term "upcast" refers to an - operation which converts a pointer Y* to a base class - pointer T* via static_cast<T*> if - Y is derived from T, or via C-style cast - (T*) if it is not. However, in the latter case the "upcast" - is ill-formed if the initial sizeof(PyObject) bytes of - Y are not layout-compatible with PyObject.

- -

Class template handle - synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  class handle
-  {
-      typedef unspecified-member-function-pointer bool_type;
-
-   public: // types
-      typedef T element_type;
-
-   public: // member functions
-      ~handle();
-
-      template <class Y>
-      explicit handle(detail::borrowed<null_ok<Y> >* p);
-
-      template <class Y>
-      explicit handle(null_ok<detail::borrowed<Y> >* p);
-
-      template <class Y>
-      explicit handle(detail::borrowed<Y>* p);
-
-      template <class Y>
-      explicit handle(null_ok<Y>* p);
-
-      template <class Y>
-      explicit handle(Y* p);
-
-      handle();
-
-      handle& operator=(handle const& r);
-
-      template<typename Y>
-      handle& operator=(handle<Y> const & r); // never throws
-
-
-      template <typename Y>
-      handle(handle<Y> const& r);
-
-      handle(handle const& r);
-
-      T* operator-> () const;
-      T& operator* () const;
-      T* get() const;
-      void reset();
-      T* release();
-
-      operator bool_type() const; // never throws
-   private:
-      T* m_p;
-  };
-  
-  template <class T> struct null_ok;
-  namespace detail { template <class T> struct borrowed; }
-}}
-
- -

Class handle constructors - and destructor

-
-virtual ~handle();
-
- -
-
Effects: - Py_XDECREF(upcast<PyObject*>(m_p))
-
-
-template <class Y>
-explicit handle(detail::borrowed<null_ok<Y> >* p);
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(p)); - m_p = upcast<T*>(p);
-
-
-template <class Y>
-explicit handle(null_ok<detail::borrowed<Y> >* p);
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(p)); - m_p = upcast<T*>(p);
-
-
-template <class Y>
-explicit handle(detail::borrowed<Y>* p);
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(p)); - m_p = upcast<T*>(expect_non_null(p));
-
-
-template <class Y>
-explicit handle(null_ok<Y>* p);
-
- -
-
Effects: - m_p = upcast<T*>(p);
-
-
-template <class Y>
-explicit handle(Y* p);
-
- -
-
Effects: - m_p = upcast<T*>(expect_non_null(p));
-
-
-handle();
-
- -
-
Effects: m_p = 0;
-
-
-template <typename Y>
-handle(handle<Y> const& r);
-handle(handle const& r);
-
- -
-
Effects: - m_p = r.m_p; Py_XINCREF(upcast<PyObject*>(m_p));
-
- -

Class handle - modifiers

-
-handle& operator=(handle const& r);
-template<typename Y>
-handle& operator=(handle<Y> const & r); // never throws
-
- -
-
Effects: - Py_XINCREF(upcast<PyObject*>(r.m_p)); Py_XDECREF( - upcast<PyObject*>(m_p)); m_p = r.m_p;
-
-
-T* release();
-
- -
-
Effects: T* x = m_p; m_p = 0;return - x;
-
-
-void reset();
-
- -
-
Effects: - *this = handle<T>();
-
- -

Class handle - observers

-
-T* operator-> () const;
-T* get() const;
-
- -
-
Returns: m_p;
-
-
-T& operator* () const;
-
- -
-
Returns: *m_p;
-
-
-operator bool_type() const; // never throws
-
- -
-
Returns: 0 if m_p == 0, a pointer - convertible to true otherwise.
-
- -

Functions

- -

borrowed

-
-template <class T>
-detail::borrowed<T>* borrowed(T* p)
-{
-    return (detail::borrowed<T>*)p;
-}
-
- -

allow_null

-
-template <class T>
-null_ok<T>* allow_null(T* p)
-{
-    return (null_ok<T>*)p;
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/has_back_reference.html b/doc/v2/has_back_reference.html deleted file mode 100644 index ab92e353..00000000 --- a/doc/v2/has_back_reference.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/has_back_reference.hpp> - - - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/has_back_reference.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - has_back_reference
- -
-
-
Class template - has_back_reference synopsis
-
-
- -
Example(s)
-
-
-
-
- -

Introduction

- -

<boost/python/has_back_reference.hpp> defines the - traits class template has_back_reference<>, which can - be specialized by the user to indicate that a wrapped class instance - holds a PyObject* corresponding to a Python object.

- -

Classes

- -

Class template - has_back_reference

- -

A unary metafunction whose value is true iff its argument - is a pointer_wrapper<>.

- -

Class template - has_back_reference synopsis

-
-namespace boost { namespace python
-{
-    template<class WrappedClass> class has_back_reference
-    { 
-        static unspecified value = false;
-    };
-}}
-
- -

A "traits - class" which is inspected by Boost.Python to determine how wrapped - classes can be constructed.

- -
-
value is an integral constant convertible to bool of - unspecified type.
- -
Specializations may substitute a value convertible to - true for value iff for each invocation of - class_<WrappedClass>::def(init<type-sequence... - >()), there exists a corresponding constructor - WrappedClass::WrappedClass(PyObject*, type-sequence... - ). If such a specialization exists, the - WrappedClass constructors will be called with a "back - reference" pointer to the corresponding Python object whenever they are - invoked from Python.
-
- -

Example

- -

C++ module definition

-
-#include <boost/python/class.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/has_back_reference.hpp>
-#include <boost/python/handle.hpp>
-#include <boost/shared_ptr.hpp>
-
-using namespace boost::python;
-
-struct X
-{
-    X(PyObject* self) : m_self(self), m_x(0) {}
-    X(PyObject* self, int x) : m_self(self), m_x(x) {}
-    
-    handle<> self() { return handle<>(borrowed(m_self)); }
-    int get() { return m_x; }
-    void set(int x) { m_x = x; }
-
-    PyObject* m_self;
-    int x;
-};
-
-// specialize has_back_reference for X
-namespace boost { namespace python
-{
-  template <>
-  struct has_back_reference<X>
-  {
-     enum { value = true; }
-  }
-}}
-
-struct Y
-{
-    Y() : m_x(0) {}
-    Y(int x) : m_x(x) {}
-    int get() { return m_x; }
-    void set(int x) { m_x = x; }
-
-    int x;
-};
-
-boost::shared_ptr<Y> Y_self(boost::shared_ptr<Y> self) const { return self; }
-
-BOOST_PYTHON_MODULE(back_references)
-{
-    class_<X>("X")
-       .def(init<int>())
-       .def("self", &X::self)
-       .def("get", &X::get)
-       .def("set", &X::set)
-       ;
-
-    class_<Y, shared_ptr<Y> >("Y")
-       .def(init<int>())
-       .def("get", &Y::get)
-       .def("set", &Y::set)
-       .def("self", Y_self)
-       ;
-}
-
- The following Python session illustrates that x.self() - returns the same Python object on which it is invoked, while - y.self() must create a new Python object which refers to the - same Y instance. - -

Python code

-
->>> from back_references import *
->>> x = X(1)
->>> x2 = x.self()
->>> x2 is x
-1
->>> (x.get(), x2.get())
-(1, 1)
->>> x.set(10)
->>> (x.get(), x2.get())
-(10, 10)
->>>
->>>
->>> y = Y(2)
->>> y2 = y.self()
->>> y2 is y
-0
->>> (y.get(), y2.get())
-(2, 2)
->>> y.set(20)
->>> (y.get(), y2.get())
-(20, 20)
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/header.html b/doc/v2/header.html deleted file mode 100644 index 73d3aea6..00000000 --- a/doc/v2/header.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - - Boost.Python - <{{header}}> - - - -
-

-

- -
-

Boost.Python

- -

Header <{{header}}>

-
-
- -

Contents

- -
-
Introduction - -
Macros - -
-
-
{{macro name}} -
- -
Values - -
-
-
{{value name}} -
- -
Types - -
-
-
{{type name}} -
- -
Classes - -
-
-
Class {{name}} - -
-
-
Class {{name}} synopsis - -
Class {{name}} - constructors and destructor - -
Class {{name}} comparison functions - -
Class {{name}} modifier functions - -
Class {{name}} observer functions - -
Class {{name}} static functions -
-
- -
Functions - -
-
-
{{function name}} -
- -
Objects - -
-
-
{{object name}} -
- -
Example(s) -
-
- -

Introduction

- -

{{Introductory text}} - -

Macros

- -

{{Macro specifications}} - -

Values

- -

{{Value specifications}} - -

Types

- -

{{Type specifications}} - -

Classes

- -

Class {{name}}

- -

{{class overview text}} - -

Class {{name}} synopsis

-
-namespace boost
-{
-    class {{name}}
-  {
-  };
-};
-
- -

Class {{name}} constructors and - destructor

-
-{{constructor}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
-
-{{destructor}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} comparison - functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} modifier - functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} observer - functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Class {{name}} static functions

-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Functions

-
-
-
-{{function}}
-
- -
-
Requires: {{text}} - -
Effects: {{text}} - -
Postconditions: {{text}} - -
Returns: {{text}} - -
Throws: {{text}} - -
Complexity: {{text}} - -
Rationale: {{text}} -
- -

Objects

- -

{{Object specifications}} - -

Example(s)

- -

{{Example(s)}} - -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html deleted file mode 100644 index c830a6c9..00000000 --- a/doc/v2/implicit.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/implicit.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/implicit.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
Function Template - implicitly_convertible
-
-
- -
Example
-
-
- -

Introduction

- implicitly_convertible allows Boost.Python to implicitly - take advantage of a C++ implicit or explicit conversion when matching - Python objects to C++ argument types. - -

Functions

- -

Function template - implicitly_convertible

-
-template <class Source, class Target>
-void implicitly_convertible();
-
- - - - - - - - - - - - - - - - - - - - - -
- implicitly_convertible template parameters
-
ParameterDescription
SourceThe source type of the implicit conversion
TargetThe target type of the implicit conversion
- -
-
Requires: The declaration Target t(s);, where - s is of type Source, is valid.
- -
Effects: registers an rvalue from_python - converter to Target which can succeed for any - PyObject* p iff there exists any registered converter - which can produce Source rvalues
- -
Rationale: C++ users expect to be able to take advantage of - the same sort of interoperability in Python as they do in C++.
-
- -

Example

- -

C++ module definition

-
-#include <boost/python/class.hpp>
-#include <boost/python/implicit.hpp>
-#include <boost/python/module.hpp>
-
-using namespace boost::python;
-
-struct X
-{
-    X(int x) : v(x) {}
-    operator int() { return v; }
-    int v;
-};
-
-int x_value(X const& x)
-{
-    return x.v;
-}
-
-X make_x(int n) { return X(n); }
-
-BOOST_PYTHON_MODULE(implicit_ext)
-{
-    def("x_value", x_value);
-    def("make_x", make_x);
-
-    class_<X>("X", 
-        init<int>())
-        ;
-
-    implicitly_convertible<X,int>();
-    implicitly_convertible<int,X>();
-}
-
- -

Python code

-
->>> from implicit_ext import *
->>> x_value(X(42))
-42
->>> x_value(42)
-42
->>> x = make_x(X(42))
->>> x_value(x)
-42
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/index.html b/doc/v2/index.html deleted file mode 100644 index 6f5150fb..00000000 --- a/doc/v2/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - Automatic redirection failed, please go to ../index.html. - - - diff --git a/doc/v2/init.html b/doc/v2/init.html deleted file mode 100644 index 644a54e7..00000000 --- a/doc/v2/init.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/init.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Headers <boost/python/init.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
init-expressions
- -
Classes
- -
-
-
Class template init
- -
-
-
Class template - init synopsis
- -
Class init - constructors
- -
-
- -
Class template - optional
- -
-
-
Class template - optional synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

<boost/python/init.hpp> defines the interface for - exposing C++ constructors to Python as extension class - __init__ functions.

- -

init-expressions

- An init-expression is used to describe a family of - __init__ methods to be generated for an extension class, and - the result has the following properties: - -
-
-
docstring: An ntbs - whose value will bound to the method's __doc__ - attribute
- -
keywords: A keyword-expression which will be - used to name (a trailing subsequence of) the arguments to the - generated __init__ function(s).
- -
call policies: An instance of a model of CallPolicies.
- -
argument types: An MPL sequence of C++ argument types - which will be used to construct the wrapped C++ object. An init - expression has one or more - valid prefixes which are given by a sequence of - prefixes of its argument types.
-
-
- -

Classes

- -

Class template init<T1 = - unspecified, T2 = - unspecified,...Tn = - unspecified>

- -

A MPL sequence which - can be used to specify a family of one or more __init__ - functions. Only the last Ti supplied - may be an instantiation of optional<...>.

- -

Class template init - synopsis

-
-namespace boost { namespace python
-{
-  template <T1 = unspecified,...Tn = unspecified>
-  struct init
-  {
-      init(char const* doc = 0);
-      template <class Keywords> init(Keywords const& kw, char const* doc = 0);
-      template <class Keywords> init(char const* doc, Keywords const& kw);
-
-      template <class CallPolicies>
-      unspecified operator[](CallPolicies const& policies) const
-  };
-}}
-
- -

Class template init - constructors

-
-init(char const* doc = 0);
-template <class Keywords> init(Keywords const& kw, char const* doc = 0);
-template <class Keywords> init(char const* doc, Keywords const& kw);
-
- -
-
Requires: If supplied, doc is an ntbs. If supplied, kw is the - result of a
- -
Effects: The result is an init-expression whose - docstring is doc and whose keywords are - a reference to kw. If the first form is used, the - resulting expression's keywords are empty. The expression's - call policies are an instance of default_call_policies. - If Tn is optional<U1, U2,... - Um>, the - expression's valid prefixes are given by:
- -
-
- (T1, T2,...Tn-1), - (T1, T2,...Tn-1 - , U1), - (T1, T2,...Tn-1 - , U1, U2), - ...(T1, T2,...Tn-1 - , U1, U2,...Um). -
- Otherwise, the expression has one valid prefix given by the - the template arguments the user specified. -
-
- -

Class template init - observer functions

-
-template <class Policies>
-unspecified operator[](Policies const& policies) const
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Returns a new init-expression with all the same - properties as the init object except that its call - policies are replaced by a reference to - policies.
-
- -

Class template optional<T1 - = unspecified, T2 = - unspecified,...Tn = - unspecified>

- -

A MPL sequence which - can be used to specify the optional arguments to an __init__ - function.

- -

Class template - optional synopsis

-
-namespace boost { namespace python
-{
-  template <T1 = unspecified,...Tn = unspecified>
-  struct optional {};
-}}
-
- -

Example(s)

- -

Given the C++ declarations:

-
-class Y;
-class X
-{
- public:
-   X(int x, Y* y) : m_y(y) {}
-   X(double);
- private:
-   Y* m_y;
-};
-
- A corresponding Boost.Python extension class can be created with: -
-using namespace boost::python;
-
-class_<X>("X", "This is X's docstring.",
-          init<int,char const*>(args("x","y"), "X.__init__'s docstring")[
-                with_custodian_and_ward<1,3>()]
-          )
-   .def(init<double>())
-   ;
-
-
- Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/instance_holder.html b/doc/v2/instance_holder.html deleted file mode 100755 index 4fabad4a..00000000 --- a/doc/v2/instance_holder.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - Boost.Python - <boost/python/instance_holder.hpp> - - - - -
-

C++ Boost

- -
-

Boost.Python

- -

Header <boost/python/instance_holder.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class - instance_holder - -
-
-
Class - instance_holder synopsis - -
Class - instance_holder destructor - -
Class - instance_holder modifier functions - -
Class - instance_holder observer functions -
-
- -
Example -
-
- -

Introduction

- -

<boost/python/instance_holder.hpp> provides - class instance_holder, the base class for types - which hold C++ instances of wrapped classes. - -

Classes

- -

Class instance_holder

- -

instance_holder is an abstract base class whose - concrete derived classes hold C++ class instances within their - Python object wrappers. To allow multiple inheritance in Python - from C++ class wrappers, each such Python object contains a chain - of instance_holders. When an __init__ - function for a wrapped C++ class is invoked, a new - instance_holder instance is created and installed in - the Python object using its install() - function. Each concrete class derived from - instance_holder must provide a holds() - implementation which allows Boost.Python to query it for the - type(s) it is holding. In order to support the held type's wrapped - constructor(s), the class must also provide constructors that can - accept an initial PyObject* argument referring to the - owning Python object, and which forward the rest of their - arguments to the constructor of the held type. The initial - argument is needed to enable virtual function overriding in - Python, and may be ignored, depending on the specific - instance_holder subclass. - -

Class instance_holder - synopsis

-
-namespace boost { namespace python
-{
-  class instance_holder : noncopyable
-  {
-   public:
-      // destructor
-      virtual ~instance_holder();
-
-      // instance_holder modifiers
-      void install(PyObject* inst) throw();
-
-      // instance_holder observers
-      virtual void* holds(type_info) = 0;
-  };
-}}
-
- -

Class instance_holder - destructor

-
-virtual ~instance_holder();
-
- -
-
Effects: destroys the object -
- -

Class - instance_holder modifiers

-
-void install(PyObject* inst) throw();
-
- -
-
Requires: inst is a Python instance of a - wrapped C++ class type, or is a type derived from a wrapped C++ - class type. -
Effects: installs the new instance at the head of the - Python object's chain of held instances. -
Throws: nothing -
- -

Class instance_holder - observers

-
-virtual void* holds(type_info x) = 0;
-
- -
-
Returns: A pointer to an object of the type described - by x if *this contains such an object, - 0 otherwise. -
- -

Example

- -The following is a simplified version of the instance holder template -used by Boost.Python to wrap classes held by smart pointers: -
-template <class SmartPtr, class Value>
-struct pointer_holder : instance_holder
-{
-   // construct from the SmartPtr type
-   pointer_holder(SmartPtr p)
-       :m_p(p)
-
-   // Forwarding constructors for the held type
-   pointer_holder(PyObject*)
-       :m_p(new Value())
-   {
-   }
-
-   template<class A0>
-   pointer_holder(PyObject*,A0 a0)
-       :m_p(new Value(a0))
-   {
-   }
-
-   template<class A0,class A1>
-   pointer_holder(PyObject*,A0 a0,A1 a1)
-       :m_p(new Value(a0,a1))
-   {
-   }
-   ...
-
- private: // required holder implementation
-   void* holds(type_info dst_t)
-   {
-       // holds an instance of the SmartPtr type...
-       if (dst_t == python::type_id<SmartPtr>())
-           return &this->m_p;
-
-       // ...and an instance of the SmartPtr's element_type, if the
-       // pointer is non-null
-       return python::type_id<Value>() == dst_t ? &*this->m_p : 0;
-   }
-
- private: // data members
-   SmartPtr m_p;
-};
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All - Rights Reserved. - diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html deleted file mode 100644 index f6d80185..00000000 --- a/doc/v2/iterator.html +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/iterator.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/iterator.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class template - iterator
- -
-
-
Class - iterator synopsis
- -
Class template - iterator constructor
-
-
-
- -
-
Class template - iterators
- -
-
-
Class - iterators synopsis
- -
Class template - iterators nested types
- -
Class template - iterators static functions
-
-
-
-
- -
Functions
- -
-
-
range
-
-
- -
Examples
-
-
- -

Introduction

- -

<boost/python/iterator.hpp> provides types and - functions for creating Python - iterators from C++ Containers and Iterators. Note - that if your class_ supports random-access iterators, - implementing __getitem__ - (also known as the Sequence Protocol) may serve you better than using - this facility: Python will automatically create an iterator type for you - (see iter()), - and each access can be range-checked, leaving no possiblity of accessing - through an invalidated C++ iterator.

- -

Classes

- -

Class Template iterator

- -

Instances of iterator<C,P> hold a reference to a - callable Python object which, when invoked from Python, expects a single - argument c convertible to C and creates a - Python iterator that traverses [c.begin(), - c.end()). The optional CallPolicies P can be used to - control how elements are returned during iteration.

- -

In the table below, c is an instance of - Container.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Template ParameterRequirementsSemanticsDefault
Container[c.begin(),c.end()) is a valid Iterator range.The result will convert its argument to c and call - c.begin() and c.end() to acquire iterators. - To invoke Container's const - begin() and end() functions, make it - const.
NextPoliciesA default-constructible model of CallPolicies.Applied to the resulting iterators' next() - method.An unspecified model of CallPolicies which - always makes a copy of the result of deferencing the underlying C++ - iterator
- -

Class Template iterator - synopsis

-
-namespace boost { namespace python
-{
-  template <class Container
-             , class NextPolicies = unspecified>
-  struct iterator : object
-  {
-      iterator();
-  };
-}}
-
- -

Class Template iterator - constructor

-
-iterator()
-
- -
-
Effects:
- -
- Initializes its base class with the result of: -
-range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)
-
-
- -
Postconditions: this->get() points to a - Python callable object which creates a Python iterator as described - above.
- -
Rationale: Provides an easy way to create iterators for the - common case where a C++ class being wrapped provides - begin() and end().
-
- - -

Class Template - iterators

- -

A utility class template which provides a way to reliably call its - argument's begin() and end() member functions. - Note that there is no portable way to take the address of a member - function of a C++ standard library container, so - iterators<> can be particularly helpful when wrapping - them.

- -

In the table below, x is an instance of - C.

- - - - - - - - - - - - - - - - - - - -
Required Valid ExpressionType
x.begin()Convertible to C::const_iterator if C - is a const type; convertible to C::iterator - otherwise.
x.end()Convertible to C::const_iterator if C - is a const type; convertible to C::iterator - otherwise.
- -

Class Template iterators - synopsis

-
-namespace boost { namespace python
-{
-  template <class C>
-  struct iterators
-  {
-      typedef typename C::[const_]iterator iterator;
-      static iterator begin(C& x);
-      static iterator end(C& x);
-  };
-}}
-
-
- -

Class Template iterators nested - types

- If C is a const type, -
-typedef typename C::const_iterator iterator;
-
- Otherwise: -
-typedef typename C::iterator iterator;
-
- -

Class Template iterators static - functions

-
-static iterator begin(C&);
-
- -
-
Returns: x.begin()
-
-
-static iterator end(C&);
-
- -
-
Returns: x.end()
-
- - -

Functions

-
-template <class NextPolicies, class Target, class Accessor1, class Accessor2>
-object range(Accessor1 start, Accessor2 finish);
-
-template <class NextPolicies, class Accessor1, class Accessor2>
-object range(Accessor1 start, Accessor2 finish);
-
-template <class Accessor1, class Accessor2>
-object range(Accessor1 start, Accessor2 finish);
-
- -
-
Requires: NextPolicies is a - default-constructible model of CallPolicies.
- -
Effects:
- -
-
-
The first form creates a Python callable object which, when - invoked, converts its argument to a Target object - x, and creates a Python iterator which traverses - [bind(start,_1)(x)bind(finish,_1)(x)), - applying NextPolicies to the iterator's - next() function.
- -
The second form is identical to the first, except that - Target is deduced from Accessor1 as - follows:
- -
-
    -
  1. If Accessor1 is a function type, - Target is the type of its first argument.
  2. - -
  3. If Accessor1 is a data member pointer of the - form R (T::*), Target is - identical to T.
  4. - -
  5. If Accessor1 is a member function pointer of - the form - R (T::*)(arguments...)  - cv-opt, where cv-opt is an optional - cv-qualifier, Target is identical to - T.
  6. -
-
- -
The third form is identical to the second, except that - NextPolicies is an unspecified model of CallPolicies which - always makes a copy of the result of deferencing the underlying C++ - iterator
-
-
- -
Rationale: The use of boost::bind() allows C++ iterators - to be accessed through functions, member functions or data member - pointers. Customization of NextPolicies (e.g. using - return_internal_reference) - is useful when it is expensive to copy sequence elements of a wrapped - class type. Customization of Target is useful when - Accessor1 is a function object, or when a base class of - the intended target type would otherwise be deduced.
-
- -

Examples

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-
-#include <vector>
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(demo)
-{
-    class_<std::vector<double> >("dvec")
-        .def("__iter__", iterator<std::vector<double> >())
-        ;
-}
-
- A more comprehensive example can be found in: - -
-
libs/python/test/iterator.cpp
- -
libs/python/test/input_iterator.cpp
- -
libs/python/test/input_iterator.py
- -
-

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All - Rights Reserved.

-
-
- - - diff --git a/doc/v2/list.html b/doc/v2/list.html deleted file mode 100644 index f999996d..00000000 --- a/doc/v2/list.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/list.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/list.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class list
- -
-
-
Class list - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - list - type.

- -

Classes

- -

Class list

- -

Exposes the mapping - protocol of Python's built-in list type. The semantics - of the constructors and member functions defined below can be fully - understood by reading the TypeWrapper concept - definition. Since list is publicly derived from object, the public object - interface applies to list instances as well.

- -

Class list - synopsis

-
-namespace boost { namespace python
-{
-  class list : public object
-  {
-   public:
-      list(); // new list
-
-      template <class T>
-      explicit list(T const& sequence);
-
-      template <class T>
-      void append(T const& x);
-
-      template <class T>
-      long count(T const& value) const;
-
-      template <class T>
-      void extend(T const& x);
-
-      template <class T>
-      long index(T const& x) const;
-
-      template <class T>
-      void insert(object const& index, T const& x); // insert object before index
-
-      object pop(); // remove and return item at index (default last)
-      object pop(long index);
-      object pop(object const& index);
-
-      template <class T>
-      void remove(T const& value);
-
-      void reverse(); // reverse *IN PLACE*
-
-      void sort(); //  sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
-
-      template <class T>
-      void sort(T const& value);
-  };
-}}
-
- -

Example

-
-using namespace boost::python;
-
-// Return the number of zeroes in the list
-long zeroes(list l)
-{
-   return l.count(0);
-}
-
- -

Revised 1 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/long.html b/doc/v2/long.html deleted file mode 100644 index a9683fd3..00000000 --- a/doc/v2/long.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/long.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/long.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class long_
- -
-
-
Class long_ - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - long - integer type.

- -

Classes

- -

Class long_

- -

Exposes the numeric type - protocol of Python's built-in long type. The semantics - of the constructors and member functions defined below can be fully - understood by reading the TypeWrapper concept - definition. Since long_ is publicly derived from object, the public object - interface applies to long_ instances as well.

- -

Class long_ - synopsis

-
-namespace boost { namespace python
-{
-  class long_ : public object
-  {
-   public:
-      long_(); // new long_
-
-      template <class T>
-      explicit long_(T const& rhs);
-
-      template <class T, class U>
-      long_(T const& rhs, U const& base);
-  };
-}}
-
- -

Example

-
-namespace python = boost::python;
-
-// compute a factorial without overflowing
-python::long_ fact(long n)
-{
-   if (n == 0)
-      return python::long_(1);
-   else
-      return n * fact(n - 1);
-}
-
- -

Revised 1 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html deleted file mode 100755 index 9ccccd7a..00000000 --- a/doc/v2/lvalue_from_pytype.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/lvalue_from_python.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/lvalue_from_pytype.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - lvalue_from_pytype
- -
-
-
Class Template - lvalue_from_pytype synopsis
- -
Class Template - lvalue_from_pytype constructor
-
-
-
- -
-
Class Template - extract_identity
- -
-
-
Class Template - extract_identity synopsis
- -
Class Template - extract_identity static functions
-
-
- -
Class Template - extract_member
- -
-
-
Class Template - extract_member synopsis
- -
Class Template - extract_member static functions
-
-
-
-
- -
Example
-
-
- -

Introduction

- <boost/python/lvalue_from_pytype.hpp> supplies a - facility for extracting C++ objects from within Python instances of a - given type. This is typically useful for dealing with "traditional" - Python extension types. - -

Classes

- -

Class template - lvalue_from_pytype

- -

Class template lvalue_from_pytype will register - from_python converters which, given an object of the given Python type, - can extract references and pointers to a particular C++ type. Its - template arguments are:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- lvalue_from_pytype Requirements
- In the table below, x denotes an object of type - PythonObject& -
ParameterRequirementsSemantics
Extractora model of Extractor whose execute - function returns a reference type.Extracts the lvalue from the Python object once its type has been - confirmed
python_typeA compile-time constant PyTypeObject*The Python type of instances convertible by this converter. - Python subtypes are also convertible.
- -

Class template - lvalue_from_pytype synopsis

-
-namespace boost { namespace python
-{
-   template <class Extractor, PyTypeObject const* python_type>
-   struct lvalue_from_pytype
-   {
-       lvalue_from_pytype();
-   };
-}}
-
- -

Class template - lvalue_from_pytype constructor

-
-lvalue_from_pytype();
-
- -
-
Effects: Registers converters which can convert Python - objects of the given type to lvalues of the type returned by - Extractor::execute.
-
- -

Class template - extract_identity

- -

extract_identity is a model of Extractor which can be used in the - common case where the C++ type to be extracted is the same as the Python - object type.

- -

Class template - extract_identity synopsis

-
-namespace boost { namespace python
-{
-   template <class InstanceType>
-   struct extract_identity
-   {
-      static InstanceType& execute(InstanceType& c);
-   };
-}}
-
- -

Class template - extract_identity static functions

-
-InstanceType& execute(InstanceType& c);
-
- -
-
Returns: c
-
- -

Class template - extract_member

- -

extract_member is a model of Extractor which can be used in the - common case in the common case where the C++ type to be extracted is a - member of the Python object.

- -

Class template - extract_member synopsis

-
-namespace boost { namespace python
-{
-   template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
-   struct extract_member
-   {
-      static MemberType& execute(InstanceType& c);
-   };
-}}
-
- -

Class template - extract_member static functions

-
-static MemberType& execute(InstanceType& c);
-
- -
-
Returns: c.*member
-
- -

Example

- This example presumes that someone has implemented the standard noddy example - module from the Python documentation, and we want to build a module - which manipulates Noddys. Since - noddy_NoddyObject is so simple that it carries no - interesting information, the example is a bit contrived: it assumes you - want to keep track of one particular object for some reason. This module - would have to be dynamically linked to the module which defines - noddy_NoddyType. - -

C++ module definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/handle.hpp>
-#include <boost/python/borrowed.hpp>
-#include <boost/python/lvalue_from_pytype.hpp>
-
-// definition lifted from the Python docs
-typedef struct {
-   PyObject_HEAD
-} noddy_NoddyObject;
-
-using namespace boost::python;
-static handle<noddy_NoddyObject> cache;
-
-bool is_cached(noddy_NoddyObject* x)
-{
-   return x == cache.get();
-}
-
-void set_cache(noddy_NoddyObject* x)
-{
-   cache = handle<noddy_NoddyObject>(borrowed(x));
-}
-
-BOOST_PYTHON_MODULE(noddy_cache)
-{
-   def("is_cached", is_cached);
-   def("set_cache", set_cache);
-
-   // register Noddy lvalue converter
-   lvalue_from_pytype<extract_identity<noddy_NoddyObject>,&noddy_NoddyType>();
-}
-
- -

Python code

-
->>> import noddy
->>> n = noddy.new_noddy()
->>> import noddy_cache
->>> noddy_cache.is_cached(n)
-0
->>> noddy_cache.set_cache(n)
->>> noddy_cache.is_cached(n)
-1
->>> noddy_cache.is_cached(noddy.new_noddy())
-0
-
- -

Revised - - 20 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html deleted file mode 100644 index 592eb37d..00000000 --- a/doc/v2/make_function.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/make_function.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/make_function.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
make_function
- -
make_constructor
-
-
- -
Example
-
-
- -

Introduction

- -

make_function() and - make_constructor() are - the functions used internally by def() and class_<>::def() to produce Python - callable objects which wrap C++ functions and member functions.

- -

Functions

-
-template <class F>
-object make_function(F f)
-
-template <class F, class Policies>
-object make_function(F f, Policies const& policies)
-
-template <class F, class Policies, class Keywords>
-object make_function(F f, Policies const& policies, Keywords const& keywords)
-
- -
-
Requires: F is a function pointer or member - function pointer type. If policies are supplied, it must - be a model of CallPolicies. If - kewords are supplied, it must be the result of a keyword-expression - specifying no more arguments than the arity of f.
- -
Effects: Creates a Python callable object which, when called - from Python, converts its arguments to C++ and calls f. If - F is a pointer-to-member-function type, the target object - of the function call (*this) will be taken from the first - Python argument, and subsequent Python arguments will be used as the - arguments to f. If policies are supplied, it - will be applied to the function as described here. If keywords are - supplied, the keywords will be applied in order to the final - arguments of the resulting function.
- -
Returns: An instance of object which holds the new Python - callable object.
-
-
-template <class T, class ArgList, class Generator>
-object make_constructor();
- 
-template <class ArgList, class Generator, class Policies>
-object make_constructor(Policies const& policies)
-
- -
-
Requires: T is a class type. - Policies is a model of CallPolicies. ArgList is an MPL sequence of C++ argument - types (A1, A2,... AN) such that if - a1, a2... aN are objects of type - A1, A2,... AN respectively, the expression new - Generator::apply<T>::type(a1, a2... aN) - is valid. Generator is a model of HolderGenerator.
- -
Effects: Creates a Python callable object which, when called - from Python, expects its first argument to be a Boost.Python extension - class object. It converts its remaining its arguments to C++ and passes - them to the constructor of a dynamically-allocated - Generator::apply<T>::type object, which is then - installed in the extension class object. In the second form, the - policies are applied to the arguments and result (None) - of the Python callable object
- -
Returns: An instance of object which holds the new Python - callable object.
-
- -

Example

- -

C++ function exposed below returns a callable object wrapping one of - two functions.

-
-#include <boost/python/make_function.hpp>
-#include <boost/python/module.hpp>
-
-char const* foo() { return "foo"; }
-char const* bar() { return "bar"; }
-
-using namespace boost::python;
-object choose_function(bool selector)
-{
-    if (selector)
-        return boost::python::make_function(foo);
-    else
-        return boost::python::make_function(bar);
-}
-
-BOOST_PYTHON_MODULE(make_function_test)
-{
-    def("choose_function", choose_function);
-}
-
- It can be used this way in Python: -
->>> from make_function_test import *
->>> f = choose_function(1)
->>> g = choose_function(0)
->>> f()
-'foo'
->>> g()
-'bar'
-
- -

- - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html deleted file mode 100644 index 6b94a4d4..00000000 --- a/doc/v2/manage_new_object.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/manage_new_object.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/manage_new_object.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - manage_new_object
- -
-
-
Class - manage_new_object synopsis
- -
Class - manage_new_object metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - manage_new_object

- -

manage_new_object is a model of ResultConverterGenerator - which can be used to wrap C++ functions which return a pointer to an - object allocated with a new-expression, and expect the caller to - take responsibility for deleting that object.

- -

Class - manage_new_object synopsis

-
-namespace boost { namespace python
-{
-    struct manage_new_object
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - manage_new_object metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U* for some - U.
- -
Returns: typedef to_python_indirect<T> - type;
-
- -

Example

- -

In C++:

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/manage_new_object.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-
-struct Foo {
-   Foo(int x) : x(x){}
-   int get_x() { return x; }
-   int x;
-};
-
-Foo* make_foo(int x) { return new Foo(x); }
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-    def("make_foo", make_foo, return_value_policy<manage_new_object>())
-    class_<Foo>("Foo")
-        .def("get_x", &Foo::get_x)
-        ;
-}
-
- In Python: -
->>> from my_module import *
->>> f = make_foo(3)     # create a Foo object
->>> f.get_x()
-3
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/module.html b/doc/v2/module.html deleted file mode 100644 index bb041f32..00000000 --- a/doc/v2/module.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - Boost.Python - <boost/python/module.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/module.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Macros - -
-
-
BOOST_PYTHON_MODULE -
- -
Example(s) -
-
- -

Introduction

- -

This header provides the basic facilities needed to create a - Boost.Python extension module. - -

Macros

- -

BOOST_PYTHON_MODULE(name) - is used to declare Python - module initialization functions. The name argument must - exactly match the name of the module to be initialized, and must conform to - Python's identifier naming - rules. Where you would normally write -

-extern "C" void initname()
-{
-   ...
-}
-
- Boost.Python modules should be initialized with -
-BOOST_PYTHON_MODULE(name)
-{
-   ...
-}
-
- -This macro generates two functions in the scope where it is used: -extern "C" void initname(), -and void init_module_name(), whose body must -follow the macro invocation. init_name passes -init_module_name to handle_exception() so -that any C++ exceptions generated are safely processeed. During the -body of init_name, the current scope refers to the module -being initialized. - -

Example(s)

- -

C++ module definition: -

-#include <boost/python/module.hpp>
-
-BOOST_PYTHON_MODULE(xxx)
-{
-    throw "something bad happened"
-}
-
- -Interactive Python: -
->>> import xxx
-Traceback (most recent call last):
-  File "", line 1, in ?
-RuntimeError: Unidentifiable C++ Exception
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/numeric.html b/doc/v2/numeric.html deleted file mode 100644 index a1d59ca9..00000000 --- a/doc/v2/numeric.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/numeric.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/numeric.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class array
- -
-
-
Class array - synopsis
- -
Class array - observer functions
- -
Class array - static functions
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - array - type.

- -

Classes

- -

Class array

- -

Provides access to the array types of Numerical Python's Numeric and NumArray modules. With - the exception of the functions documented below, the semantics of the constructors and - member functions defined below can be fully understood by reading the TypeWrapper concept - definition. Since array is publicly derived from object, the public object - interface applies to array instances as well.

- -

The default behavior is to use - Numeric.ArrayType as the associated Python type if the - Numeric module is installed in the default location. - Otherwise it falls back to use numarray.NDArray. If neither - extension module is installed, conversions to arguments of type - numeric::array will cause overload resolution to reject the - overload, and other attempted uses of numeric::array will raise an appropriate Python exception. - The associated Python type can be set manually using the set_module_and_type(...) static - function.

- -

Class array - synopsis

-
-namespace boost { namespace python { namespace numeric
-{
-   class array : public object
-   {
-    public:
-      object astype();
-      template <class Type>
-      object astype(Type const& type_);
-
-      template <class Type>
-      object new_(Type const& type_) const;
-
-      template <class Sequence> 
-      void resize(Sequence const& x);
-      void resize(long x1);
-      void resize(long x1, long x2);
-      ...
-      void resize(long x1, long x2,...long xn);
-
-      template <class Sequence> 
-      void setshape(Sequence const& x);
-      void setshape(long x1);
-      void setshape(long x1, long x2);
-      ...
-      void setshape(long x1, long x2,...long xn);
-
-      template <class Indices, class Values>
-      void put(Indices const& indices, Values const& values);
-
-      template <class Sequence>
-      object take(Sequence const& sequence, long axis = 0);
-
-      template <class File>
-      void tofile(File const& f) const;
-
-      object factory();
-      template <class Buffer>
-      object factory(Buffer const&);
-      template <class Buffer, class Type>
-      object factory(Buffer const&, Type const&);
-      template <class Buffer, class Type, class Shape>
-      object factory(Buffer const&, Type const&, Shape const&, bool copy = true, bool savespace = false);
-      template <class Buffer, class Type, class Shape>
-      object factory(Buffer const&, Type const&, Shape const&, bool copy, bool savespace, char typecode);
-
-      template <class T1>
-      explicit array(T1 const& x1);
-      template <class T1, class T2>
-      explicit array(T1 const& x1, T2 const& x2);
-      ...
-      template <class T1, class T2,...class Tn>
-      explicit array(T1 const& x1, T2 const& x2,...Tn const& xn);
-
-      static void set_module_and_type();
-      static void set_module_and_type(char const* package_path = 0, char const* type_name = 0);
-
-      object argmax(long axis=-1);
-
-      object argmin(long axis=-1);
-
-      object argsort(long axis=-1);
-
-      void byteswap();
-
-      object copy() const;
-
-      object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const;
-
-      void info() const;
-
-      bool is_c_array() const;
-      bool isbyteswapped() const;
-      void sort();
-      object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const;
-      object type() const;
-      char typecode() const;
-      
-      object getflat() const;
-      long getrank() const;
-      object getshape() const;
-      bool isaligned() const;
-      bool iscontiguous() const;
-      long itemsize() const;
-      long nelements() const;
-      object nonzero() const;
-   
-      void ravel();
-   
-      object repeat(object const& repeats, long axis=0);
-   
-      void setflat(object const& flat);
-   
-      void swapaxes(long axis1, long axis2);
-   
-      str tostring() const;
-   
-      void transpose(object const& axes = object());
-   
-      object view() const;
-  };
-}}}
-
- -

Class array observer - functions

-
-object factory();
-template <class Buffer>
-object factory(Buffer const&);
-template <class Buffer, class Type>
-object factory(Buffer const&, Type const&);
-template <class Buffer, class Type, class Shape>
-object factory(Buffer const&, Type const&, Shape const&, bool copy = true, bool savespace = false);
-template <class Buffer, class Type, class Shape>
-object factory(Buffer const&, Type const&, Shape const&, bool copy, bool savespace, char typecode);
-
- These functions map to the underlying array type's array() - function family. They are not called "array" because of the - C++ limitation that you can't define a member function with the same name - as its enclosing class. -
-template <class Type>
-object new_(Type const&) const;
-
- This function maps to the underlying array type's new() - function. It is not called "new" because that is a keyword - in C++. - -

Class array static - functions

-
-static void set_module_and_type(char const* package_path, char const* type_name);
-static void set_module_and_type();
-
- -
-
Requires: package_path and - type_name, if supplied, is an ntbs.
- -
Effects: The first form sets the package path of the module - which supplies the type named by type_name to - package_path. The second form restores the default search behavior. The associated Python - type will be searched for only the first time it is needed, and - thereafter the first time it is needed after an invocation of - set_module_and_type.
-
- -

Example

-
-#include <boost/python/numeric.hpp>
-#include <boost/python/tuple.hpp>
-
-// sets the first element in a 2d numeric array
-void set_first_element(numeric::array& y, double value)
-{
-    y[make_tuple(0,0)] = value;
-}
-
- -

Revised 03 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/object.html b/doc/v2/object.html deleted file mode 100644 index 93b9027e..00000000 --- a/doc/v2/object.html +++ /dev/null @@ -1,931 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/object.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/object.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Types
- -
-
-
slice_nil
-
-
- -
Classes
- -
-
-
Class - const_attribute_policies
- -
-
-
Class - const_attribute_policies synopsis
- -
Class - const_attribute_policies static functions
-
-
- -
Class - attribute_policies
- -
-
-
Class - attribute_policies synopsis
- -
Class - attribute_policies static functions
-
-
- -
Class - const_item_policies
- -
-
-
Class - const_item_policies synopsis
- -
Class - const_item_policies static functions
-
-
- -
Class - item_policies
- -
-
-
Class - item_policies synopsis
- -
Class - item_policies static functions
-
-
- -
Class - const_slice_policies
- -
-
-
Class - const_slice_policies synopsis
- -
Class - const_slice_policies static functions
-
-
- -
Class - slice_policies
- -
-
-
Class - slice_policies synopsis
- -
Class - slice_policies static functions
-
-
- -
Class - object_operators
- -
-
-
Class - object_operators synopsis
- -
Class - object_operators observer functions
-
-
- -
Class object
- -
-
-
Class object - synopsis
- -
Class object - constructors and destructor
- -
Class template - object modifier functions
- -
Class template - object observer functions
-
-
- -
Class template - proxy
- -
-
-
Class template - proxy synopsis
- -
Class template - proxy modifier functions
- -
Class template - proxy observer functions
-
-
-
-
- -
Functions
- -
-
-
del
- -
comparisons
- -
binary operations
- -
assignment operations
-
- -
-
operators
-
-
- -
Example
-
-
- -

Introduction

- -

Exposes the generic Python object wrapper class object, - and related classes. In order to avoid some potenential problems with - argument-dependent lookup and the generalized operators defined on - object, all these facilities are defined in - namespace boost::python::api, and object - is imported into namespace boost::python with a - using-declaration.

- -

Types

- -

-
-enum slice_nil { _ };
-
- A type that can be used to get the effect of leaving out an index in a - Python slice expression: -
->>> x[:-1]
-
- C++ equivalent: -
-x.slice(_,-1)
-
- -

Classes

- - -

Class - const_attribute_policies

- -

The policies which are used for proxies representing an attribute - access to a const object.

- -

Class - const_attribute_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct const_attribute_policies
-  {
-      typedef char const* key_type;
-      static object get(object const& target, char const* key);
-  };
-}}}
-
- -

Class - const_attribute_policies static functions

-
-static object get(object const& target, char const* key);
-
- -
-
Requires: key is an ntbs.
- -
Effects: accesses the attribute of target named - by key.
- -
Returns: An object managing the result of the - attribute access.
- -
Throws: error_already_set if a - Python exception is raised.
-
- -

Class - attribute_policies

- -

The policies which are used for proxies representing an attribute - access to a mutable object.

- -

Class - attribute_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct attribute_policies : const_attribute_policies
-  {
-      static object const& set(object const& target, char const* key, object const& value);
-      static void del(object const&target, char const* key);
-  };
-}}}
-
- -

Class - attribute_policies static functions

-
-static object const& set(object const& target, char const* key, object const& value);
-
- -
-
Requires: key is an ntbs.
- -
Effects: sets the attribute of target named by - key to value.
- -
Throws: error_already_set if a - Python exception is raised.
-
-
-static void del(object const&target, char const* key);
-
- -
-
Requires: key is an ntbs.
- -
Effects: deletes the attribute of target named - by key.
- -
Throws: error_already_set if a - Python exception is raised.
-
- - - -

Class - const_item_policies

- -

The policies which are used for proxies representing an item access - (via the Python bracket operators []) to a - const object.

- -

Class - const_item_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct const_item_policies
-  {
-      typedef object key_type;
-      static object get(object const& target, object const& key);
-  };
-}}}
-
- -

Class - const_item_policies static functions

-
-static object get(object const& target, object const& key);
-
- -
-
Effects: accesses the item of target specified - by key.
- -
Returns: An object managing the result of the - item access.
- -
Throws: error_already_set if a - Python exception is raised.
-
- -

Class - item_policies

- -

The policies which are used for proxies representing an item access - (via the Python bracket operators []) to a mutable - object.

- -

Class - item_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct item_policies : const_item_policies
-  {
-      static object const& set(object const& target, object const& key, object const& value);
-      static void del(object const& target, object const& key);
-  };
-}}}
-
- -

Class - item_policies static functions

-
-static object const& set(object const& target, object const& key, object const& value);
-
- -
-
Effects: sets the item of target specified by - key to value.
- -
Throws: error_already_set if a - Python exception is raised.
-
-
-static void del(object const& target, object const& key);
-
- -
-
Effects: deletes the item of target specified - by key.
- -
Throws: error_already_set if a - Python exception is raised.
-
- - - -

Class - const_slice_policies

- -

The policies which are used for proxies representing an slice access - (via the Python slice notation - [x:y]) to a - const object.

- -

Class - const_slice_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct const_slice_policies
-  {
-      typedef std::pair<handle<>, handle<> > key_type;
-      static object get(object const& target, key_type const& key);
-  };
-}}}
-
- -

Class - const_slice_policies static functions

-
-static object get(object const& target, key_type const& key);
-
- -
-
Effects: accesses the slice of target specified - by key.
- -
Returns: An object managing the result of the - slice access.
- -
Throws: error_already_set if a - Python exception is raised.
-
- -

Class - slice_policies

- -

The policies which are used for proxies representing an slice access - to a mutable object.

- -

Class - slice_policies synopsis

-
-namespace boost { namespace python { namespace api
-{
-  struct slice_policies : const_slice_policies
-  {
-      static object const& set(object const& target, key_type const& key, object const& value);
-      static void del(object const& target, key_type const& key);
-  };
-}}}
-
- -

Class - slice_policies static functions

-
-static object const& set(object const& target, key_type const& key, object const& value);
-
- -
-
Effects: sets the slice of target specified by - key to value.
- -
Throws: error_already_set if a - Python exception is raised.
-
-
-static void del(object const& target, key_type const& key);
-
- -
-
Effects: deletes the slice of target specified - by key.
- -
Throws: error_already_set if a - Python exception is raised.
-
- - -

Class template - object_operators<U>

- -

This is the base class of object and its - proxy template used to supply common interface: member - functions, and operators which must be defined within the class body. Its - template parameter U is expected to be a class derived from - object_operators<U>. In practice users should never - use this class directly, but it is documented here because it supplies - important interface to object and its proxies.

- -

Class template - object_operators synopsis

-
-namespace boost { namespace python { namespace api
-{
-  template <class U>
-  class object_operators
-  {
-   public:
-      // function call
-      //
-      object operator()() const;
-
-      template <class A0>
-      object operator()(A0 const&) const;
-      template <class A0, class A1>
-      object operator()(A0 const&, A1 const&) const;
-      ...
-      template <class A0, class A1,...class An>
-      object operator()(A0 const&, A1 const&,...An const&) const;
-
-      // truth value testing
-      //
-      typedef unspecified bool_type;
-      operator bool_type() const;
-
-      // Attribute access
-      //
-      proxy<const_object_attribute> attr(char const*) const;
-      proxy<object_attribute> attr(char const*);
-
-      // item access
-      //
-      template <class T>
-      proxy<const_object_item> operator[](T const& key) const;
-    
-      template <class T>
-      proxy<object_item> operator[](T const& key);
-
-      // slicing
-      //
-      template <class T, class V>
-      proxy<const_object_slice> slice(T const& start, V const& end) const
-    
-      template <class T, class V>
-      proxy<object_slice> slice(T const& start, V const& end);
-  };
-}}}
-
- -

Class template - object_operators observer functions

-
-object operator()() const;
-template <class A0>
-object operator()(A0 const&) const;
-template <class A0, class A1>
-object operator()(A0 const&, A1 const&) const;
-...
-template <class A0, class A1,...class An>
-object operator()(A0 const& a1, A1 const& a2,...An const& aN) const;
-
- -
-
Effects: - call<object>(object(*static_cast<U*>(this)).ptr(), a1, - a2,...aN)
-
-
-operator bool_type() const;
-
- -
-
Effects: Tests truth value of *this.
- -
Returns: - call<object>(object(*static_cast<U*>(this)).ptr(), a1, - a2,...aN)
-
-
-proxy<const_object_attribute> attr(char const* name) const;
-proxy<object_attribute> attr(char const* name);
-
- -
-
Requires: name is an ntbs.
- -
Effects: accesses the named attribute of - *this.
- -
Returns: a proxy object which binds - object(*static_cast<U*>(this)) as its target, and - name as its key.
-
-
-template <class T>
-proxy<const_object_item> operator[](T const& key) const;
-template <class T>
-proxy<object_item> operator[](T const& key);
-
- -
-
Effects: accesses the item of *this indicated - by key.
- -
Returns: a proxy object which binds - object(*static_cast<U*>(this)) as its target, and - object(key) as its key.
-
-
-template <class T, class V>
-proxy<const_object_slice> slice(T const& start; start, V const& finish) const
-template <class T, class V>
-proxy<object_slice> slice(T const& start; start, V const& finish);
-
- -
-
Effects: accesses the slice of *this indicated - by std::make_pair(object(start), object(finish)).
- -
Returns: a proxy object which binds - object(*static_cast<U*>(this)) as its target, and - std::make_pair(object(start), object(finish)) as its - key.
-
- - -

Class object

- -

The intention is that object acts as much like a - Python variable as possible. Thus expressions you'd expect to work - in Python should generally work in the same way from C++. Most of - object's interface is provided by its base class - object_operators<object>, - and the free functions defined in this - header. -

- -

Class object - synopsis

-
-namespace boost { namespace python { namespace api
-{
-  class object : public object_operators<object>
-  {
-   public:
-      object();
-
-      object(object const&);
-      
-      template <class T>
-      explicit object(T const& x);
-
-      ~object();
-
-      object& operator=(object const&); 
-
-      PyObject* ptr() const;
-  };
-}}}
-
- -

Class object - constructors and destructor

-
-object();
-
- -
-
Effects: Constructs an object managing a reference to the - Python None object.
- -
Throws: nothing.
-
-
-template <class T>
-explicit object(T const& x);
-
- -
-
Effects: converts x to python and manages a - reference to it.
- -
Throws: error_already_set and sets a Python - TypeError exception if no such conversion is - possible.
-
-
-~object();
-
- -
-
Effects: decrements the reference count of the - internally-held object.
-
- -

Class object - modifiers

-
-object& operator=(object const& rhs); 
-
- -
-
Effects: increments the reference count of the object held - by rhs and decrements the reference count of the object - held by *this.
-
- -

Class object - observers

-
-PyObject* ptr() const;
-
- -
-
Returns: a pointer to the internally-held Python - object.
-
- - -

Class template proxy

- -

This template is instantiated with various Policies described in this - document in order to implement attribute, item, and slice access for - object. It stores an object of type - Policies::key_type.

- -

Class template proxy - synopsis

-
-namespace boost { namespace python { namespace api
-{
-  template <class Policies>
-  class proxy : public object_operators<proxy<Policies> >
-  {
-   public:
-      operator object() const;
-
-      proxy const& operator=(proxy const&) const;
-      template <class T>
-      inline proxy const& operator=(T const& rhs) const;
-      
-      void del() const;
-
-      template <class R>
-      proxy operator+=(R const& rhs);
-      template <class R>
-      proxy operator-=(R const& rhs);
-      template <class R>
-      proxy operator*=(R const& rhs);
-      template <class R>
-      proxy operator/=(R const& rhs);
-      template <class R>
-      proxy operator%=(R const& rhs);
-      template <class R>
-      proxy operator<<=(R const& rhs);
-      template <class R>
-      proxy operator>>=(R const& rhs);
-      template <class R>
-      proxy operator&=(R const& rhs);
-      template <class R>
-      proxy operator|=(R const& rhs);
-  };
-}}}
-
- -

Class template proxy - observer functions

-
-operator object() const;
-
- -
-
Effects: applies - Policies::get(target, key - ) with the proxy's target and key objects.
-
- -

Class template proxy - modifier functions

-
-proxy const& operator=(proxy const& rhs) const;
-template <class T>
-inline proxy const& operator=(T const& rhs) const;
-
- -
-
Effects: - Policies::set(target, key - , object(rhs)) with the proxy's target and key - objects.
-
-
-template <class R>
-proxy operator+=(R const& rhs);
-template <class R>
-proxy operator-=(R const& rhs);
-template <class R>
-proxy operator*=(R const& rhs);
-template <class R>
-proxy operator/=(R const& rhs);
-template <class R>
-proxy operator%=(R const& rhs);
-template <class R>
-proxy operator<<=(R const& rhs);
-template <class R>
-proxy operator>>=(R const& rhs);
-template <class R>
-proxy operator&=(R const& rhs);
-template <class R>
-proxy operator|=(R const& rhs);
-
- -
-
Effects: for a given operator@=, - object(*this) @= rhs;
-
Returns: *this
-
-
-void del() const;
-
- -
-
Effects: - Policies::del(target, key - ) with the proxy's target and key objects.
-
- - -

Functions

-
-template <class T>
-void del(proxy<T> const& x);
-
- -
-
Effects: x.del()
-
-
-
-template<class L,class R> bool operator>(L const&l,R const&r);
-template<class L,class R> bool operator>=(L const&l,R const&r);
-template<class L,class R> bool operator<(L const&l,R const&r);
-template<class L,class R> bool operator<=(L const&l,R const&r);
-template<class L,class R> bool operator==(L const&l,R const&r);
-template<class L,class R> bool operator!=(L const&l,R const&r);
-
- -
-
Effects: returns the result of applying the operator to - object(l) and object(r), respectively, in - Python.
-
-
-
-template<class L,class R> object operator+(L const&l,R const&r);
-template<class L,class R> object operator-(L const&l,R const&r);
-template<class L,class R> object operator*(L const&l,R const&r);
-template<class L,class R> object operator/(L const&l,R const&r);
-template<class L,class R> object operator%(L const&l,R const&r);
-template<class L,class R> object operator<<(L const&l,R const&r);
-template<class L,class R> object operator>>(L const&l,R const&r);
-template<class L,class R> object operator&(L const&l,R const&r);
-template<class L,class R> object operator^(L const&l,R const&r);
-template<class L,class R> object operator|(L const&l,R const&r);
-
- -
-
Effects: returns the result of applying the operator to - object(l) and object(r), respectively, in - Python.
-
-
-
-template<class R> object& operator+=(object&l,R const&r);
-template<class R> object& operator-=(object&l,R const&r);
-template<class R> object& operator*=(object&l,R const&r);
-template<class R> object& operator/=(object&l,R const&r);
-template<class R> object& operator%=(object&l,R const&r);
-template<class R> object& operator<<=(object&l,R const&r)
-template<class R> object& operator>>=(object&l,R const&r);
-template<class R> object& operator&=(object&l,R const&r);
-template<class R> object& operator^=(object&l,R const&r);
-template<class R> object& operator|=(object&l,R const&r);
-
- -
-
Effects: assigns to l the result of applying the - corresponding Python inplace operator to l and - object(r), respectively.
- -
Returns: l.
-
- -

Example

- Python code: -
-def sum_items(seq):
-   result = 0
-   for x in seq:
-      result += x
-   return result
-
- C++ version: -
-object sum_items(object seq)
-{
-   object result = object(0);
-   for (int i = 0; i < seq.attr("__len__")(); ++i)
-      result += seq[i];
-   return result;
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/operators.html b/doc/v2/operators.html deleted file mode 100755 index 45f502a6..00000000 --- a/doc/v2/operators.html +++ /dev/null @@ -1,888 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/operators.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/operators.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class - self_ns::self_t
- -
-
-
Class self_t - synopsis
- -
Class self_t - inplace operators
- -
Class - self_t comparison functions
- -
Class self_t - non-member operations
- -
Class - self_t unary operations
- -
Class - self_t value operations
-
-
- -
Class template - other
- -
-
-
Class other - synopsis
-
-
- -
Class template - operator_
- -
-
-
Class - operator_ synopsis
-
-
-
-
- -
Objects
- -
-
-
self
-
-
- -
Examples
-
-
- -

Introduction

- -

<boost/python/operators.hpp> provides types and - functions for automatically generating Python special methods - from the corresponding C++ constructs. Most of these constructs are - operator expressions, hence the name. To use the facility, substitute the - self object for an object of the - class type being wrapped in the expression to be exposed, and pass the - result to class_<>::def(). Much of - what is exposed in this header should be considered part of the - implementation, so is not documented in detail here.

- -

Classes

- -

Class self_ns::self_t

- -

self_ns::self_t is the actual type of the self object. The library isolates - self_t in its own namespace, self_ns, in order - to prevent the generalized operator templates which operate on it from - being found by argument-dependent lookup in other contexts. This should - be considered an implementation detail, since users should never have to - mention self_t directly.

- -

Class self_ns::self_t - synopsis

-
-namespace boost { namespace python { namespace self_ns {
-{
-   unspecified-type-declaration self_t;
-
-   // inplace operators
-   template <class T> operator_<unspecified> operator+=(self_t, T);
-   template <class T> operator_<unspecified> operator-=(self_t, T);
-   template <class T> operator_<unspecified> operator*=(self_t, T);
-   template <class T> operator_<unspecified> operator/=(self_t, T);
-   template <class T> operator_<unspecified> operator%=(self_t, T);
-   template <class T> operator_<unspecified> operator>>=(self_t, T);
-   template <class T> operator_<unspecified> operator<<=(self_t, T);
-   template <class T> operator_<unspecified> operator&=(self_t, T);
-   template <class T> operator_<unspecified> operator^=(self_t, T);
-   template <class T> operator_<unspecified> operator|=(self_t, T);
-
-   // comparisons
-   template <class L, class R> operator_<unspecified> operator==(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator!=(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator<(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator>(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator<=(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator>=(L const&, R const&);
-
-   // non-member operations
-   template <class L, class R> operator_<unspecified> operator+(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator-(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator*(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator/(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator%(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator>>(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator<<(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator&(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator^(L const&, R const&);
-   template <class L, class R> operator_<unspecified> operator|(L const&, R const&);
-   template <class L, class R> operator_<unspecified> pow(L const&, R const&);
-
-   // unary operations
-   operator_<unspecified> operator-(self_t);
-   operator_<unspecified> operator+(self_t);
-   operator_<unspecified> operator~(self_t);
-
-   // value operations
-   operator_<unspecified> int_(self_t);
-   operator_<unspecified> long_(self_t);
-   operator_<unspecified> float_(self_t);
-   operator_<unspecified> complex_(self_t);
-   operator_<unspecified> str(self_t);
-
-}}};
-
- The tables below describe the methods generated when the results of the - expressions described are passed as arguments to class_<>::def(). - x is an object of the class type being wrapped. - -

Class self_t inplace - operators

- In the table below, If r is an object of type - other<T>, - y is an object of type T; otherwise, - y is an object of the same type as - r. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
self += r__iadd__x += y
self -= r__isub__x -= y
self *= r__imul__x *= y
self /= r__idiv__x /= y
self %= r__imod__x %= y
self >>= r__irshift__x >>= y
self <<= r__ilshift__x <<= y
self &= r__iand__x &= y
self ^= r__ixor__x ^= y
self |= r__ior__x |= y
- -

Class self_t - comparison functions

- In the tables below, if r is of type self_t, y is an object of - the same type as x;
- if l or r is an object of type - other<T>, - y is an object of type T;
- otherwise, y is an object of the same type as - l or r.
- l is never of type self_t. - -

The column of Python Expressions illustrates the expressions - that will be supported in Python for objects convertible to the types of - x and y. The secondary operation arises due to - Python's reflection - rules for rich comparison operators, and are only used when the - corresponding operation is not defined as a method of the y - object.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ ImplementationPython Expressions
- (primary, secondary)
self == r__eq__x == yx == y, y == x
l == self__eq__y == xy == x, x == y
self != r__ne__x != yx != y, y != x
l != self__ne__y != xy != x, x != y
self < r__lt__x < yx < y, y > x
l < self__gt__y < xy > x, x < y
self > r__gt__x > yx > y, y < x
l > self__lt__y > xy < x, x > y
self <= r__le__x <= yx <= y, y >= x
l <= self__ge__y <= xy >= x, x <= y
self >= r__ge__x >= yx >= y, y <= x
l >= self__le__y >= xy <= x, x >= y
- -

Class self_t non-member - operations

- The operations whose names begin with "__r" below will only - be called if the left-hand operand does not already support the given - operation, as described here. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
self + r__add__x + y
l + self__radd__y + x
self - r__sub__x - y
l - self__rsub__y - x
self * r__mul__x * y
l * self__rmul__y * x
self / r__div__x / y
l / self__rdiv__y / x
self % r__mod__x % y
l % self__rmod__y % x
self >> r__rshift__x >> y
l >> self__rrshift__y >> x
self << r__lshift__x << y
l << self__rlshift__y << x
self & r__and__x & y
l & self__rand__y & x
self ^ r__xor__x ^ y
l ^ self__rxor__y ^ x
self | r__or__x | y
l | self__ror__y | x
pow(self, r)__pow__pow(x, y)
pow(l, self)__rpow__pow(y, x)
- -

Class self_t unary - operations

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
-self__neg__-x
+self__pos__+x
~self__invert__~x
- -

Class self_t value - operations

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C++ ExpressionPython Method NameC++ Implementation
int_(self)__int__long(x)
long___long__PyLong_FromLong(x)
float___float__double(x)
complex___complex__std::complex<double>(x)
str__str__lexical_cast<std::string>(x)
- -

Class Template other

- -

Instances of other<T> can be used in operator - expressions with self; the result is equivalent - to the same expression with a T object in place of - other<T>. Use other<T> to prevent - construction of a T object in case it is heavyweight, when - no constructor is available, or simply for clarity.

- -

Class Template other synopsis

-
-namespace boost { namespace python
-{
-  template <class T>
-  struct other
-  {
-  };
-}}
-
- - -

Class Template - detail::operator_

- -

Instantiations of detail::operator_<> are used as - the return type of operator expressions involving self. This should be considered an implementation - detail and is only documented here as a way of showing how the result of - self-expressions match calls to class_<>::def().

- -

Class Template - detail::operator_ synopsis

-
-namespace boost { namespace python { namespace detail
-{
-  template <unspecified>
-  struct operator_
-  {
-  };
-}}}
-
- -

Objects

- -

self

-
-namespace boost { namespace python
-{
-  using self_ns::self;
-}}
-
- -

Example

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/operators.hpp>
-#include <boost/operators.hpp>
-
-struct number
-   : boost::integer_arithmetic<number>
-{
-   number(long x_) : x(x_) {}
-   operator long() const { return x; }
-
-   number& operator+=(number const& rhs)
-      { x += rhs }
-   number& operator-=(number const& rhs);
-      { x -= rhs }
-   number& operator*=(number const& rhs)
-      { x *= rhs }
-   number& operator/=(number const& rhs);
-      { x /= rhs }
-   number& operator%=(number const& rhs);
-      { x %= rhs }
-
-   long x;
-};
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(demo)
-{
-   class_<number>("number")
-      // interoperate with self
-      .def(self += self)
-      .def(self + self)
-      .def(self -= self)
-      .def(self - self)
-      .def(self *= self)
-      .def(self * self)
-      .def(self /= self)
-      .def(self / self)
-      .def(self %= self)
-      .def(self % self)
-
-      // Convert to Python int
-      .def(int_(self))
-
-      // interoperate with long
-      .def(self += long())
-      .def(self + long())
-      .def(long() + self)
-      .def(self -= long())
-      .def(self - long())
-      .def(long() - self)
-      .def(self *= long())
-      .def(self * long())
-      .def(long() * self)
-      .def(self /= long())
-      .def(self / long())
-      .def(long() / self)
-      .def(self %= long())
-      .def(self % long())
-      .def(long() % self)
-      ;
-}
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/overloads.html b/doc/v2/overloads.html deleted file mode 100644 index a0a37b34..00000000 --- a/doc/v2/overloads.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/overloads.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/overloads.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
overload-dispatch-expressions
- -
OverloadDispatcher concept
- -
Macros
- -
-
-
BOOST_PYTHON_FUNCTION_OVERLOADS
- -
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Defines facilities for generating families of overloaded Python - functions and extension class methods from C++ functions and - member functions with default arguments, or from similar families - of C++ overloads

- -

overload-dispatch-expressions

- -

- An overload-dispatch-expression is used to describe a - family of overloaded methods to be generated for an extension - class. It has the following properties: - -

-
-
docstring: An ntbs - whose value will bound to the methods' __doc__ - attribute
- -
keywords: A keyword-expression which - will be used to name (a trailing subsequence of) the arguments - to the generated methods.
- -
call policies: An instance of some type which models CallPolicies.
- -
minimum arity - The minimum number of arguments to be accepted by a generated - method overload.
- -
maximum arity - The maximum number of arguments to be accepted by a generated - method overload.
-
-
- -

OverloadDispatcher Concept

- - An OverloadDispatcher X is a class which has a - minimum arity and a maximum arity, and for which - the following following are valid overload-dispatch-expressions, - with the same minimum and maximum arity as the OverloadDispatcher. - -
-X()
-X(docstring)
-X(docstring, keywords)
-X(keywords, docstring)
-X()[policies]
-X(docstring)[policies]
-X(docstring, keywords)[policies]
-X(keywords, docstring)[policies]
-
- -
    -
  • If policies are supplied, it must be an instance of a -type which models CallPolicies, and -will be used as the result's call policies. Otherwise the result's -call policies will be an instance of default_call_policies. - -
  • If docstring is supplied it must be an ntbs, and will be used as the result's docstring. Otherwise the result has an empty docstring. - -
  • If keywords is supplied it must be the result of a keyword-expression - whose length is no greater than X's maximum - arity, and will be used as the result's keywords. Otherwise - the result's keywords will be empty. -
- - - - -

Macros

- -

BOOST_PYTHON_FUNCTION_OVERLOADS(name, func_id, min_args, max_args)

- Expands to the definition of an OverloadDispatcher called - name in the current scope which can be used to - generate the following function invocation: -
-func_id(a1, a2,...ai);
-
- - for all min_args <= i <= max_args. - -

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(name, member_name, min_args, max_args)

- - Expands to the definition of an OverloadDispatcher called - name in the current scope which can be used to - generate the following function invocation: -
-x.member_name(a1, a2,...ai);
-
- - for all min_args <= i <= - max_args, where x is a reference to an - object of class type. - -

Example(s)

- -
-#include <boost/python/module.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/args.hpp>
-#include <boost/python/tuple.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/overloads.hpp>
-#include <boost/python/return_internal_reference.hpp>
-
-using namespace boost::python;
-
-tuple f(int x = 1, double y = 4.25, char const* z = "wow")
-{
-    return make_tuple(x, y, z);
-}
-
-BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
-
-struct Y {};
-struct X
-{
-    Y& f(int x, double y = 4.25, char const* z = "wow")
-    {
-        return inner;
-    }
-    Y inner;
-};
-
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 1, 3)
-
-BOOST_PYTHON_MODULE(args_ext)
-{
-    def("f", f, args("x", "y", "z")
-        , "This is f's docstring"
-        );
-
-    
-    class_<Y>("Y")
-        ;
-            
-    class_<X>("X", "This is X's docstring")
-        .def("f1", &X::f, 
-                X_f_overloads(args("x", "y", "z"),
-                              "f's docstring"
-                                  )[return_internal_reference<>()])
-        ;
-}
-
- -

Revised - - 15 December, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/overview.html b/doc/v2/overview.html deleted file mode 100644 index 00a39773..00000000 --- a/doc/v2/overview.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - -Boost.Python - Overview - - - - - - - -
-

-

-
-

Boost.Python

-

Overview

-
-
-
-
Introduction
-
First topic
-
Second topic
-
Footnotes
-
-

Introduction

-

{{text}}

-

First Topic

-

{{text}}

-

Second Topic

-

{{text}}

-

Footnotes

-
-
(1) {{text}}
-
(2) {{text}}
-
-
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/pickle.html b/doc/v2/pickle.html deleted file mode 100644 index 13c7b306..00000000 --- a/doc/v2/pickle.html +++ /dev/null @@ -1,293 +0,0 @@ - - -Boost.Python Pickle Support - -
- -c++boost.gif (8819 bytes) - -
-

Boost.Python Pickle Support

- -Pickle is a Python module for object serialization, also known -as persistence, marshalling, or flattening. - -

-It is often necessary to save and restore the contents of an object to -a file. One approach to this problem is to write a pair of functions -that read and write data from a file in a special format. A powerful -alternative approach is to use Python's pickle module. Exploiting -Python's ability for introspection, the pickle module recursively -converts nearly arbitrary Python objects into a stream of bytes that -can be written to a file. - -

-The Boost Python Library supports the pickle module -through the interface as described in detail in the -Python Library Reference for pickle. This interface -involves the special methods __getinitargs__, -__getstate__ and __setstate__ as described -in the following. Note that Boost.Python is also fully compatible -with Python's cPickle module. - -


-

The Boost.Python Pickle Interface

- -At the user level, the Boost.Python pickle interface involves three special -methods: - -
-
-__getinitargs__ -
- When an instance of a Boost.Python extension class is pickled, the - pickler tests if the instance has a __getinitargs__ method. - This method must return a Python tuple (it is most convenient to use - a boost::python::tuple). When the instance is restored by the - unpickler, the contents of this tuple are used as the arguments for - the class constructor. - -

- If __getinitargs__ is not defined, pickle.load - will call the constructor (__init__) without arguments; - i.e., the object must be default-constructible. - -

-

-__getstate__ - -
- When an instance of a Boost.Python extension class is pickled, the - pickler tests if the instance has a __getstate__ method. - This method should return a Python object representing the state of - the instance. - -

-

-__setstate__ - -
- When an instance of a Boost.Python extension class is restored by the - unpickler (pickle.load), it is first constructed using the - result of __getinitargs__ as arguments (see above). Subsequently - the unpickler tests if the new instance has a __setstate__ - method. If so, this method is called with the result of - __getstate__ (a Python object) as the argument. - -
- -The three special methods described above may be .def()'ed -individually by the user. However, Boost.Python provides an easy to use -high-level interface via the -boost::python::pickle_suite class that also -enforces consistency: __getstate__ and __setstate__ -must be defined as pairs. Use of this interface is demonstrated by the -following examples. - -
-

Examples

- -There are three files in boost/libs/python/test that show how to -provide pickle support. - -
-

pickle1.cpp

- - The C++ class in this example can be fully restored by passing the - appropriate argument to the constructor. Therefore it is sufficient - to define the pickle interface method __getinitargs__. - This is done in the following way: - -
    -
  • 1. Definition of the C++ pickle function: -
    -  struct world_pickle_suite : boost::python::pickle_suite
    -  {
    -    static
    -    boost::python::tuple
    -    getinitargs(world const& w)
    -    {
    -        return boost::python::make_tuple(w.get_country());
    -    }
    -  };
    -
    -
  • 2. Establishing the Python binding: -
    -  class_<world>("world", args<const std::string&>())
    -      // ...
    -      .def_pickle(world_pickle_suite())
    -      // ...
    -
    -
- -
-

pickle2.cpp

- - The C++ class in this example contains member data that cannot be - restored by any of the constructors. Therefore it is necessary to - provide the __getstate__/__setstate__ pair of - pickle interface methods: - -
    -
  • 1. Definition of the C++ pickle functions: -
    -  struct world_pickle_suite : boost::python::pickle_suite
    -  {
    -    static
    -    boost::python::tuple
    -    getinitargs(const world& w)
    -    {
    -      // ...
    -    }
    -
    -    static
    -    boost::python::tuple
    -    getstate(const world& w)
    -    {
    -      // ...
    -    }
    -
    -    static
    -    void
    -    setstate(world& w, boost::python::tuple state)
    -    {
    -      // ...
    -    }
    -  };
    -
    -
  • 2. Establishing the Python bindings for the entire suite: -
    -  class_<world>("world", args<const std::string&>())
    -      // ...
    -      .def_pickle(world_pickle_suite())
    -      // ...
    -
    -
- -

- For simplicity, the __dict__ is not included in the result - of __getstate__. This is not generally recommended, but a - valid approach if it is anticipated that the object's - __dict__ will always be empty. Note that the safety guard - described below will catch the cases where this assumption is violated. - -


-

pickle3.cpp

- - This example is similar to pickle2.cpp. However, the - object's __dict__ is included in the result of - __getstate__. This requires a little more code but is - unavoidable if the object's __dict__ is not always empty. - -
-

Pitfall and Safety Guard

- -The pickle protocol described above has an important pitfall that the -end user of a Boost.Python extension module might not be aware of: -

- -__getstate__ is defined and the instance's __dict__ -is not empty. - -

- - The author of a Boost.Python extension class might provide a - __getstate__ method without considering the possibilities - that: - -

-

    -
  • - his class is used in Python as a base class. Most likely the - __dict__ of instances of the derived class needs to be - pickled in order to restore the instances correctly. - -

    -

  • - the user adds items to the instance's __dict__ directly. - Again, the __dict__ of the instance then needs to be - pickled. - -
-

- - To alert the user to this highly unobvious problem, a safety guard is - provided. If __getstate__ is defined and the instance's - __dict__ is not empty, Boost.Python tests if the class has - an attribute __getstate_manages_dict__. An exception is - raised if this attribute is not defined: - -

-    RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
-
- - To resolve this problem, it should first be established that the - __getstate__ and __setstate__ methods manage the - instances's __dict__ correctly. Note that this can be done - either at the C++ or the Python level. Finally, the safety guard - should intentionally be overridden. E.g. in C++ (from - pickle3.cpp): - -
-  struct world_pickle_suite : boost::python::pickle_suite
-  {
-    // ...
-
-    static bool getstate_manages_dict() { return true; }
-  };
-
- - Alternatively in Python: - -
-    import your_bpl_module
-    class your_class(your_bpl_module.your_class):
-      __getstate_manages_dict__ = 1
-      def __getstate__(self):
-        # your code here
-      def __setstate__(self, state):
-        # your code here
-
- -
-

Practical Advice

- -
    -
  • - In Boost.Python extension modules with many extension classes, - providing complete pickle support for all classes would be a - significant overhead. In general complete pickle support should - only be implemented for extension classes that will eventually - be pickled. - -

    -

  • - Avoid using __getstate__ if the instance can also be - reconstructed by way of __getinitargs__. This automatically - avoids the pitfall described above. - -

    -

  • - If __getstate__ is required, include the instance's - __dict__ in the Python object that is returned. - -
- -
- -© Copyright Ralf W. Grosse-Kunstleve 20012-2002. Permission to copy, -use, modify, sell and distribute this document is granted provided this -copyright notice appears in all copies. This document is provided "as -is" without express or implied warranty, and with no claim as to its -suitability for any purpose. - -

-Updated: Aug 2002. -

diff --git a/doc/v2/platforms.html b/doc/v2/platforms.html deleted file mode 100644 index 42429b2e..00000000 --- a/doc/v2/platforms.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - Boost.Python - Known Working Platforms and Compilers - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Known Working Platforms and Compilers

-
-
- Boost.Python has been successfully tested on the following - platforms and compilers: - -
-
Unix Platforms:
- -
-
-
with Python 2.2 and 2.2.2b1:
- -
-
-
GCC 2.95.3, 2.96, 3.0.4, - 3.1, and 3.2 on RedHat Linux 7.3 - for Intel x86
- -
Tru64 CXX - 6.5.1 on OSF v. 5.1 for Dec/Compaq Alpha
- -
- MIPSPro 7.3.1.2m on IRIX 6.5 for SGI - mips
- -
GCC 3.1 on SunOS 5.8
-
-
- -
with Python 2.2.1
- -
-
-
KCC - 3.4d on OSF v. 5.1 for Dec/Compaq Alpha
- -
KCC - 3.4d on AIX
-
-
-
-
-
- -
Microsoft - Windows XP Professional with Python 2.2, 2.2.1, and 2.2.2b1:
- -
-
-
Microsoft Visual - C++ 6, 7, and 7.1 beta
- -
Microsoft Visual - C++ 6 with STLPort - 4.5.3
- -
- Metrowerks CodeWarrior 7.2, 8.0, 8.2 and 8.3 beta
- -
Intel - C++ 5.0, 6.0, and 7.0 beta
- -
Intel C++ - 5.0 with STLPort - 4.5.3
- -
Cygwin GCC 3.0.4 and 3.2
- -
MinGW-1.1 (GCC 2.95.3-5)
- -
MinGW-2.0 (GCC 3.2)
-
-
-
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/pointee.html b/doc/v2/pointee.html deleted file mode 100644 index 47440700..00000000 --- a/doc/v2/pointee.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Boost.Python - <boost/python/pointee.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/pointee.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class Templatepointee - -
-
-
Class Template - pointee synopsis -
-
- -
Example -
-
- -

Introduction

- -

<boost/python/pointee.hpp> introduces a - traits metafunction - template pointee<T> which can be used to extract the "pointed-to" type from the type of a pointer or smart pointer. - -

Classes

- -

Class Template pointee<class T>

- -

pointee<T> is used by the class_<...> - template to deduce the type being held when a pointer or smart - pointer type is used as its HeldType argument. - -

Class Template - pointee synopsis

-
-namespace boost { namespace python
-{
-   template <class T> struct pointee
-   {
-      typedef T::element_type type;
-   };
-
-   // specialization for pointers
-   template <T> struct pointee<T*>
-   {
-      typedef T type;
-   };
-}
-
- - -

Example

- -Given a 3rd-party smart pointer type -smart_pointer<T>, one might partially specialize -pointee<smart_pointer<T> > so that it can be -used as the HeldType for a class wrapper: - -
-#include <boost/python/pointee.hpp>
-#include <boost/python/class.hpp>
-#include <third_party_lib.hpp>
-
-namespace boost { namespace python
-{
-  template <class T> struct pointee<smart_pointer<T> >
-  {
-     typedef T type;
-  };
-}}
-
-BOOST_PYTHON_MODULE(pointee_demo)
-{
-   class_<third_party_class, smart_pointer<third_party_class> >("third_party_class")
-      .def(...)
-      ...
-      ;
-}
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/progress_reports.html b/doc/v2/progress_reports.html deleted file mode 100644 index f5441edd..00000000 --- a/doc/v2/progress_reports.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - -Boost.Python - Progress Reports - - - - - - - -
-

-

-
-

Boost.Python

-

Progress Reports

-
-


- -Monthly progress reports are required as part of Boost Consulting's -contract with LLNL for Boost.Python development. These reports contain -a useful record of the project history, including the rationale for -design decisions and links to relevant discussions. - -
-
February 2002
-
March 2002
-
April 2002
-
May 2002
-
June 2002
-
-
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/ptr.html b/doc/v2/ptr.html deleted file mode 100644 index 0633be80..00000000 --- a/doc/v2/ptr.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - Boost.Python - <boost/python/ptr.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/ptr.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Functions -
-
-
ptr -
- -
Classes -
-
-
Class template pointer_wrapper - -
-
-
Class template pointer_wrapper synopsis - -
Class - pointer_wrapper types - -
Class - pointer_wrapper constructors and destructor - -
Class - pointer_wrapper observer functions - -
-
- -
Metafunctions -
-
-
Class template is_pointer_wrapper - -
-
-
Class template is_pointer_wrapper synopsis -
- - -
Class template unwrap_pointer - -
-
-
Class template unwrap_pointer synopsis -
- -
- - -
Example(s) -
-
- -

Introduction

- -

<boost/python/ptr.hpp> defines the - ptr() function template, which allows users to - specify how to convert C++ pointer values to python in the context - of implementing overridable virtual functions, invoking Python - callable objects, or explicitly converting C++ objects to - Python. Normally, when passing pointers to Python callbacks, the - pointee is copied to ensure that the Python object - never holds a dangling reference. To specify that the new Python - object should merely contain a copy of a pointer p, - the user can pass ptr(p) instead of passing - p directly. This interface is meant to mirror the use - of boost::ref(), - which can be similarly used to prevent copying of referents. - -

ptr(p) returns an instance of pointer_wrapper<>, which - can be detected using the is_pointer_wrapper<> - metafunction; unwrap_pointer<> is a - metafunction which extracts the original pointer type from a - pointer_wrapper<>. These classes can be thought - of as implementation details. - -

Functions

-
-
-template <class T>
-pointer_wrapper<T> ptr(T x);
-
- -
-
Requires: T is a pointer type. - -
Returns: pointer_wrapper<T>(x) - -
Throws: nothing. -
- -

Classes

- -

Class template pointer_wrapper

- -

A "type envelope" which is returned by ptr(), used to indicate reference semantics - for pointers passed to Python callbacks. - -

Class - pointer_wrapper synopsis

-
-namespace boost { namespace python
-{
-    template<class Ptr> class pointer_wrapper
-    { 
-     public:
-        typedef Ptr type;
-
-        explicit pointer_wrapper(Ptr x);
-        operator Ptr() const;
-        Ptr get() const;
-    };
-}}
-
- -

Class template pointer_wrapper types

-
-typedef Ptr type;
-
-The type of the pointer being wrapped. - -

Class template pointer_wrapper constructors and - destructor

-
-explicit pointer_wrapper(Ptr x);
-
- -
-
Requires: Ptr is a pointer type. - -
Effects: Stores x in a the pointer_wrapper<>. -
Throws: nothing. -
- -

Class template pointer_wrapper observer - functions

-
-operator Ptr() const;
-Ptr get() const;
-
- -
-
Returns: a copy of the stored pointer. -
Rationale: pointer_wrapper is intended - to be a stand-in for the actual pointer type, but sometimes it's - better to have an explicit way to retrieve the pointer. -
- -

Metafunctions

- -

Class template is_pointer_wrapper

- -

A unary metafunction whose value is true iff its - argument is a pointer_wrapper<>. - -

Class template is_pointer_wrapper synopsis

-
-namespace boost { namespace python
-{
-    template<class T> class is_pointer_wrapper
-    { 
-        static unspecified value = ...;
-    };
-}}
-
- - -
-
Returns: true iff T is a - specialization of -pointer_wrapper<>. -
value is an integral constant convertible to bool of -unspecified type - -
- -

Class template unwrap_pointer

- -A unary metafunction which extracts the wrapped pointer type from a -specialization of pointer_wrapper<>. - -

Class template unwrap_pointer synopsis

-
-namespace boost { namespace python
-{
-    template<class T> class unwrap_pointer
-    { 
-        typedef unspecified type;
-    };
-}}
-
- -
-
Returns: T::type if T is a - specialization of -pointer_wrapper<>, T otherwise -
- - -

Example(s)

- -This example illustrates the use of ptr() to prevent an -object from being copied: -
-#include <boost/python/call.hpp>
-#include <boost/python/ptr.hpp>
-
-class expensive_to_copy
-{
-   ...
-};
-
-void pass_as_arg(expensive_to_copy* x, PyObject* f)
-{
-   // call the Python function f, passing a Python object built around
-   // which refers to *x by-pointer.
-   //
-   // *** Note: ensuring that *x outlives the argument to f() is    ***
-   // *** up to the user! Failure to do so could result in a crash! ***
-
-   boost::python::call<void>(f, ptr(x));
-}
-...
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/python.html b/doc/v2/python.html deleted file mode 100644 index 64d0c135..00000000 --- a/doc/v2/python.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python.hpp>

-
-


- -

Contents

- -
-
Introduction
-
-
- -

Introduction

- -

This is a convenience header which #includes all of the public - interface headers that are part of the Boost.Python library

-
-# include <args.hpp>
-# include <args_fwd.hpp>
-# include <back_reference.hpp>
-# include <bases.hpp>
-# include <borrowed.hpp>
-# include <call.hpp>
-# include <call_method.hpp>
-# include <class.hpp>
-# include <copy_const_reference.hpp>
-# include <copy_non_const_reference.hpp>
-# include <data_members.hpp>
-# include <def.hpp>
-# include <default_call_policies.hpp>
-# include <dict.hpp>
-# include <enum.hpp>
-# include <errors.hpp>
-# include <exception_translator.hpp>
-# include <extract.hpp>
-# include <handle.hpp>
-# include <has_back_reference.hpp>
-# include <implicit.hpp>
-# include <init.hpp>
-# include <instance_holder.hpp>
-# include <iterator.hpp>
-# include <list.hpp>
-# include <long.hpp>
-# include <lvalue_from_pytype.hpp>
-# include <make_function.hpp>
-# include <manage_new_object.hpp>
-# include <module.hpp>
-# include <numeric.hpp>
-# include <object.hpp>
-# include <object_protocol.hpp>
-# include <object_protocol_core.hpp>
-# include <operators.hpp>
-# include <other.hpp>
-# include <overloads.hpp>
-# include <pointee.hpp>
-# include <ptr.hpp>
-# include <reference_existing_object.hpp>
-# include <return_internal_reference.hpp>
-# include <return_value_policy.hpp>
-# include <scope.hpp>
-# include <self.hpp>
-# include <slice_nil.hpp>
-# include <str.hpp>
-# include <to_python_converter.hpp>
-# include <to_python_indirect.hpp>
-# include <to_python_value.hpp>
-# include <tuple.hpp>
-# include <type_id.hpp>
-# include <with_custodian_and_ward.hpp>
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/rationale.html b/doc/v2/rationale.html deleted file mode 100644 index 8219adad..00000000 --- a/doc/v2/rationale.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - -Boost.Python - Rationale - - - - - - - -
-

-

-
-

Boost.Python

-

Rationale

-
-
-
-
Introduction
-
First topic
-
Second topic
-
Footnotes
-
-

Introduction

-

{{text}}

-

First Topic

-

{{text}}

-

Second Topic

-

{{text}}

-

Footnotes

-
-
(1) {{text}}
-
(2) {{text}}
-
-
-

Revised - - 13 November, 2002 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - diff --git a/doc/v2/raw_function.html b/doc/v2/raw_function.html deleted file mode 100755 index ae1ad6c0..00000000 --- a/doc/v2/raw_function.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/raw_function.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/raw_function.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Functions
- -
-
-
raw_function
-
-
- -
Example
-
-
- -

Introduction

- -

raw_function(...) - is used to convert a function taking a tuple and a dict into a Python callable object - which accepts a variable number of arguments and arbitrary keyword - arguments. - -

Functions

- raw_function -
-template <class F>
-object raw_function(F f, std::size_t min_args = 0);
-
- -
-
Requires: f(tuple(), dict()) is - well-formed.
- -
Returns: a callable object which requires at least min_args arguments. When called, the actual non-keyword arguments will be passed in a tuple as the first argument to f, and the keyword arguments will be passed in a dict as the second argument to f. - - -
- -

Example

-C++: -
-#include <boost/python/def.hpp>
-#include <boost/python/tuple.hpp>
-#include <boost/python/dict.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/raw_function.hpp>
-
-using namespace boost::python;
-
-tuple raw(tuple args, dict kw)
-{
-    return make_tuple(args, kw);
-}
-
-BOOST_PYTHON_MODULE(raw_test)
-{
-    def("raw", raw_function(raw));
-}
-
- -Python: -
->>> from raw_test import *
-
->>> raw(3, 4, foo = 'bar', baz = 42)
-((3, 4), {'foo': 'bar', 'baz': 42})
-
-

- - 7 March, 2003 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html deleted file mode 100644 index e066debf..00000000 --- a/doc/v2/reference_existing_object.html +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/reference_existing_object.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/reference_existing_object.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - reference_existing_object
- -
-
-
Class - reference_existing_object synopsis
- -
Class - reference_existing_object metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - reference_existing_object

- -

reference_existing_object is a model of ResultConverterGenerator - which can be used to wrap C++ functions which return a reference or - pointer to a C++ object. When the wrapped function is called, the value - referenced by its return value is not copied. A new Python object is - created which contains a pointer to the referent, and no attempt is made - to ensure that the lifetime of the referent is at least as long as that - of the corresponding Python object. Thus, it can be highly dangerous to use - reference_existing_object without additional lifetime - management from such models of CallPolicies as with_custodian_and_ward. - This class is used in the implementation of return_internal_reference.

- -

Class - reference_existing_object synopsis

-
-namespace boost { namespace python
-{
-    struct reference_existing_object
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - reference_existing_object metafunctions

-
-template <class T> struct apply
-
- -
-
Requires: T is U& or - U*for some U.
- -
Returns: typedef to_python_indirect<T,V> - type, where V is a HolderObjectGenerator - which constructs an instance holder containing an unowned - U* pointing to the referent of the wrapped function's - return value.
-
- -

Example

- -

In C++:

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/reference_existing_object.hpp>
-#include <boost/python/return_value_policy.hpp>
-#include <utility>
-
-// classes to wrap
-struct Singleton
-{
-   Singleton() : x(0) {}
-
-   int exchange(int n)  // set x and return the old value
-   {
-        std::swap(n, x);
-        return n;
-   }
-
-   int x;
-};
-
-Singleton& get_it()
-{
-   static Singleton just_one;
-   return just_one;
-}
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(singleton)
-{
-    def("get_it", get_it,
-        return_value_policy<reference_existing_object>());
-
-    class_<Singleton>("Singleton")
-       .def("exchange", &Singleton::exchange)
-       ;
-}
-
- In Python: -
->>> import singleton
->>> s1 = singleton.get_it()  
->>> s2 = singleton.get_it()
->>> id(s1) == id(s2)  # s1 and s2 are not the same object
-0
->>> s1.exchange(42)   # but they reference the same C++ Singleton
-0
->>> s2.exchange(99)
-42
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/return_by_value.html b/doc/v2/return_by_value.html deleted file mode 100644 index 80c26d75..00000000 --- a/doc/v2/return_by_value.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/return_by_value.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/return_by_value.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - return_by_value
- -
-
-
Class - return_by_value synopsis
- -
Class - return_by_value metafunctions
-
-
-
-
- -
Example
-
-
- -

Classes

- -

Class - return_by_value

- -

return_by_value is a model of ResultConverterGenerator - which can be used to wrap C++ functions returning any reference or value - type such that the return value is copied into a new Python object.

- -

Class - return_by_value synopsis

-
-namespace boost { namespace python
-{
-    struct return_by_value
-    {
-        template <class T> struct apply;
-    };
-}}
-
- -

Class - return_by_value metafunctions

-
-template <class T> struct apply
-
- -
-
Returns: typedef to_python_value<T> - type;
-
- -

Example

- -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/return_by_value.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { };
-
-Bar global_bar;
-
-// functions to wrap:
-Bar b1();
-Bar& b2();
-Bar const& b3();
-
-// Wrapper code
-using namespace boost::python;
-template <class R>
-void def_void_function(char const* name, R (*f)())
-{
-   def(name, f, return_value_policy<return_by_value>());
-}
-
-BOOST_PYTHON_MODULE(my_module)
-{
-    class_<Bar>("Bar");
-    def_void_function("b1", b1);
-    def_void_function("b2", b2);
-    def_void_function("b3", b3);
-}
-
- -

Python Code

-
->>> from my_module import *
->>> b = b1() # each of these calls
->>> b = b2() # creates a brand
->>> b = b3() # new Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html deleted file mode 100644 index bd9946da..00000000 --- a/doc/v2/return_internal_reference.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/return_internal_reference.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/return_internal_reference.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - return_internal_reference
- -
-
-
Class - Template return_internal_reference - synopsis
- -
Class - return_internal_reference static - functions
-
-
-
-
- -
Example
-
-
- -

Introduction

- return_internal_reference instantiations are models of CallPolicies which allow pointers and - references to objects held internally by a free or member function - argument or from the target of a member function to be returned safely - without making a copy of the referent. The default for its first template - argument handles the common case where the containing object is the - target (*this) of a wrapped member function. - -

Classes

- -

Class template - return_internal_reference

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- return_internal_reference template parameters -
ParameterRequirementsDescriptionDefault
owner_argA positive compile-time constant of type - std::size_t.The index of the parameter which contains the object to which the - reference or pointer is being returned. If used to wrap a member - function, parameter 1 is the target object (*this). Note - that if the target Python object type doesn't support weak - references, a Python TypeError exception will be raised - when the function being wrapped is called.1
BaseA model of CallPoliciesUsed for policy composition. Any result_converter it - supplies will be overridden by - return_internal_reference, but its precall - and postcall policies are composed as described here CallPolicies.default_call_policies
- -

Class template - return_internal_reference synopsis

-
-namespace boost { namespace python
-{
-   template <std::size_t owner_arg = 1, class Base = default_call_policies>
-   struct return_internal_reference : Base
-   {
-      static PyObject* postcall(PyObject*, PyObject* result);
-      typedef reference_existing_object result_converter;
-   };
-}}
-
- -

Class - default_call_policies static functions

-
-PyObject* postcall(PyObject* args, PyObject* result);
-
- -
-
Requires: PyTuple_Check(args) - != 0
- -
Returns: - with_custodian_and_ward_postcall::postcall(args, - result)
-
- -

Example

- -

C++ module definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/return_internal_reference.hpp>
-
-class Bar
-{
-   Bar(int x) : x(x) {}
-   int get_x() const { return x; }
-   void set_x(int x) { this->x = x; }
- private:
-   int x;
-}
-
-class Foo
-{
- public:
-   Foo(int x) : b(x) {}
-
-   // Returns an internal reference
-   Bar const& get_bar() const { return b; }
-
- private:
-   Bar b;
-};
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(internal_refs)
-{
-   class_<Bar>("Bar")
-      .def("get_x", &Bar::get_x)
-      .def("set_x", &Bar::set_x)
-      ;
-
-   class_<Foo>("Foo", init<int>())
-      .def("get_bar", &Foo::get_bar
-          , return_internal_reference<>())
-      ;
-}
-
- -

Python code

-
->>> from internal_refs import *
->>> f = Foo(3)
->>> b1 = f.get_bar()
->>> b2 = f.get_bar()
->>> b1.get_x()
-3
->>> b2.get_x()
-3
->>> b1.set_x(42)
->>> b2.get_x()
-42
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html deleted file mode 100644 index 601c49d5..00000000 --- a/doc/v2/return_value_policy.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/return_value_policy.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/return_value_policy.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - return_value_policy
- -
-
-
Class Template - return_value_policy synopsis
-
-
-
-
- -
Example
-
-
- -

Introduction

- return_value_policy instantiations are simply models of CallPolicies which are composed of a ResultConverterGenerator - and optional Base CallPolicies. - -

Classes

- -

Class template - return_value_policy

- - - - - - - - - - - - - - - - - - - - - - - - - -
- return_value_policy template parameters -
ParameterRequirementsDefault
ResultConverterGeneratorA model of ResultConverterGenerator.
BaseA model of CallPoliciesdefault_call_policies
- -

Class template - return_value_policy synopsis

-
-namespace boost { namespace python
-{
-  template <class ResultConverterGenerator, class Base = default_call_policies>
-  struct return_value_policy : Base
-  {
-      typedef ResultConverterGenerator result_converter;
-  };
-}}
-
- -

Example

- -

C++ Module Definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/copy_const_reference.hpp>
-#include <boost/python/return_value_policy.hpp>
-
-// classes to wrap
-struct Bar { int x; }
-
-struct Foo {
-   Foo(int x) : { b.x = x; }
-   Bar const& get_bar() const { return b; }
- private:
-   Bar b;
-};
-
-// Wrapper code
-using namespace boost::python;
-BOOST_PYTHON_MODULE(my_module)
-{
-   class_<Bar>("Bar");
-
-   class_<Foo>("Foo", init<int>())
-      .def("get_bar", &Foo::get_bar
-          , return_value_policy<copy_const_reference>())
-      ;
-}
-
- -

Python Code

-
->>> from my_module import *
->>> f = Foo(3)         # create a Foo object
->>> b = f.get_bar()    # make a copy of the internal Bar object
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/scope.html b/doc/v2/scope.html deleted file mode 100644 index 1d578d36..00000000 --- a/doc/v2/scope.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/scope.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/scope.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class scope
- -
-
-
Class scope - synopsis
- -
Class scope - constructors and destructor
-
-
-
-
- -
Example
-
-
- -

Introduction

- -

Defines facilities for querying and controlling the Python scope - (namespace) which will contain new wrapped classes and functions.

- -

Classes

- -

Class scope

- -

The scope class has an associated global Python - object which controls the Python namespace in which new extension - classes and wrapped functions will be defined as - attributes. Default-constructing a new scope object - binds it to the associated global Python object. Constructing a - scope object with an argument changes the associated - global Python object to the one held by the argument, until the - lifetime of the scope object ends, at which time the - associated global Python object reverts to what it was before the - scope object was constructed.

- -

Class scope - synopsis

-
-namespace boost { namespace python
-{
-  class scope : public object
-  {
-   public:
-      scope(scope const&);
-      scope(object const&);
-      scope();
-      ~scope()
-   private:
-      void operator=(scope const&);
-  };
-}}
-
- -

Class scope constructors - and destructor

-
-explicit scope(scope const& x);
-explicit scope(object const& x);
-
- Stores a reference to the current associated scope object, and sets the - associated scope object to the one referred to by x.ptr(). - The object base class is initialized with x. -
-scope();
-
- Stores a reference to the current associated scope object. The - object base class is initialized with the current associated - scope object. Outside any module initialization function, the current - associated Python object is None. -
-~scope()
-
- Sets the current associated Python object to the stored object. - -

Example

- The following example shows how scope setting can be used to define - nested classes. - -

C++ Module definition:

-
-#include <boost/python/class.hpp>
-#include <boost/python/scope.hpp>
-using namespace boost::python;
-
-struct X
-{
-  void f();
-
-  struct Y { int g() { return 42; } };
-};
-
-BOOST_PYTHON_MODULE(nested)
-{
-   // add some constants to the current (module) scope
-   scope().attr("yes") = 1;
-   scope().attr("no") = 0;
-
-   // Change the current scope 
-   scope outer
-       = class_<X>("X")
-            .def("f", &X::f)
-            ;
-
-   // Define a class Y in the current scope, X
-   class_<Y>("Y")
-      .def("g", &Y::g)
-      ;
-}
-
- Interactive Python: -
->>> import nested
->>> nested.yes
-1
->>> y = nested.X.Y()
->>> y.g()
-42
-
- -

Revised 09 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/str.html b/doc/v2/str.html deleted file mode 100644 index 79ae74f1..00000000 --- a/doc/v2/str.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/str.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/str.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class str
- -
-
-
Class str - synopsis
-
-
-
-
- -
Example(s)
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - str - type.

- -

Classes

- -

Class str

- -

Exposes the string - methods of Python's built-in str type. The - semantics of the constructors and member functions defined below - can be fully understood by reading the TypeWrapper concept - definition. Since str is publicly derived from - object, the - public object interface applies to str instances as - well.

- -

Class str - synopsis

-
-namespace boost { namespace python
-{
-  class str : public object
-  {
-   public:
-      str(); // new str
-
-      str(const char* s); // new str
-
-      template <class T>
-      explicit str(T const& other);
-
-      str capitalize() const;
-
-      template <class T>
-      str center(T const& width) const;
-
-      template<class T>
-      long count(T const& sub) const;
-      template<class T1, class T2>
-      long count(T1 const& sub,T2 const& start) const;
-      template<class T1, class T2, class T3>
-      long count(T1 const& sub,T2 const& start, T3 const& end) const;
-
-      object decode() const;
-      template<class T>
-      object decode(T const& encoding) const;
-      template<class T1, class T2>
-      object decode(T1 const& encoding, T2 const& errors) const;
-
-      object encode() const;
-      template <class T>
-      object encode(T const& encoding) const;
-      template <class T1, class T2>
-      object encode(T1 const& encoding, T2 const& errors) const;
-
-      template <class T>
-      bool endswith(T const& suffix) const;
-      template <class T1, class T2>
-      bool endswith(T1 const& suffix, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const;
-
-      str expandtabs() const;
-      template <class T>
-      str expandtabs(T const& tabsize) const;
-
-      template <class T>
-      long find(T const& sub) const;
-      template <class T1, class T2>
-      long find(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long find(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      template <class T>
-      long index(T const& sub) const;
-      template <class T1, class T2>
-      long index(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long index(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      bool isalnum() const;
-      bool isalpha() const;
-      bool isdigit() const;
-      bool islower() const;
-      bool isspace() const;
-      bool istitle() const;
-      bool isupper() const;
-
-      template <class T>
-      str join(T const& sequence) const;
-
-      template <class T>
-      str ljust(T const& width) const;
-
-      str lower() const;
-      str lstrip() const;
-
-      template <class T1, class T2>
-      str replace(T1 const& old, T2 const& new_) const;
-      template <class T1, class T2, class T3>
-      str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const;
-
-      template <class T>
-      long rfind(T const& sub) const;
-      template <class T1, class T2>
-      long rfind(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long rfind(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      template <class T>
-      long rindex(T const& sub) const;
-      template <class T1, class T2>
-      long rindex(T1 const& sub, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      long rindex(T1 const& sub, T2 const& start, T3 const& end) const;
-
-      template <class T>
-      str rjust(T const& width) const;
-
-      str rstrip() const;
-
-      list split() const; 
-      template <class T>
-      list split(T const& sep) const;
-      template <class T1, class T2>
-      list split(T1 const& sep, T2 const& maxsplit) const;
-
-      list splitlines() const;
-      template <class T>
-      list splitlines(T const& keepends) const;
-
-      template <class T>
-      bool startswith(T const& prefix) const;
-      template <class T1, class T2>
-      bool startswidth(T1 const& prefix, T2 const& start) const;
-      template <class T1, class T2, class T3>
-      bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const;
-
-      str strip() const;
-      str swapcase() const;
-      str title() const;
-
-      template <class T>
-      str translate(T const& table) const;
-      template <class T1, class T2>
-      str translate(T1 const& table, T2 const& deletechars) const;
-
-      str upper() const;
-  };
-}}
-
- -

Example

-
-using namespace boost::python;
-str remove_angle_brackets(str x)
-{
-  return x.strip('<').strip('>');
-}
-
- -

Revised 3 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/to_python_converter.html b/doc/v2/to_python_converter.html deleted file mode 100644 index 33e3b684..00000000 --- a/doc/v2/to_python_converter.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - Boost.Python - - <boost/python/to_python_converter.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/to_python_converter.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - to_python_converter
- -
-
-
Class Template - to_python_converter synopsis
- -
Class Template - to_python_converter constructor
-
-
-
-
- -
Example
-
-
- -

Introduction

- to_python_converter registers a conversion from objects of a - given C++ type into a Python object. - -

Classes

- -

Class template - to_python_converter

- to_python_converter adds a wrapper around a static member - function of its second template parameter, handling low-level details - such as insertion into the converter registry. - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- to_python_converter template parameters
- In the table below, x denotes an object of type - T -
ParameterRequirementsDescription
T - The C++ type of the source object in the conversion
Conversion - PyObject* p = Conversion::convert(x),
- if p == 0, PyErr_Occurred() != 0.
A class type whose static member function convert - does the real work of the conversion.
- -

Class template - to_python_converter synopsis

-
-namespace boost { namespace python
-{
-  template <class T, class Conversion>
-  struct to_python_converter
-  {
-      to_python_converter();
-  };
-}}
-
- -

Class template - to_python_converter constructor

-
-to_python_converter();
-
- -
-
Effects: Registers a to_python converter which uses - Conversion::convert() to do its work.
-
- -

Example

- This example presumes that someone has implemented the standard noddy example - module from the Python documentation, and placed the corresponding - declarations in "noddy.h". Because - noddy_NoddyObject is the ultimate trivial extension type, - the example is a bit contrived: it wraps a function for which all - information is contained in the type of its return value. - -

C++ module definition

-
-#include <boost/python/reference.hpp>
-#include <boost/python/module.hpp>
-#include "noddy.h"
-
-struct tag {};
-tag make_tag() { return tag(); }
-
-using namespace boost::python;
-
-struct tag_to_noddy
-{
-    static PyObject* convert(tag const& x)
-    {
-        return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
-    }
-};
-
-BOOST_PYTHON_MODULE(to_python_converter)
-{
-    def("make_tag", make_tag);
-    to_python_converter<tag, tag_to_noddy>();
-}
-
- -

Python code

-
->>> import to_python_converter
->>> def always_none():
-...     return None
-...
->>> def choose_function(x):
-...     if (x % 2 != 0):
-...         return to_python_converter.make_tag
-...     else:
-...         return always_none
-...
->>> a = [ choose_function(x) for x in range(5) ]
->>> b = [ f() for f in a ]
->>> type(b[0])
-<type 'NoneType'>
->>> type(b[1])
-<type 'Noddy'>
->>> type(b[2])
-<type 'NoneType'>
->>> type(b[3])
-<type 'Noddy'>
-
- -

Revised - - 13 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/to_python_indirect.html b/doc/v2/to_python_indirect.html deleted file mode 100644 index 7871c548..00000000 --- a/doc/v2/to_python_indirect.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - Boost.Python - <boost/python/to_python_indirect.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header <boost/python/to_python_indirect.hpp>

-
-
- -

Contents

- -
-
Introduction - - -
Classes - -
-
-
Class Template to_python_indirect - -
-
- -
Class Template - to_python_indirect synopsis - -
Class Template - to_python_indirect observer functions - -
Class Template - to_python_indirect static functions -
-
- -
Example -
-
- -

Introduction

- - <boost/python/to_python_indirect.hpp> supplies - a way to construct new Python objects that hold wrapped C++ class - instances via a pointer or smart pointer. - -

Classes

- -

Class template to_python_indirect

-

Class template to_python_indirect converts objects -of its first argument type to python as extension class instances, using the ownership policy provided by its 2nd argument. - -

- - - - - - - -
- to_python_indirect Requirements
- - In the table below, x denotes an object of - type T, h denotes an - object of type - boost::python::objects::instance_holder*, and - p denotes an object of type - U*. - -
Parameter - - Requirements - - Description - -
T - - Either U cv& - (where cv is any optional cv-qualification) or a Dereferenceable type such that - *x is convertible to U const&, where - U is a class type. - - A type deferencing a C++ class exposed to Python using - class template class_. - -
MakeHolder - - h = MakeHolder::execute(p); - - A class whose static execute() creates an - instance_holder. - -
- - Instantiations of to_python_indirect are models of ResultConverter. - - -

Class template to_python_indirect synopsis

-
-namespace boost { namespace python
-{
-  template <class T, class MakeHolder>
-  struct to_python_indirect
-  {
-     static bool convertible();
-     PyObject* operator()(T ptr_or_reference) const;
-   private:
-     static PyTypeObject* type();
-  };
-}}
-
- -

Class template to_python_indirect observers

-
-PyObject* operator()(T x) const;
-
- -
- -
Requires: x refers to an object (if it - is a pointer type, it is non-null). convertible() == - true. - -
Effects: Creates an appropriately-typed Boost.Python - extension class instance, uses MakeHolder to create - an instance_holder from x, installs - the instance_holder in the new extension class - instance, and returns a pointer to it. - -
- - -

Class template to_python_indirect statics

-
-bool convertible();
-
- -
Effects: Returns true iff any module has - registered a Python type corresponding to U. - -

Example

- -This example replicates the functionality of reference_existing_object, -but without some of the compile-time error checking. - - -
-
-struct make_reference_holder
-{
-   typedef boost::python::objects::instance_holder* result_type;
-   template <class T>
-   static result_type execute(T* p)
-   {
-      return new boost::python::objects::pointer_holder<T*, T>(p);
-   }
-};
-
-struct reference_existing_object
-{
-   // metafunction returning the ResultConverter
-   template <class T>
-   struct apply
-   {
-      typedef boost::python::to_python_indirect<T,make_reference_holder> type;
-   };
-};
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/to_python_value.html b/doc/v2/to_python_value.html deleted file mode 100644 index 76446024..00000000 --- a/doc/v2/to_python_value.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - Boost.Python - <boost/python/to_python_value.hpp> - - - -
-

-

- -
-

Boost.Python

- -

Header - <boost/python/to_python_value.hpp>

-
-


- -

Contents

- -
-
Classes - -
-
-
Class - to_python_value - -
-
-
Class template - to_python_value synopsis - -
Class template - to_python_value observer functions -
-
- -
-
- -

Classes

- -

Class template - to_python_value

- -

to_python_value is a model of ResultConverter - which copies its argument into a new Python object. - -

Class - to_python_value synopsis

-
-namespace boost { namespace python
-{
-   template <class T>
-   struct to_python_value
-   {
-      typedef typename add_reference<
-         typename add_const<T>::type
-      >::type argument_type;
-
-      static bool convertible();
-      PyObject* operator()(argument_type) const;
-   };
-}}
-
- -

Class - to_python_value observers

-
-static bool convertible();
-
- -
-
Returns: true iff a converter has been registered which can convert T to python by-value. -
- -
-PyObject* operator()(argument_type x) const;
-
- -
-
Requires: convertible() == true -
Effects: converts x to python -
Returns: the resulting Python object iff a converter for T has been registered, 0 otherwise. -
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/tuple.html b/doc/v2/tuple.html deleted file mode 100644 index 3108cc5f..00000000 --- a/doc/v2/tuple.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/tuple.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/tuple.hpp>

-
-


- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class tuple
- -
-
-
Class tuple - synopsis
-
-
-
-
- -
Functions
- -
-
-
make_tuple
-
-
- -
Example
-
-
- -

Introduction

- -

Exposes a TypeWrapper for the Python - - tuple type.

- -

Classes

- -

Class tuple

- -

Exposes the interface of Python's built-in tuple type. - The semantics of the constructors and member functions defined below can - be fully understood by reading the TypeWrapper concept - definition. Since tuple is publicly derived from object, the public object - interface applies to tuple instances as well.

- -

Class tuple - synopsis

-
-namespace boost { namespace python
-{
-   class tuple : public object
-   {
-      // tuple() -> an empty tuple
-      tuple();
-
-      // tuple(sequence) -> tuple initialized from sequence's items
-      template <class T>
-      explicit tuple(T const& sequence)
-  };
-}}
-
- -

Functions

- -

make_tuple

-
-namespace boost { namespace python
-{
-  tuple make_tuple();
-
-  template <class A0>
-  tuple make_tuple(A0 const& a0);
-
-  template <class A0, class A1>
-  tuple make_tuple(A0 const& a0, A1 const& a1);
-  ...
-  template <class A0, class A1,...class An> 
-  tuple make_tuple(A0 const& a0, A1 const& a1,...An const& an);
-}}
-
- Constructs a new tuple object composed of object(a0), - object(a0),...object(an). - -

Example

-
-using namespace boost::python;
-tuple head_and_tail(object sequence)
-{
-    return make_tuple(sequence[0],sequence[-1]);
-}
-
- -

Revised 03 October, 2002

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

- - - diff --git a/doc/v2/type_id.html b/doc/v2/type_id.html deleted file mode 100755 index 62300206..00000000 --- a/doc/v2/type_id.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - Boost.Python - <boost/python/type_id.hpp> - - - - -
-

C++ Boost

- -
-

Boost.Python

- -

Header <boost/python/type_id.hpp>

-
-
- -

Contents

- -
-
Introduction - -
Classes - -
-
-
Class - type_info - -
-
-
Class - type_info synopsis - -
Class - type_info constructor - -
Class - type_info comparison functions - -
Class - type_info observer functions -
-
- -
Functions - -
-
-
type_id -
- -
Example -
-
- -

Introduction

- -

<boost/python/type_id.hpp> provides types and - functions for runtime type identification like those of of - <typeinfo>. It exists mostly to work around - certain compiler bugs and platform-dependent interactions with - shared libraries. - -

Classes

- -

Class type_info

- -

type_info instances identify a type. As - std::type_info is specified to (but unlike its - implementation in some compilers), - boost::python::type_info never represents top-level - references or cv-qualification (see section 5.2.8 in the C++ - standard). Unlike std::type_info, - boost::python::type_info instances are copyable, and - comparisons always work reliably across shared library boundaries. - -

Class type_info - synopsis

-
-namespace boost { namespace python
-{
-  class type_info : totally_ordered<type_info>
-  {
-   public:
-      // constructor
-      type_info(std::type_info const& = typeid(void));
-
-      // comparisons
-      bool operator<(type_info const& rhs) const;
-      bool operator==(type_info const& rhs) const;
-
-      // observers
-      char const* name() const;
-  };
-}}
-
- -

Class type_info - constructor

-
-type_info(std::type_info const& = typeid(void));
-
- -
-
Effects: constructs a type_info object - which identifies the same type as its argument. - -
Rationale: Since it is occasionally neccessary to make - an array of type_info objects a benign default - argument is supplied. Note: this - constructor does not correct for non-conformance of - compiler typeid() implementations. See type_id, below. -
- -

Class - type_info comparisons

-
-bool operator<(type_info const& rhs) const;
-
- -
-
Effects: yields a total order over - type_info objects. -
-
-bool operator==(type_info const& rhs) const;
-
- -
-
Returns: true iff the two values describe - the same type. -
- -
-
Note: The use of totally_ordered<type_info> - as a private base class supplies operators <=, - >=, >, and != -
- -

Class type_info - observers

-
-char const* name() const;
-
- -
-
Returns: The result of calling name() on - the argument used to construct the object. -
- -

Functions

-
-std::ostream& operator<<(std::ostream&s, type_info const&x);
-
- -
-
Effects: Writes a description of the type described by - to x into s. - -
Rationale: Not every C++ implementation provides a - truly human-readable type_info::name() string, but - for some we may be able to decode the string and produce a - reasonable representation. -
-
-template <class T> type_info type_id()
-
- -
-
Returns: type_info(typeid(T)) - -
Note: On some non-conforming C++ implementations, the - code is not actually as simple as described above; the semantics - are adjusted to work as-if the C++ implementation were - conforming. -
- -

Example

- The following example, though silly, illustrates how the - type_id facility might be used -
-#include <boost/python/type_id.hpp>
-
-// Returns true iff the user passes an int argument
-template <class T>
-bool is_int(T x)
-{
-   using boost::python::type_id;
-   return type_id<T>() == type_id<int>();
-}
-
- -

Revised - - 13 November, 2002 - - - -

© Copyright Dave Abrahams 2002. All - Rights Reserved. - diff --git a/doc/v2/with_custodian_and_ward.html b/doc/v2/with_custodian_and_ward.html deleted file mode 100644 index e6fc15df..00000000 --- a/doc/v2/with_custodian_and_ward.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - - Boost.Python - <boost/python/with_custodian_and_ward.hpp> - - - - - - - - -
-

- C++ Boost - -

-
-

- Boost.Python -

-

- Header <boost/python/with_custodian_and_ward.hpp> -

-
-


-

- Contents -

-
-
- Introduction -
-
- Classes -
-
-
-
- Class Template - with_custodian_and_ward -
-
-
-
- Class - Template with_custodian_and_ward synopsis -
-
- Class - with_custodian_and_ward static functions -
-
-
-
- Class Template - with_custodian_and_ward_postcall -
-
-
-
- Class - Template with_custodian_and_ward_postcall - synopsis -
-
- Class - with_custodian_and_ward_postcall static - functions -
-
-
-
-
-
- Example -
-
-
-

- Introduction -

This header provides faciliites for establishing a lifetime - dependency between two of a function's Python argument or result objects. - The ward object will not be destroyed until after the custodian as - long as the custodian object supports weak - references (Boost.Python extension classes all support weak - references). If the custodian object does not support weak - references and is not None, an appropriate exception will be - thrown. The two class templates with_custodian_and_ward and - with_custodian_and_ward_postcall differ in the point at - which they take effect. -

- In order to reduce the chance of inadvertently creating dangling - pointers, the default is to do lifetime binding before the - underlying C++ object is invoked. However, before invocation the result - object is not available, so - with_custodian_and_ward_postcall is provided to bind - lifetimes after invocation. Also, if a C++ exception is thrown after - with_custodian_and_ward<>::precall but before the - underlying C++ object actually stores a pointer, the lifetime of the - custodian and ward objects will be artificially bound together, so one - might choose with_custodian_and_ward_postcall instead, - depending on the semantics of the function being wrapped. -

-

- Please note that this is not the appropriate tool to use when - wrapping functions which transfer ownership of a raw pointer - across the function-call boundary. Please see the FAQ if you want to do that. -

-

- Classes -

-

- Class template - with_custodian_and_ward -

- - - - - - - - - - - - - - - - - - - - - - - - -
- with_custodian_and_ward template parameters -
- Parameter - - Requirements - - Description - - Default -
- custodian - - A positive compile-time constant of type std::size_t. - - The 1-based index of the parameter which is the dependency in the - lifetime relationship to be established. If used to wrap a member - function, parameter 1 is the target object (*this). - Note that if the target Python object type doesn't support weak - references, a Python TypeError exception will be - raised when the C++ object being wrapped is called. -
- ward - - A positive compile-time constant of type std::size_t. - - The 1-based index of the parameter which is the dependent in the - lifetime relationship to be established. If used to wrap a member - function, parameter 1 is the target object (*this). -
- Base - - A model of CallPolicies - - Used for policy - composition. - - default_call_policies -
-

- Class template - with_custodian_and_ward synopsis -

-
-namespace boost { namespace python
-{
-   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
-   struct with_custodian_and_ward : Base
-   {
-      static bool precall(PyObject* args);
-   };
-}}
-
-

- Class - with_custodian_and_ward static functions -

-
-bool precall(PyObject* args);
-
-
-
- Requires: PyTuple_Check(args) - != 0 -
-
- Effects: Makes the lifetime of the argument indicated by - ward dependent on the lifetime of the argument indicated - by custodian. -
-
- Returns: false and PyErr_Occurred() != 0 - upon failure, true otherwise. -
-
-

- Class template - with_custodian_and_ward_postcall -

- - - - - - - - - - - - - - - - - - - - - - - - -
- with_custodian_and_ward_postcall template - parameters -
- Parameter - - Requirements - - Description - - Default -
- custodian - - A compile-time constant of type std::size_t. - - The index of the parameter which is the dependency in the lifetime - relationship to be established. Zero indicates the result object; 1 - indicates the first argument. If used to wrap a member function, - parameter 1 is the target object (*this). Note that if - the target Python object type doesn't support weak references, a - Python TypeError exception will be raised when the C++ - object being wrapped is called. -
- ward - - A compile-time constant of type std::size_t. - - The index of the parameter which is the dependent in the lifetime - relationship to be established. Zero indicates the result object; 1 - indicates the first argument. If used to wrap a member function, - parameter 1 is the target object (*this). -
- Base - - A model of CallPolicies - - Used for policy - composition. - - default_call_policies -
-

- Class - template with_custodian_and_ward_postcall synopsis -

-
-namespace boost { namespace python
-{
-   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
-   struct with_custodian_and_ward_postcall : Base
-   {
-      static PyObject* postcall(PyObject* args, PyObject* result);
-   };
-}}
-
-

- Class - with_custodian_and_ward_postcall static functions -

-
-PyObject* postcall(PyObject* args, PyObject* result);
-
-
-
- Requires: PyTuple_Check(args) - != 0, result != 0. -
-
- Effects: Makes the lifetime of the object indicated by - ward dependent on the lifetime of the object indicated - by custodian. -
-
- Returns: 0 and PyErr_Occurred() != 0 - upon failure, true otherwise. -
-
-

- Example -

The following example shows how - with_custodian_and_ward_postcall is used by the library to - implement return_internal_reference - -
-template <std::size_t owner_arg = 1, class Base = default_call_policies>
-struct return_internal_reference
-    : with_custodian_and_ward_postcall<0, owner_arg, Base>
-{
-   typedef reference_existing_object result_converter;
-};
-
-

- Revised - - 13 November, 2002 - -

-

- © Copyright Dave - Abrahams 2002. All Rights Reserved. -

- - diff --git a/example/Attic/project.zip b/example/Attic/project.zip deleted file mode 100644 index d863defdb784ca6864f83a6ca22443b65259bda6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF diff --git a/example/Jamfile b/example/Jamfile deleted file mode 100644 index 83664cc2..00000000 --- a/example/Jamfile +++ /dev/null @@ -1,61 +0,0 @@ -# Specify our location in the boost project hierarchy -subproject libs/python/example ; - -# Declares the following targets: -# -# 1. an extension module called "getting_started1", which is -# built from "getting_started1.cpp". Built by default -# -# 2. A test target called my-test.test which runs -# test_getting_started1.py with the extension module above. Built -# when out-of date, but only if invoked by name or if the global -# "test" target is invoked. -# -# 3. A test target called my-test.run wihch runs the above test -# unconditionally. Built only when invoked by name. -# -# To see verbose test output, add "-sPYTHON_TEST_ARGS=-v" to the bjam -# command-line before the first target. -# - -# Include definitions needed for Python modules -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -# ----- getting_started1 ------- - -# Declare a Python extension called getting_started1 -extension getting_started1 -: # sources - getting_started1.cpp - - # dependencies - ../build/boost_python - ; - -# Declare a test for the extension module -boost-python-runtest test1 - : # Python test driver - test_getting_started1.py - # extension modules to use - getting_started1 ; - - - -# ----- getting_started2 ------- - -# Declare a Python extension called getting_started2 -extension getting_started2 -: # sources - getting_started2.cpp - - # dependencies - ../build/boost_python - ; - -# Declare a test for the extension module -boost-python-runtest test2 - : # Python test driver - test_getting_started2.py - # extension modules to use - getting_started2 ; \ No newline at end of file diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 deleted file mode 100644 index cf7a2972..00000000 --- a/example/Jamfile.v2 +++ /dev/null @@ -1,12 +0,0 @@ - -use-project /boost/python : ../build ; - -project - : requirements @/boost/python/boost_python - ; - -python-extension getting_started1 : getting_started1.cpp : true ; -python-extension getting_started2 : getting_started2.cpp : true ; - -exe embedding_test : embedding_test.cpp : BOOST_PYTHON_DYNAMIC_LIB true ; - diff --git a/example/README b/example/README deleted file mode 100644 index ab22de54..00000000 --- a/example/README +++ /dev/null @@ -1,6 +0,0 @@ -To get started with the Boost Python Library, use the examples -getting_started1.cpp and getting_started2.cpp. - - bjam -sTOOLS=your-toolset test - -in this directory will build and run the examples. diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp deleted file mode 100644 index bdb79edc..00000000 --- a/example/getting_started1.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -#include - -namespace { // Avoid cluttering the global namespace. - - // A couple of simple C++ functions that we want to expose to Python. - std::string greet() { return "hello, world"; } - int square(int number) { return number * number; } -} - -#include -#include -namespace python = boost::python; - -// Python requires an exported function called init in every -// extension module. This is where we build the module contents. -BOOST_PYTHON_MODULE(getting_started1) -{ - // Add regular functions to the module. - python::def("greet", greet); - python::def("square", square); -} diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp deleted file mode 100644 index bec7447e..00000000 --- a/example/getting_started2.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -#include -#include - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class hello - { - public: - hello(const std::string& country) { this->country = country; } - std::string greet() const { return "Hello from " + country; } - private: - std::string country; - }; - - // A function taking a hello object as an argument. - std::string invite(const hello& w) { - return w.greet() + "! Please come soon!"; - } -} - -#include -#include -#include - -BOOST_PYTHON_MODULE(getting_started2) -{ - using namespace boost::python; - class_("hello", init()) - // Add a regular member function. - .def("greet", &hello::greet) - // Add invite() as a member of hello! - .def("invite", invite) - ; - - // Also add invite() as a regular function to the module. - def("invite", invite); -} diff --git a/example/project.zip b/example/project.zip deleted file mode 100644 index d863defdb784ca6864f83a6ca22443b65259bda6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF diff --git a/example/tutorial/Jamfile b/example/tutorial/Jamfile deleted file mode 100644 index c05463c1..00000000 --- a/example/tutorial/Jamfile +++ /dev/null @@ -1,15 +0,0 @@ -# Hello World Example from the tutorial -# [Joel de Guzman 10/9/2002] - -# Specify our location in the boost project hierarchy -subproject libs/python/example/tutorial ; - -# Include definitions needed for Python modules -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -extension hello # Declare a Python extension called hello -: hello.cpp # source - ../../build/boost_python # dependencies - ; - diff --git a/example/tutorial/hello.cpp b/example/tutorial/hello.cpp deleted file mode 100644 index 01ed60c3..00000000 --- a/example/tutorial/hello.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Hello World Example from the tutorial -// [Joel de Guzman 10/9/2002] - -char const* greet() -{ - return "hello, world"; -} - -#include -#include -using namespace boost::python; - -BOOST_PYTHON_MODULE(hello) -{ - def("greet", greet); -} - diff --git a/include/boost/python/arg_from_python.hpp b/include/boost/python/arg_from_python.hpp deleted file mode 100755 index b30c70eb..00000000 --- a/include/boost/python/arg_from_python.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARG_FROM_PYTHON_DWA2002128_HPP -# define ARG_FROM_PYTHON_DWA2002128_HPP - -# include -# include - -namespace boost { namespace python { - -template -struct arg_from_python - : converter::select_arg_from_python::type -{ - typedef typename converter::select_arg_from_python::type base; - arg_from_python(PyObject*); -}; - -// specialization for PyObject* -template <> -struct arg_from_python -{ - typedef PyObject* result_type; - - arg_from_python(PyObject*) {} - bool convertible() const { return true; } - PyObject* operator()(PyObject* source) const { return source; } -}; - -template <> -struct arg_from_python -{ - typedef PyObject* const& result_type; - arg_from_python(PyObject*) {} - bool convertible() const { return true; } - PyObject*const& operator()(PyObject*const& source) const { return source; } -}; - -namespace detail -{ - // - // Meta-iterators for use with caller<> - // - - // temporary hack - template struct nullary : T - { - nullary(PyObject* x) : T(x), m_p(x) {} - typename T::result_type operator()() { return this->T::operator()(m_p); } - PyObject* m_p; - }; - - // An MPL metafunction class which returns arg_from_python - struct gen_arg_from_python - { - template struct apply - { - typedef nullary > type; - }; - }; - - // An MPL iterator over an endless sequence of gen_arg_from_python - struct args_from_python - { - typedef gen_arg_from_python type; - typedef args_from_python next; - }; -} - -// -// implementations -// -template -inline arg_from_python::arg_from_python(PyObject* source) - : base(source) -{ -} - -}} // namespace boost::python - -#endif // ARG_FROM_PYTHON_DWA2002128_HPP diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp deleted file mode 100644 index b2b76c87..00000000 --- a/include/boost/python/args.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef KEYWORDS_DWA2002323_HPP -# define KEYWORDS_DWA2002323_HPP - -# include -# include -# include -# include - -# include -# include -# include - -# include -# include -# include -# include - -# include -# include - -# include -# include - - -namespace boost { namespace python { - -namespace detail -{ - template - struct keywords - { - BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords); - - keyword_range range() const - { - return keyword_range(elements, elements + nkeywords); - } - - keyword elements[nkeywords]; - }; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct is_keywords - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; - - template - struct is_keywords > - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - template - struct is_reference_to_keywords - { - BOOST_STATIC_CONSTANT(bool, is_ref = is_reference::value); - typedef typename remove_reference::type deref; - typedef typename remove_cv::type key_t; - BOOST_STATIC_CONSTANT(bool, is_key = is_keywords::value); - BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key)); - - typedef mpl::bool_ type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) - }; -# else - typedef char (&yes_keywords_t)[1]; - typedef char (&no_keywords_t)[2]; - - no_keywords_t is_keywords_test(...); - - template - yes_keywords_t is_keywords_test(void (*)(keywords&)); - - template - yes_keywords_t is_keywords_test(void (*)(keywords const&)); - - template - class is_reference_to_keywords - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_keywords_test( (void (*)(T))0 )) - == sizeof(detail::yes_keywords_t))); - - typedef mpl::bool_ type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) - }; -# endif -} - -# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n; -# define BOOST_PP_LOCAL_MACRO(n) \ -inline detail::keywords args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \ -{ \ - detail::keywords result; \ - BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \ - return result; \ -} -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) -# include BOOST_PP_LOCAL_ITERATE() - -}} // namespace boost::python - - -# endif // KEYWORDS_DWA2002323_HPP diff --git a/include/boost/python/args_fwd.hpp b/include/boost/python/args_fwd.hpp deleted file mode 100644 index e310f761..00000000 --- a/include/boost/python/args_fwd.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARGS_FWD_DWA2002927_HPP -# define ARGS_FWD_DWA2002927_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - struct keyword - { - char const* name; - handle<> default_value; - }; - - template struct keywords; - - typedef std::pair keyword_range; - - template <> - struct keywords<0> - { - BOOST_STATIC_CONSTANT(std::size_t, size = 0); - static keyword_range range() { return keyword_range(); } - }; - - namespace error - { - template - struct more_keywords_than_function_arguments - { - typedef char too_many_keywords[keywords > function_args ? -1 : 1]; - }; - } -} - -}} // namespace boost::python - -#endif // ARGS_FWD_DWA2002927_HPP diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp deleted file mode 100644 index 75a14525..00000000 --- a/include/boost/python/back_reference.hpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BACK_REFERENCE_DWA2002510_HPP -# define BACK_REFERENCE_DWA2002510_HPP - -# include -# include -# include - -namespace boost { namespace python { - -template -struct back_reference -{ - private: // types - typedef typename detail::dependent::type source_t; - public: - typedef T type; - - back_reference(PyObject*, T); - source_t const& source() const; - T get() const; - private: - source_t m_source; - T m_value; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class is_back_reference -{ - public: - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -class is_back_reference > -{ - public: - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -# else // no partial specialization - -}} // namespace boost::python - -#include - -namespace boost { namespace python { - -namespace detail -{ - typedef char (&yes_back_reference_t)[1]; - typedef char (&no_back_reference_t)[2]; - - no_back_reference_t is_back_reference_test(...); - - template - yes_back_reference_t is_back_reference_test(boost::type< back_reference >); -} - -template -class is_back_reference -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_back_reference_test(boost::type())) - == sizeof(detail::yes_back_reference_t))); -}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -// -// implementations -// -template -back_reference::back_reference(PyObject* p, T x) - : m_source(detail::borrowed_reference(p)) - , m_value(x) -{ -} - -template -typename back_reference::source_t const& back_reference::source() const -{ - return m_source; -} - -template -T back_reference::get() const -{ - return m_value; -} - -}} // namespace boost::python - -#endif // BACK_REFERENCE_DWA2002510_HPP diff --git a/include/boost/python/base_type_traits.hpp b/include/boost/python/base_type_traits.hpp deleted file mode 100755 index cae9ebc2..00000000 --- a/include/boost/python/base_type_traits.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BASE_TYPE_TRAITS_DWA2002614_HPP -# define BASE_TYPE_TRAITS_DWA2002614_HPP - -namespace boost { namespace python { - -namespace detail -{ - struct unspecialized {}; -} - -// Derive from unspecialized so we can detect whether traits are -// specialized -template struct base_type_traits - : detail::unspecialized -{}; - -template <> -struct base_type_traits -{ - typedef PyObject type; -}; - -template <> -struct base_type_traits -{ - typedef PyObject type; -}; - -}} // namespace boost::python - -#endif // BASE_TYPE_TRAITS_DWA2002614_HPP diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp deleted file mode 100644 index 5b6ea8c3..00000000 --- a/include/boost/python/bases.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BASES_DWA2002321_HPP -# define BASES_DWA2002321_HPP -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -# define BOOST_PYTHON_BASE_PARAMS BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, Base) - - // A type list for specifying bases - template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename Base, mpl::void_) > - struct bases : detail::type_list< BOOST_PYTHON_BASE_PARAMS >::type - {}; - - namespace detail - { -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template struct specifies_bases - : mpl::false_ - { - }; - - template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class Base) > - struct specifies_bases< bases< BOOST_PYTHON_BASE_PARAMS > > - : mpl::true_ - { - }; -# else - template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class Base) > - static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&); - - static char (& is_bases_helper(...) )[256]; - - template - struct specifies_bases - { - private: - static typename add_reference::type make(); - BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference::value); - public: - BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1)); - typedef mpl::bool_ type; - }; -# endif - template > - struct select_bases - : mpl::if_< - specifies_bases - , T - , Prev - > - { - }; - } -# undef BOOST_PYTHON_BASE_PARAMS -}} // namespace boost::python - -#endif // BASES_DWA2002321_HPP diff --git a/include/boost/python/borrowed.hpp b/include/boost/python/borrowed.hpp deleted file mode 100755 index 10b1b5d1..00000000 --- a/include/boost/python/borrowed.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BORROWED_DWA2002614_HPP -# define BORROWED_DWA2002614_HPP -# include - -namespace boost { namespace python { - -template -inline python::detail::borrowed* borrowed(T* p) -{ - return (detail::borrowed*)p; -} - -}} // namespace boost::python - -#endif // BORROWED_DWA2002614_HPP diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp deleted file mode 100644 index d80cba3c..00000000 --- a/include/boost/python/call.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef CALL_DWA2002411_HPP -# define CALL_DWA2002411_HPP - -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \ - , converter::arg_to_python(a##n).get() - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET - -}} // namespace boost::python - -# endif // CALL_DWA2002411_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -# line BOOST_PP_LINE(__LINE__, call.hpp) - -# define N BOOST_PP_ITERATION() - -template < - class R - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > -typename detail::returnable::type -call(PyObject* callable - BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) - , boost::type* = 0 - ) -{ - converter::return_from_python converter; - return converter( - PyEval_CallFunction( - callable - , const_cast("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")") - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) - )); -} - -# undef N - -#endif diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp deleted file mode 100644 index 347f866c..00000000 --- a/include/boost/python/call_method.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -# ifndef CALL_METHOD_DWA2002411_HPP -# define CALL_METHOD_DWA2002411_HPP - -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \ - , converter::arg_to_python(a##n).get() - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET - -}} // namespace boost::python - -# endif // CALL_METHOD_DWA2002411_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -# line BOOST_PP_LINE(__LINE__, call_method.hpp) - -# define N BOOST_PP_ITERATION() - -template < - class R - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > -typename detail::returnable::type -call_method(PyObject* self, char const* name - BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) - , boost::type* = 0 - ) -{ - converter::return_from_python converter; - return converter( - PyEval_CallMethod( - self - , const_cast(name) - , const_cast("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")") - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) - )); -} - -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/cast.hpp b/include/boost/python/cast.hpp deleted file mode 100755 index d20cbd3a..00000000 --- a/include/boost/python/cast.hpp +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CAST_DWA200269_HPP -# define CAST_DWA200269_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template inline Target* upcast_impl(Source*, Target*); - - template - inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*) - { - return p; - } - - template - inline Target* upcast(Source* p, no_convertible, no_convertible, Target*) - { - typedef typename base_type_traits::type base; - - return detail::upcast_impl((base*)p, (Target*)0); - } - - template - struct upcaster - { - template - static inline T* execute(T* x, T*) { return x; } - }; - - template <> - struct upcaster - { - template - static inline Target* execute(Source* x, Target*) - { - return detail::upcast( - x, detail::convertible::check(x) - , detail::convertible::check((Target*)0) - , (Target*)0); - } - }; - - - template - inline Target* downcast(Source* p, yes_convertible) - { - return static_cast(p); - } - - template - inline Target* downcast(Source* p, no_convertible, boost::type* = 0) - { - typedef typename base_type_traits::type base; - return (Target*)detail::downcast(p, convertible::check((base*)0)); - } - - template - inline void assert_castable(boost::type* = 0) - { - typedef char must_be_a_complete_type[sizeof(T)]; - } - - template - inline Target* upcast_impl(Source* x, Target*) - { - typedef typename add_cv::type src_t; - typedef typename add_cv::type target_t; - static bool const same = is_same::value; - - return detail::upcaster::execute(x, (Target*)0); - } -} - -template -inline Target* upcast(Source* x, Target* = 0) -{ - detail::assert_castable(); - detail::assert_castable(); - return detail::upcast_impl(x, (Target*)0); - -} - -template -inline Target* downcast(Source* x, Target* = 0) -{ - detail::assert_castable(); - detail::assert_castable(); - return detail::downcast(x, detail::convertible::check((Target*)0)); -} - -}} // namespace boost::python - -#endif // CAST_DWA200269_HPP diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp deleted file mode 100644 index fd1d7411..00000000 --- a/include/boost/python/class.hpp +++ /dev/null @@ -1,548 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_DWA200216_HPP -# define CLASS_DWA200216_HPP - -# include -# include - -# include -# include -# include -# include -# include -# include -# include -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -# include -# include - -namespace boost { namespace python { - -enum no_init_t { no_init }; - -namespace detail -{ - // This function object is used with mpl::for_each to write the id - // of the type a pointer to which is passed as its 2nd compile-time - // argument. into the iterator pointed to by its runtime argument - struct write_type_id - { - write_type_id(type_info**p) : p(p) {} - - // Here's the runtime behavior - template - void operator()(T*) const - { - *(*p)++ = type_id(); - } - - type_info** p; - }; - - template - struct select_held_type; - - template - struct has_noncopyable; - - template - struct operator_; - - // Register to_python converters for a class T. The first argument - // will be mpl::true_ unless noncopyable was specified as a - // class_<...> template parameter. The 2nd argument is a pointer to - // the type of holder that must be created. The 3rd argument is a - // reference to the Python type object to be created. - template - inline void register_class_to_python(mpl::true_ copyable, SelectHolder selector, T* = 0) - { - typedef typename SelectHolder::type holder; - force_instantiate(objects::class_cref_wrapper >()); - SelectHolder::register_(); - } - - template - inline void register_class_to_python(mpl::false_ copyable, SelectHolder selector, T* = 0) - { - SelectHolder::register_(); - } - - namespace error - { - // - // A meta-assertion mechanism which prints nice error messages and - // backtraces on lots of compilers. Usage: - // - // assertion::failed - // - // where C is an MPL metafunction class - // - - template struct assertion_failed { }; - template struct assertion_ok { typedef C failed; }; - - template - struct assertion - : mpl::if_, assertion_failed >::type - {}; - - // - // Checks for validity of arguments used to define virtual - // functions with default implementations. - // - - template - void not_a_derived_class_member(Default) {} - - template - struct virtual_function_default - { - template - static void - must_be_derived_class_member(Default const&) - { - typedef typename assertion > >::failed test0; -# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - typedef typename assertion >::failed test1; -# endif - typedef typename assertion >::failed test2; - not_a_derived_class_member(Fn()); - } - }; - } -} - -// This is the primary mechanism through which users will expose -// C++ classes to Python. -template < - class T // class being wrapped - , class X1 // = detail::not_specified - , class X2 // = detail::not_specified - , class X3 // = detail::not_specified - > -class class_ : public objects::class_base -{ - public: // types - typedef objects::class_base base; - typedef T wrapped_type; - - typedef class_ self; - BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); - - typedef typename detail::select_held_type< - X1, typename detail::select_held_type< - X2, typename detail::select_held_type< - X3 - >::type>::type>::type held_type; - - typedef objects::select_holder holder_selector; - - private: // types - - typedef typename detail::select_bases::type - >::type - >::type bases; - - - // A helper class which will contain an array of id objects to be - // passed to the base class constructor - struct id_vector - { - id_vector() - { - // Stick the derived class id into the first element of the array - ids[0] = type_id(); - - // Write the rest of the elements into succeeding positions. - type_info* p = ids + 1; - mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer*)0); - } - - BOOST_STATIC_CONSTANT( - std::size_t, size = mpl::size::value + 1); - type_info ids[size]; - }; - friend struct id_vector; - - public: // constructors - - // Construct with the class name, with or without docstring, and default __init__() function - class_(char const* name, char const* doc = 0); - - // Construct with class name, no docstring, and an uncallable __init__ function - class_(char const* name, no_init_t); - - // Construct with class name, docstring, and an uncallable __init__ function - class_(char const* name, char const* doc, no_init_t); - - // Construct with class name and init<> function - template - inline class_(char const* name, init_base const& i) - : base(name, id_vector::size, id_vector().ids) - { - this->register_(); - define_init(*this, i.derived()); - this->set_instance_size(holder_selector::additional_size()); - } - - // Construct with class name, docstring and init<> function - template - inline class_(char const* name, char const* doc, init_base const& i) - : base(name, id_vector::size, id_vector().ids, doc) - { - this->register_(); - define_init(*this, i.derived()); - this->set_instance_size(holder_selector::additional_size()); - } - - public: // member functions - - // Define additional constructors - template - self& def(init_base const& i) - { - define_init(*this, i.derived()); - return *this; - } - - // Wrap a member function or a non-member function which can take - // a T, T cv&, or T cv* as its first parameter, or a callable - // python object. - template - self& def(char const* name, F f) - { - this->def_impl(name, f, detail::def_helper(0), &f); - return *this; - } - - template - self& def(char const* name, A1 a1, A2 const& a2) - { - this->def_maybe_overloads(name, a1, a2, &a2); - return *this; - } - - template - self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2) - { - // The arguments are definitely: - // def(name, function, policy, doc_string) - // def(name, function, doc_string, policy) - - this->def_impl( - name, fn - , detail::def_helper(a1,a2) - , &fn); - - return *this; - } - - template - self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3) - { - this->def_impl( - name, fn - , detail::def_helper(a1,a2,a3) - , &fn); - - return *this; - } - - template - self& def(detail::operator_ const& op) - { - typedef detail::operator_ op_t; - return this->def(op.name(), &op_t::template apply::execute); - } - - // - // Data member access - // - template - self& def_readonly(char const* name, D B::*pm_) - { - D T::*pm = pm_; - this->add_property(name, make_getter(pm)); - return *this; - } - - template - self& def_readwrite(char const* name, D B::*pm_) - { - D T::*pm = pm_; - return this->add_property(name, make_getter(pm), make_setter(pm)); - } - - // Property creation - template - self& add_property(char const* name, Get fget) - { - base::add_property( - name - , object( - detail::member_function_cast::stage1(fget).stage2((T*)0).stage3(fget) - ) - ); - - return *this; - } - - template - self& add_property(char const* name, Get fget, Set fset) - { - base::add_property( - name - , object( - detail::member_function_cast::stage1(fget).stage2((T*)0).stage3(fget) - ) - , object( - detail::member_function_cast::stage1(fset).stage2((T*)0).stage3(fset) - ) - ); - return *this; - } - - template - self& setattr(char const* name, U const& x) - { - this->base::setattr(name, object(x)); - return *this; - } - - // Pickle support - template - self& def_pickle(PickleSuiteType const& x) - { - error_messages::must_be_derived_from_pickle_suite(x); - detail::pickle_suite_finalize::register_( - *this, - &PickleSuiteType::getinitargs, - &PickleSuiteType::getstate, - &PickleSuiteType::setstate, - PickleSuiteType::getstate_manages_dict()); - return *this; - } - - self& staticmethod(char const* name) - { - this->make_method_static(name); - return *this; - } - private: // helper functions - - inline void register_() const; - - // - // These two overloads discriminate between def() as applied to - // things which are already wrapped into callable python::object - // instances and everything else. - // - template - inline void def_impl( - char const* name - , F f - , detail::def_helper const& helper - , object const*) - { - // It's too late to specify anything other than docstrings, if - // the callable object is already wrapped. - BOOST_STATIC_ASSERT( - (is_same::value - || detail::is_string_literal::value)); - - objects::add_to_namespace(*this, name, f, helper.doc()); - } - - template - inline void def_impl( - char const* name - , Fn fn - , Helper const& helper - , ...) - { - objects::add_to_namespace( - *this, name, - make_function( - // This bit of nastiness casts F to a member function of T if possible. - detail::member_function_cast::stage1(fn).stage2((T*)0).stage3(fn) - , helper.policies(), helper.keywords()) - , helper.doc()); - - this->def_default(name, fn, helper, mpl::bool_()); - } - - // - // These two overloads handle the definition of default - // implementation overloads for virtual functions. The second one - // handles the case where no default implementation was specified. - // - template - inline void def_default( - char const* name - , Fn fn - , Helper const& helper - , mpl::bool_) - { - detail::error::virtual_function_default::must_be_derived_class_member( - helper.default_implementation()); - - objects::add_to_namespace( - *this, name, - make_function( - helper.default_implementation(), helper.policies(), helper.keywords()) - ); - } - - template - inline void def_default(char const*, Fn, Helper const&, mpl::bool_) - { } - - // - // These two overloads discriminate between def() as applied to - // regular functions and def() as applied to the result of - // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to - // discriminate. - // - template - void def_maybe_overloads( - char const* name - , SigT sig - , OverloadsT const& overloads - , detail::overloads_base const*) - - { - // convert sig to a type_list (see detail::get_signature in signature.hpp) - // before calling detail::define_with_defaults. - detail::define_with_defaults( - name, overloads, *this, detail::get_signature(sig)); - } - - template - void def_maybe_overloads( - char const* name - , Fn fn - , A1 const& a1 - , ...) - { - this->def_impl( - name, fn - , detail::def_helper(a1) - , &fn); - - } -}; - - -// -// implementations -// - -// register converters -template -inline void class_::register_() const -{ - objects::register_class_from_python(); - - detail::register_class_to_python( - mpl::bool_() -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - , holder_selector::execute((held_type*)0) -# elif BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - , holder_selector::type() -# else - , typename holder_selector::type() -# endif - ); -} - -template -inline class_::class_(char const* name, char const* doc) - : base(name, id_vector::size, id_vector().ids, doc) -{ - this->register_(); - this->set_instance_size(holder_selector::additional_size()); -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - holder_selector::execute((held_type*)0).assert_default_constructible(); -# else - holder_selector::type::assert_default_constructible(); -# endif - this->def(init<>()); -} - -template -inline class_::class_(char const* name, no_init_t) - : base(name, id_vector::size, id_vector().ids) -{ - this->register_(); - this->def_no_init(); -} - -template -inline class_::class_(char const* name, char const* doc, no_init_t) - : base(name, id_vector::size, id_vector().ids, doc) -{ - this->register_(); - this->def_no_init(); -} - -namespace detail -{ - template - struct has_noncopyable - : mpl::or_< - is_same - , is_same - , is_same - > - {}; - - - template - struct select_held_type - : mpl::if_< - mpl::or_< - specifies_bases - , is_same - > - , Prev - , T - > - { - }; -} - -}} // namespace boost::python - -#endif // CLASS_DWA200216_HPP diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp deleted file mode 100644 index 8aaec6a6..00000000 --- a/include/boost/python/class_fwd.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_FWD_DWA200222_HPP -# define CLASS_FWD_DWA200222_HPP -# include - -namespace boost { namespace python { - -template < - class T // class being wrapped - // arbitrarily-ordered optional arguments. Full qualification needed for MSVC6 - , class X1 = ::boost::python::detail::not_specified - , class X2 = ::boost::python::detail::not_specified - , class X3 = ::boost::python::detail::not_specified - > -class class_; - -}} // namespace boost::python - -#endif // CLASS_FWD_DWA200222_HPP diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp deleted file mode 100755 index b835e633..00000000 --- a/include/boost/python/converter/arg_from_python.hpp +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARG_FROM_PYTHON_DWA2002127_HPP -# define ARG_FROM_PYTHON_DWA2002127_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python -{ - template struct arg_from_python; -}} - -// This header defines Python->C++ function argument converters, -// parametrized on the argument type. - -namespace boost { namespace python { namespace converter { - -// -// lvalue converters -// -// These require that an lvalue of the type U is stored somewhere in -// the Python object being converted. - -// Used when T == U*const& -template -struct pointer_cref_arg_from_python -{ - typedef T result_type; - - pointer_cref_arg_from_python(PyObject*); - T operator()(PyObject*) const; - bool convertible() const; - - private: // storage for a U* - // needed because not all compilers will let us declare U* as the - // return type of operator() -- we return U*const& instead - typename python::detail::referent_storage::type m_result; -}; - -// Base class for pointer and reference converters -struct arg_lvalue_from_python_base -{ - public: // member functions - arg_lvalue_from_python_base(void* result); - bool convertible() const; - - protected: // member functions - void*const& result() const; - - private: // data members - void* m_result; -}; - -// Used when T == U* -template -struct pointer_arg_from_python : arg_lvalue_from_python_base -{ - typedef T result_type; - - pointer_arg_from_python(PyObject*); - T operator()(PyObject*) const; -}; - -// Used when T == U& and (T != V const& or T == W volatile&) -template -struct reference_arg_from_python : arg_lvalue_from_python_base -{ - typedef T result_type; - - reference_arg_from_python(PyObject*); - T operator()(PyObject*) const; -}; - -// =================== - -// -// rvalue converters -// -// These require only that an object of type T can be created from -// the given Python object, but not that the T object exist -// somewhere in storage. -// - -// Used when T is a plain value (non-pointer, non-reference) type or -// a (non-volatile) const reference to a plain value type. -template -struct arg_rvalue_from_python -{ - typedef typename boost::add_reference< - T - // We can't add_const here, or it would be impossible to pass - // auto_ptr args from Python to C++ - >::type result_type; - - arg_rvalue_from_python(PyObject*); - bool convertible() const; - -# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196 - typename arg_rvalue_from_python:: -# endif - result_type operator()(PyObject*); - - private: - rvalue_from_python_data m_data; -}; - - -// ================== - -// Converts to a (PyObject*,T) bundle, for when you need a reference -// back to the Python object -template -struct back_reference_arg_from_python - : boost::python::arg_from_python -{ - typedef T result_type; - - back_reference_arg_from_python(PyObject*); - T operator()(PyObject*); - private: - typedef boost::python::arg_from_python base; -}; - - -// ================== - -// This metafunction selects the appropriate arg_from_python converter -// type for an argument of type T. -template -struct select_arg_from_python -{ - BOOST_STATIC_CONSTANT( - bool, obj_mgr = is_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, obj_mgr_ref = is_reference_to_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ptr_cref - = boost::python::detail::is_reference_to_pointer::value - && boost::python::detail::is_reference_to_const::value - && !boost::python::detail::is_reference_to_volatile::value); - - - BOOST_STATIC_CONSTANT( - bool, ref = - boost::python::detail::is_reference_to_non_const::value - || boost::python::detail::is_reference_to_volatile::value); - - BOOST_STATIC_CONSTANT( - bool, back_ref = - boost::python::is_back_reference::value); - - typedef typename mpl::if_c< - obj_mgr - , object_manager_value_arg_from_python - , typename mpl::if_c< - obj_mgr_ref - , object_manager_ref_arg_from_python - , typename mpl::if_c< - ptr - , pointer_arg_from_python - , typename mpl::if_c< - ptr_cref - , pointer_cref_arg_from_python - , typename mpl::if_c< - ref - , reference_arg_from_python - , typename mpl::if_c< - back_ref - , back_reference_arg_from_python - , arg_rvalue_from_python - >::type - >::type - >::type - >::type - >::type - >::type type; -}; - -// ================== - -// -// implementations -// - -// arg_lvalue_from_python_base -// -inline arg_lvalue_from_python_base::arg_lvalue_from_python_base(void* result) - : m_result(result) -{ -} - -inline bool arg_lvalue_from_python_base::convertible() const -{ - return m_result != 0; -} - -inline void*const& arg_lvalue_from_python_base::result() const -{ - return m_result; -} - -// pointer_cref_arg_from_python -// -namespace detail -{ - // null_ptr_reference -- a function returning a reference to a null - // pointer of type U. Needed so that extractors for T*const& can - // convert Python's None. - template - struct null_ptr_owner - { - static T value; - }; - template T null_ptr_owner::value = 0; - - template - inline U& null_ptr_reference(U&(*)()) - { - return null_ptr_owner::value; - } -} - -template -inline pointer_cref_arg_from_python::pointer_cref_arg_from_python(PyObject* p) -{ - // T == U*const&: store a U* in the m_result storage. Nonzero - // indicates success. If find returns nonzero, it's a pointer to - // a U object. - python::detail::write_void_ptr_reference( - m_result.bytes - , p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee::converters) - , (T(*)())0); -} - -template -inline bool pointer_cref_arg_from_python::convertible() const -{ - return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0; -} -template -inline T pointer_cref_arg_from_python::operator()(PyObject* p) const -{ - return (p == Py_None) // None ==> 0 - ? detail::null_ptr_reference((T(*)())0) - // Otherwise, return a U*const& to the m_result storage. - : python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); -} - -// pointer_arg_from_python -// -template -inline pointer_arg_from_python::pointer_arg_from_python(PyObject* p) - : arg_lvalue_from_python_base( - p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee::converters)) -{ -} - -template -inline T pointer_arg_from_python::operator()(PyObject* p) const -{ - return (p == Py_None) ? 0 : T(result()); -} - -// reference_arg_from_python -// -template -inline reference_arg_from_python::reference_arg_from_python(PyObject* p) - : arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered::converters)) -{ -} - -template -inline T reference_arg_from_python::operator()(PyObject*) const -{ - return python::detail::void_ptr_to_reference(result(), (T(*)())0); -} - - -// arg_rvalue_from_python -// -template -inline arg_rvalue_from_python::arg_rvalue_from_python(PyObject* obj) - : m_data(converter::rvalue_from_python_stage1(obj, registered::converters)) -{ -} - -template -inline bool arg_rvalue_from_python::convertible() const -{ - return m_data.stage1.convertible != 0; -} - -template -inline typename arg_rvalue_from_python::result_type -arg_rvalue_from_python::operator()(PyObject* p) -{ - if (m_data.stage1.construct != 0) - m_data.stage1.construct(p, &m_data.stage1); - - return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); -} - -// back_reference_arg_from_python -// -template -back_reference_arg_from_python::back_reference_arg_from_python(PyObject* x) - : base(x) -{ -} - -template -inline T -back_reference_arg_from_python::operator()(PyObject* x) -{ - return T(x, base::operator()(x)); -} - -}}} // namespace boost::python::converter - -#endif // ARG_FROM_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp deleted file mode 100755 index 3d62eccd..00000000 --- a/include/boost/python/converter/arg_to_python.hpp +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARG_TO_PYTHON_DWA200265_HPP -# define ARG_TO_PYTHON_DWA200265_HPP - -# include -# include -# include - -# include -# include -# include -# include -// Bring in specializations -# include - -# include - -# include - -# include -# include -# include -# include - -# include -# include -# include - - -# include - -namespace boost { namespace python { namespace converter { - -template struct is_object_manager; - -namespace detail -{ - template - struct function_arg_to_python : handle<> - { - function_arg_to_python(T const& x); - }; - - template - struct reference_arg_to_python : handle<> - { - reference_arg_to_python(T& x); - private: - static PyObject* get_object(T& x); - }; - - template - struct shared_ptr_arg_to_python : handle<> - { - shared_ptr_arg_to_python(T const& x); - private: - static PyObject* get_object(T& x); - }; - - template - struct value_arg_to_python : arg_to_python_base - { - // Throw an exception if the conversion can't succeed - value_arg_to_python(T const&); - }; - - template - struct pointer_deep_arg_to_python : arg_to_python_base - { - // Throw an exception if the conversion can't succeed - pointer_deep_arg_to_python(Ptr); - }; - - template - struct pointer_shallow_arg_to_python : handle<> - { - // Throw an exception if the conversion can't succeed - pointer_shallow_arg_to_python(Ptr); - private: - static PyObject* get_object(Ptr p); - }; - - // Convert types that manage a Python object to_python - template - struct object_manager_arg_to_python - { - object_manager_arg_to_python(T const& x) : m_src(x) {} - - PyObject* get() const - { - return python::upcast(get_managed_object(m_src, tag)); - } - - private: - T const& m_src; - }; - - template - struct select_arg_to_python - { - typedef typename unwrap_reference::type unwrapped_referent; - typedef typename unwrap_pointer::type unwrapped_ptr; - - typedef typename mpl::if_< - // Special handling for char const[N]; interpret them as char - // const* for the sake of conversion - python::detail::is_string_literal - , arg_to_python - - , typename mpl::if_< - python::detail::value_is_shared_ptr - , shared_ptr_arg_to_python - - , typename mpl::if_< - mpl::or_< - is_function - , python::detail::is_pointer_to_function - , is_member_function_pointer - > - , function_arg_to_python - - , typename mpl::if_< - is_object_manager - , object_manager_arg_to_python - - , typename mpl::if_< - is_pointer - , pointer_deep_arg_to_python - - , typename mpl::if_< - is_pointer_wrapper - , pointer_shallow_arg_to_python - - , typename mpl::if_< - is_reference_wrapper - , reference_arg_to_python - , value_arg_to_python - >::type - >::type - >::type - >::type - >::type - >::type - >::type - - type; - }; -} - -template -struct arg_to_python - : detail::select_arg_to_python::type -{ - typedef typename detail::select_arg_to_python::type base; - public: // member functions - // Throw an exception if the conversion can't succeed - arg_to_python(T const& x); -}; - -// -// implementations -// -namespace detail -{ - // reject_raw_object_ptr -- cause a compile-time error if the user - // should pass a raw Python object pointer - using python::detail::yes_convertible; - using python::detail::no_convertible; - using python::detail::unspecialized; - - template struct cannot_convert_raw_PyObject; - - template - struct reject_raw_object_helper - { - static void error(Convertibility) - { - cannot_convert_raw_PyObject::to_python_use_handle_instead(); - } - static void error(...) {} - }; - - template - inline void reject_raw_object_ptr(T*) - { - reject_raw_object_helper::error( - python::detail::convertible::check((T*)0)); - - typedef typename remove_cv::type value_type; - - reject_raw_object_helper::error( - python::detail::convertible::check( - (base_type_traits*)0 - )); - } - // --------- - - template - inline function_arg_to_python::function_arg_to_python(T const& x) - : handle<>(python::objects::make_function_handle(x)) - { - } - - template - inline value_arg_to_python::value_arg_to_python(T const& x) - : arg_to_python_base(&x, registered::converters) - { - } - - template - inline pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr x) - : arg_to_python_base(x, registered_pointee::converters) - { - detail::reject_raw_object_ptr((Ptr)0); - } - - template - inline PyObject* reference_arg_to_python::get_object(T& x) - { - to_python_indirect convert; - return convert(x); - } - - template - inline reference_arg_to_python::reference_arg_to_python(T& x) - : handle<>(reference_arg_to_python::get_object(x)) - { - } - - template - inline shared_ptr_arg_to_python::shared_ptr_arg_to_python(T const& x) - : handle<>(shared_ptr_to_python(x)) - { - } - - template - inline pointer_shallow_arg_to_python::pointer_shallow_arg_to_python(Ptr x) - : handle<>(pointer_shallow_arg_to_python::get_object(x)) - { - detail::reject_raw_object_ptr((Ptr)0); - } - - template - inline PyObject* pointer_shallow_arg_to_python::get_object(Ptr x) - { - to_python_indirect convert; - return convert(x); - } -} - -template -inline arg_to_python::arg_to_python(T const& x) - : base(x) -{} - -}}} // namespace boost::python::converter - -#endif // ARG_TO_PYTHON_DWA200265_HPP diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp deleted file mode 100755 index 850da036..00000000 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARG_TO_PYTHON_BASE_DWA200237_HPP -# define ARG_TO_PYTHON_BASE_DWA200237_HPP -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -namespace detail -{ - struct BOOST_PYTHON_DECL arg_to_python_base -# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179 - : handle<> -# endif - { - arg_to_python_base(void const volatile* source, registration const&); -# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102179 - PyObject* get() const { return m_ptr.get(); } - PyObject* release() { return m_ptr.release(); } - private: - handle<> m_ptr; -# endif - }; -} - -}}} // namespace boost::python::converter - -#endif // ARG_TO_PYTHON_BASE_DWA200237_HPP diff --git a/include/boost/python/converter/as_to_python_function.hpp b/include/boost/python/converter/as_to_python_function.hpp deleted file mode 100644 index 3c2f97e5..00000000 --- a/include/boost/python/converter/as_to_python_function.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef AS_TO_PYTHON_FUNCTION_DWA2002121_HPP -# define AS_TO_PYTHON_FUNCTION_DWA2002121_HPP -# include - -namespace boost { namespace python { namespace converter { - -// Given a typesafe to_python conversion function, produces a -// to_python_function_t which can be registered in the usual way. -template -struct as_to_python_function -{ - // Assertion functions used to prevent wrapping of converters - // which take non-const reference parameters. The T* argument in - // the first overload ensures it isn't used in case T is a - // reference. - template - static int convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0); - template - static int convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...); - - static PyObject* convert(void const* x) - { - BOOST_STATIC_ASSERT( - sizeof( - convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L)) - == sizeof(int)); - - // Yes, the const_cast below opens a hole in const-correctness, - // but it's needed to convert auto_ptr to python. - // - // How big a hole is it? It allows ToPython::convert() to be - // a function which modifies its argument. The upshot is that - // client converters applied to const objects may invoke - // undefined behavior. The damage, however, is limited by the - // use of the assertion function. Thus, the only way this can - // modify its argument is if T is an auto_ptr-like type. There - // is still a const-correctness hole w.r.t. auto_ptr const, - // but c'est la vie. - return ToPython::convert(*const_cast(static_cast(x))); - } -}; - -}}} // namespace boost::python::converter - -#endif // AS_TO_PYTHON_FUNCTION_DWA2002121_HPP diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp deleted file mode 100644 index 9772079c..00000000 --- a/include/boost/python/converter/builtin_converters.hpp +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP -# define BUILTIN_CONVERTERS_DWA2002124_HPP -# include -# include -# include -# include -# include -# include - -// Since all we can use to decide how to convert an object to_python -// is its C++ type, there can be only one such converter for each -// type. Therefore, for built-in conversions we can bypass registry -// lookups using explicit specializations of arg_to_python and -// result_to_python. - -namespace boost { namespace python { - -namespace converter -{ - template struct arg_to_python; - BOOST_PYTHON_DECL PyObject* do_return_to_python(char); - BOOST_PYTHON_DECL PyObject* do_return_to_python(char const*); - BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject*); - BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject*); -} - -// Provide specializations of to_python_value -template struct to_python_value; - -namespace detail -{ - // Since there's no registry lookup, always report the existence of - // a converter. - struct builtin_to_python - { - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = false); - }; -} - -// Use expr to create the PyObject corresponding to x -# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - inline PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - inline PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; - -# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \ - namespace converter \ - { \ - template <> struct arg_to_python< T > \ - : handle<> \ - { \ - arg_to_python(T const& x) \ - : python::handle<>(expr) {} \ - }; \ - } - -// Specialize argument and return value converters for T using expr -# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ - BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \ - BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr) - -// Specialize converters for signed and unsigned T to Python Int -# define BOOST_PYTHON_TO_INT(T) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE( \ - unsigned T \ - , static_cast(x) > static_cast( \ - std::numeric_limits::max()) \ - ? PyLong_FromUnsignedLong(x) \ - : PyInt_FromLong(x)) - -// Bool is not signed. -BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x)) - -// note: handles signed char and unsigned char, but not char (see below) -BOOST_PYTHON_TO_INT(char) - -BOOST_PYTHON_TO_INT(short) -BOOST_PYTHON_TO_INT(int) -BOOST_PYTHON_TO_INT(long) - -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG -BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, PyLong_FromLongLong(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong(x)) -# endif - -# undef BOOST_TO_PYTHON_INT - -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromStringAndSize(x.c_str(),x.size())) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) -BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) - -namespace converter -{ - - void initialize_builtin_converters(); - -} - -}} // namespace boost::python::converter - -#endif // BUILTIN_CONVERTERS_DWA2002124_HPP diff --git a/include/boost/python/converter/constructor_function.hpp b/include/boost/python/converter/constructor_function.hpp deleted file mode 100644 index f3c49bd4..00000000 --- a/include/boost/python/converter/constructor_function.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CONSTRUCTOR_FUNCTION_DWA200278_HPP -# define CONSTRUCTOR_FUNCTION_DWA200278_HPP - -namespace boost { namespace python { namespace converter { - -// Declares the type of functions used to construct C++ objects for -// rvalue from_python conversions. -struct rvalue_from_python_stage1_data; -typedef void (*constructor_function)(PyObject* source, rvalue_from_python_stage1_data*); - -}}} // namespace boost::python::converter - -#endif // CONSTRUCTOR_FUNCTION_DWA200278_HPP diff --git a/include/boost/python/converter/convertible_function.hpp b/include/boost/python/converter/convertible_function.hpp deleted file mode 100644 index 98db1cfb..00000000 --- a/include/boost/python/converter/convertible_function.hpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CONVERTIBLE_FUNCTION_DWA200278_HPP -# define CONVERTIBLE_FUNCTION_DWA200278_HPP - -namespace boost { namespace python { namespace converter { - -typedef void* (*convertible_function)(PyObject*); - -}}} // namespace boost::python::converter - -#endif // CONVERTIBLE_FUNCTION_DWA200278_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp deleted file mode 100644 index 32a7431e..00000000 --- a/include/boost/python/converter/from_python.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FIND_FROM_PYTHON_DWA2002223_HPP -# define FIND_FROM_PYTHON_DWA2002223_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - - -BOOST_PYTHON_DECL void* get_lvalue_from_python( - PyObject* source, registration const&); - -BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python( - PyObject* source, registration const&); - -BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( - PyObject* source, registration const&); - -BOOST_PYTHON_DECL void* rvalue_from_python_stage2( - PyObject* source, rvalue_from_python_stage1_data&, registration const&); - -BOOST_PYTHON_DECL void* rvalue_result_from_python( - PyObject*, rvalue_from_python_stage1_data&); - -BOOST_PYTHON_DECL void* reference_result_from_python(PyObject*, registration const&); -BOOST_PYTHON_DECL void* pointer_result_from_python(PyObject*, registration const&); - -BOOST_PYTHON_DECL void void_result_from_python(PyObject*); - -BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject*, registration const&); -BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject*, registration const&); - -}}} // namespace boost::python::converter - -#endif // FIND_FROM_PYTHON_DWA2002223_HPP diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp deleted file mode 100644 index fd588f6b..00000000 --- a/include/boost/python/converter/implicit.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef IMPLICIT_DWA2002326_HPP -# define IMPLICIT_DWA2002326_HPP - -# include -# include -# include - -# include - -namespace boost { namespace python { namespace converter { - -template -struct implicit -{ - static void* convertible(PyObject* obj) - { - // Find a converter which can produce a Source instance from - // obj. The user has told us that Source can be converted to - // Target, and instantiating construct() below, ensures that - // at compile-time. - return implicit_rvalue_convertible_from_python(obj, registered::converters) - ? obj : 0; - } - - static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) - { - void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; - - new (storage) Target(extract(obj)()); - - // record successful construction - data->convertible = storage; - } -}; - -}}} // namespace boost::python::converter - -#endif // IMPLICIT_DWA2002326_HPP diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp deleted file mode 100644 index dfda753d..00000000 --- a/include/boost/python/converter/obj_mgr_arg_from_python.hpp +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP -# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP - -# include -# include -# include -# include -# include -# include -# include - -// -// arg_from_python converters for Python type wrappers, to be used as -// base classes for specializations. -// -namespace boost { namespace python { namespace converter { - -template -struct object_manager_value_arg_from_python -{ - typedef T result_type; - - object_manager_value_arg_from_python(PyObject*); - bool convertible() const; - T operator()(PyObject*) const; - private: - PyObject* m_source; -}; - -// Used for converting reference-to-object-manager arguments from -// python. The process used here is a little bit odd. Upon -// construction, we build the object manager object in the m_result -// object, *forcing* it to accept the source Python object by casting -// its pointer to detail::borrowed_reference. This is supposed to -// bypass any type checking of the source object. The convertible -// check then extracts the owned object and checks it. If the check -// fails, nothing else in the program ever gets to touch this strange -// "forced" object. -template -struct object_manager_ref_arg_from_python -{ - typedef Ref result_type; - - object_manager_ref_arg_from_python(PyObject*); - bool convertible() const; - Ref operator()(PyObject*) const; - ~object_manager_ref_arg_from_python(); - private: - typename python::detail::referent_storage::type m_result; -}; - -// -// implementations -// - -template -inline object_manager_value_arg_from_python::object_manager_value_arg_from_python(PyObject* x) - : m_source(x) -{ -} - -template -inline bool object_manager_value_arg_from_python::convertible() const -{ - return object_manager_traits::check(m_source); -} - -template -inline T object_manager_value_arg_from_python::operator()(PyObject* x) const -{ - return T(python::detail::borrowed_reference(x)); -} - -template -inline object_manager_ref_arg_from_python::object_manager_ref_arg_from_python(PyObject* x) -{ -# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 - // needed for warning suppression - python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x); - python::detail::construct_referent(&m_result.bytes, x_); -# else - python::detail::construct_referent(&m_result.bytes, (python::detail::borrowed_reference)x); -# endif -} - -template -inline object_manager_ref_arg_from_python::~object_manager_ref_arg_from_python() -{ - python::detail::destroy_referent(this->m_result.bytes); -} - -namespace detail -{ - template - inline bool object_manager_ref_check(T const& x) - { - return object_manager_traits::check(get_managed_object(x, tag)); - } -} - -template -inline bool object_manager_ref_arg_from_python::convertible() const -{ - return detail::object_manager_ref_check( - python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0)); -} - -template -inline Ref object_manager_ref_arg_from_python::operator()(PyObject*) const -{ - return python::detail::void_ptr_to_reference( - this->m_result.bytes, (Ref(*)())0); -} - -}}} // namespace boost::python::converter - -#endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp deleted file mode 100755 index 7c8c9084..00000000 --- a/include/boost/python/converter/object_manager.hpp +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_MANAGER_DWA2002614_HPP -# define OBJECT_MANAGER_DWA2002614_HPP - -# include -# include -# include -# include -# include -# include -# include - -// Facilities for dealing with types which always manage Python -// objects. Some examples are object, list, str, et. al. Different -// to_python/from_python conversion rules apply here because in -// contrast to other types which are typically embedded inside a -// Python object, these are wrapped around a Python object. For most -// object managers T, a C++ non-const T reference argument does not -// imply the existence of a T lvalue embedded in the corresponding -// Python argument, since mutating member functions on T actually only -// modify the held Python object. -// -// handle is an object manager, though strictly speaking it should -// not be. In other words, even though mutating member functions of -// hanlde actually modify the handle and not the T object, -// handle& arguments of wrapped functions will bind to "rvalues" -// wrapping the actual Python argument, just as with other object -// manager classes. Making an exception for handle is simply not -// worth the trouble. -// -// borrowed cv* is an object manager so that we can use the general -// to_python mechanisms to convert raw Python object pointers to -// python, without the usual semantic problems of using raw pointers. - - -// Object Manager Concept requirements: -// -// T is an Object Manager -// p is a PyObject* -// x is a T -// -// * object_manager_traits::is_specialized == true -// -// * T(detail::borrowed_reference(p)) -// Manages p without checking its type -// -// * get_managed_object(x, boost::python::tag) -// Convertible to PyObject* -// -// Additional requirements if T can be converted from_python: -// -// * T(object_manager_traits::adopt(p)) -// steals a reference to p, or throws a TypeError exception if -// p doesn't have an appropriate type. May assume p is non-null -// -// * X::check(p) -// convertible to bool. True iff T(X::construct(p)) will not -// throw. - -// Forward declarations -// -namespace boost { namespace python -{ - namespace api - { - class object; - } -}} - -namespace boost { namespace python { namespace converter { - - -// Specializations for handle -template -struct handle_object_manager_traits - : pyobject_traits -{ - private: - typedef pyobject_traits base; - - public: - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - - // Initialize with a null_ok pointer for efficiency, bypassing the - // null check since the source is always non-null. - static null_ok* adopt(PyObject* p) - { - return python::allow_null(base::checked_downcast(p)); - } -}; - -template -struct default_object_manager_traits -{ - BOOST_STATIC_CONSTANT( - bool, is_specialized = python::detail::is_borrowed_ptr::value - ); -}; - -template -struct object_manager_traits - : mpl::if_c< - is_handle::value - , handle_object_manager_traits - , default_object_manager_traits - >::type -{ -}; - -// -// Traits for detecting whether a type is an object manager or a -// (cv-qualified) reference to an object manager. -// - -template -struct is_object_manager - : mpl::bool_::is_specialized> -{ -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_reference_to_object_manager - : mpl::false_ -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; - -template -struct is_reference_to_object_manager - : is_object_manager -{ -}; -# else - -namespace detail -{ - typedef char (&yes_reference_to_object_manager)[1]; - typedef char (&no_reference_to_object_manager)[2]; - - // A number of nastinesses go on here in order to work around MSVC6 - // bugs. - template - struct is_object_manager_help - { - typedef typename mpl::if_< - is_object_manager - , yes_reference_to_object_manager - , no_reference_to_object_manager - >::type type; - - // If we just use the type instead of the result of calling this - // function, VC6 will ICE. - static type call(); - }; - - // A set of overloads for each cv-qualification. The same argument - // is passed twice: the first one is used to unwind the cv*, and the - // second one is used to avoid relying on partial ordering for - // overload resolution. - template - typename is_object_manager_help - is_object_manager_helper(U*, void*); - - template - typename is_object_manager_help - is_object_manager_helper(U const*, void const*); - - template - typename is_object_manager_help - is_object_manager_helper(U volatile*, void volatile*); - - template - typename is_object_manager_help - is_object_manager_helper(U const volatile*, void const volatile*); - - template - struct is_reference_to_object_manager_nonref - : mpl::false_ - { - }; - - template - struct is_reference_to_object_manager_ref - { - static T sample_object; - BOOST_STATIC_CONSTANT( - bool, value - = (sizeof(is_object_manager_helper(&sample_object, &sample_object).call()) - == sizeof(detail::yes_reference_to_object_manager) - ) - ); - typedef mpl::bool_ type; - }; -} - -template -struct is_reference_to_object_manager - : mpl::if_< - is_reference - , detail::is_reference_to_object_manager_ref - , detail::is_reference_to_object_manager_nonref - >::type -{ -}; -# endif - -}}} // namespace boost::python::converter - -#endif // OBJECT_MANAGER_DWA2002614_HPP diff --git a/include/boost/python/converter/pointer_type_id.hpp b/include/boost/python/converter/pointer_type_id.hpp deleted file mode 100644 index 01e55977..00000000 --- a/include/boost/python/converter/pointer_type_id.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef POINTER_TYPE_ID_DWA2002222_HPP -# define POINTER_TYPE_ID_DWA2002222_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - template - struct pointer_typeid_select - { - template - static inline type_info execute(T*(*)() = 0) - { - return type_id(); - } - }; - - template <> - struct pointer_typeid_select - { - template - static inline type_info execute(T* const volatile&(*)() = 0) - { - return type_id(); - } - - template - static inline type_info execute(T*volatile&(*)() = 0) - { - return type_id(); - } - - template - static inline type_info execute(T*const&(*)() = 0) - { - return type_id(); - } - - template - static inline type_info execute(T*&(*)() = 0) - { - return type_id(); - } - }; -} - -// Usage: pointer_type_id() -// -// Returns a type_info associated with the type pointed -// to by T, which may be a pointer or a reference to a pointer. -template -type_info pointer_type_id(T(*)() = 0) -{ - return detail::pointer_typeid_select< - is_reference::value - >::execute((T(*)())0); -} - -}}} // namespace boost::python::converter - -#endif // POINTER_TYPE_ID_DWA2002222_HPP diff --git a/include/boost/python/converter/pyobject_traits.hpp b/include/boost/python/converter/pyobject_traits.hpp deleted file mode 100644 index f975360c..00000000 --- a/include/boost/python/converter/pyobject_traits.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PYOBJECT_TRAITS_DWA2002720_HPP -# define PYOBJECT_TRAITS_DWA2002720_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -template struct pyobject_traits; - -template <> -struct pyobject_traits -{ - // All objects are convertible to PyObject - static bool check(PyObject*) { return true; } - static PyObject* checked_downcast(PyObject* x) { return x; } -}; - -// -// Specializations -// - -# define BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(T) \ - template <> struct pyobject_traits \ - : pyobject_type {} - -// This is not an exhaustive list; should be expanded. -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict); -BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple); - -}}} // namespace boost::python::converter - -#endif // PYOBJECT_TRAITS_DWA2002720_HPP diff --git a/include/boost/python/converter/pyobject_type.hpp b/include/boost/python/converter/pyobject_type.hpp deleted file mode 100644 index 59ff7244..00000000 --- a/include/boost/python/converter/pyobject_type.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PYOBJECT_TYPE_DWA2002720_HPP -# define PYOBJECT_TYPE_DWA2002720_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*); - -// Used as a base class for specializations which need to provide -// Python type checking capability. -template -struct pyobject_type -{ - static bool check(PyObject* x) - { - return ::PyObject_IsInstance(x, (PyObject*)pytype); - } - - static Object* checked_downcast(PyObject* x) - { - return python::downcast( - (checked_downcast_impl)(x, pytype) - ); - } -}; - -}}} // namespace boost::python::converter - -#endif // PYOBJECT_TYPE_DWA2002720_HPP diff --git a/include/boost/python/converter/pytype_arg_from_python.hpp b/include/boost/python/converter/pytype_arg_from_python.hpp deleted file mode 100644 index ade4fd66..00000000 --- a/include/boost/python/converter/pytype_arg_from_python.hpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP -# define PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP - -# include - -// -// arg_from_python converters for Python type wrappers, to be used as -// base classes for specializations. -// -namespace boost { namespace python { namespace converter { - -template -struct pytype_arg_from_python -{ - pytype_arg_from_python(PyObject*); - bool convertible() const; - private: - PyObject* m_src; -}; - -// rvalue converter base -template -struct pytype_wrapper_value_arg_from_python - : pytype_arg_from_python -{ - typedef Wrapper result_type; - - pytype_wrapper_value_arg_from_python(PyObject*); - Wrapper operator()(PyObject*) const; -}; - -// Special case for Wrapper& - must store an lvalue internally. This -// OK because the entire state of the object is actually in the Python -// object. -template -struct pytype_wrapper_ref_arg_from_python - : pytype_arg_from_python -{ - typedef Wrapper& result_type; - - pytype_wrapper_ref_arg_from_python(PyObject*); - Wrapper& operator()(PyObject*) const; - private: - mutable Wrapper m_result; -}; - -// -// implementations -// - -template -inline pytype_arg_from_python::pytype_arg_from_python(PyObject* x) - : m_src(x) -{ -} - -template -inline bool pytype_arg_from_python::convertible() const -{ - return PyObject_IsInstance(m_src, (PyObject*)python_type); -} - -template -pytype_wrapper_value_arg_from_python::pytype_wrapper_value_arg_from_python( - PyObject* p) - : pytype_arg_from_python(p) -{ -} - -template -Wrapper pytype_wrapper_value_arg_from_python::operator()( - PyObject* x) const -{ - return Wrapper(python::detail::borrowed_reference(x)); -} - -template -pytype_wrapper_ref_arg_from_python::pytype_wrapper_ref_arg_from_python( - PyObject* p) - : pytype_arg_from_python(p) - , m_result(python::detail::borrowed_reference(p)) -{ -} - -template -Wrapper& pytype_wrapper_ref_arg_from_python::operator()( - PyObject* x) const -{ - return m_result; -} - -}}} // namespace boost::python::converter - -#endif // PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP diff --git a/include/boost/python/converter/pytype_object_mgr_traits.hpp b/include/boost/python/converter/pytype_object_mgr_traits.hpp deleted file mode 100644 index 94cbae64..00000000 --- a/include/boost/python/converter/pytype_object_mgr_traits.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP -# define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// Provide a forward declaration as a convenience for clients, who all -// need it. -template struct object_manager_traits; - -// Derive specializations of object_manager_traits from this class -// when T is an object manager for a particular Python type hierarchy. -// -template -struct pytype_object_manager_traits - : pyobject_type // provides check() -{ - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - static inline python::detail::new_reference adopt(PyObject*); -}; - -// -// implementations -// -template -inline python::detail::new_reference pytype_object_manager_traits::adopt(PyObject* x) -{ - return python::detail::new_reference(python::pytype_check(pytype, x)); -} - -}}} // namespace boost::python::converter - -#endif // PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP diff --git a/include/boost/python/converter/registered.hpp b/include/boost/python/converter/registered.hpp deleted file mode 100644 index 2d3daa99..00000000 --- a/include/boost/python/converter/registered.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REGISTERED_DWA2002710_HPP -# define REGISTERED_DWA2002710_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -namespace detail -{ - template - struct registered_base - { - static registration const& converters; - }; -} - -template -struct registered - : detail::registered_base< - typename add_reference< - typename add_cv::type - >::type - > -{ -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -// collapses a few more types to the same static instance -template -struct registered : registered {}; -# endif - -// -// implementations -// -namespace detail -{ - template - registration const& registered_base::converters - = registry::lookup(type_id()); -} -}}} // namespace boost::python::converter - -#endif // REGISTERED_DWA2002710_HPP diff --git a/include/boost/python/converter/registered_pointee.hpp b/include/boost/python/converter/registered_pointee.hpp deleted file mode 100644 index 861cf724..00000000 --- a/include/boost/python/converter/registered_pointee.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REGISTERED_POINTEE_DWA2002710_HPP -# define REGISTERED_POINTEE_DWA2002710_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct registered_pointee - : registered< - typename remove_pointer< - typename remove_cv< - typename remove_reference::type - >::type - >::type - > -{ -}; -# else -namespace detail -{ - template - struct registered_pointee_base - { - static registration const& converters; - }; -} - -template -struct registered_pointee - : detail::registered_pointee_base< - typename add_reference< - typename add_cv::type - >::type - > -{ -}; - -// -// implementations -// -namespace detail -{ - template - registration const& registered_pointee_base::converters - = registry::lookup(pointer_type_id()); -} - -# endif -}}} // namespace boost::python::converter - -#endif // REGISTERED_POINTEE_DWA2002710_HPP diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp deleted file mode 100644 index 973e052f..00000000 --- a/include/boost/python/converter/registrations.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REGISTRATIONS_DWA2002223_HPP -# define REGISTRATIONS_DWA2002223_HPP - -# include - -# include -# include -# include - -# include - -# include - -namespace boost { namespace python { namespace converter { - -struct lvalue_from_python_chain -{ - convertible_function convert; - lvalue_from_python_chain* next; -}; - -struct rvalue_from_python_chain -{ - convertible_function convertible; - constructor_function construct; - rvalue_from_python_chain* next; -}; - -struct BOOST_PYTHON_DECL registration -{ - public: // member functions - explicit registration(type_info); - - // Convert the appropriately-typed data to Python - PyObject* to_python(void const volatile*) const; - - // Return the class object, or raise an appropriate Python - // exception if no class has been registered. - PyTypeObject* get_class_object() const; - - public: // data members. So sue me. - const python::type_info target_type; - - // The chain of eligible from_python converters when an lvalue is required - lvalue_from_python_chain* lvalue_chain; - - // The chain of eligible from_python converters when an rvalue is acceptable - rvalue_from_python_chain* rvalue_chain; - - // The class object associated with this type - PyTypeObject* m_class_object; - - // The unique to_python converter for the associated C++ type. - to_python_function_t m_to_python; - -# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - private: - void operator=(registration); // This is not defined, and just keeps MWCW happy. -# endif -}; - -// -// implementations -// -inline registration::registration(type_info target_type) - : target_type(target_type) - , lvalue_chain(0) - , rvalue_chain(0) - , m_class_object(0) - , m_to_python(0) -{} - -inline bool operator<(registration const& lhs, registration const& rhs) -{ - return lhs.target_type < rhs.target_type; -} - -}}} // namespace boost::python::converter - -#endif // REGISTRATIONS_DWA2002223_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp deleted file mode 100644 index b71c949a..00000000 --- a/include/boost/python/converter/registry.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REGISTRY_DWA20011127_HPP -# define REGISTRY_DWA20011127_HPP -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct registration; - -// This namespace acts as a sort of singleton -namespace registry -{ - // Get the registration corresponding to the type, creating it if neccessary - BOOST_PYTHON_DECL registration const& lookup(type_info); - - // Return a pointer to the corresponding registration, if one exists - BOOST_PYTHON_DECL registration const* query(type_info); - - BOOST_PYTHON_DECL void insert(to_python_function_t, type_info); - - // Insert an lvalue from_python converter - BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info); - - // Insert an rvalue from_python converter - BOOST_PYTHON_DECL void insert( - convertible_function - , constructor_function - , type_info - ); - - // Insert an rvalue from_python converter at the tail of the - // chain. Used for implicit conversions - BOOST_PYTHON_DECL void push_back( - convertible_function - , constructor_function - , type_info - ); -} - -}}} // namespace boost::python::converter - -#endif // REGISTRY_DWA20011127_HPP diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp deleted file mode 100755 index 69c7a71b..00000000 --- a/include/boost/python/converter/return_from_python.hpp +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef RETURN_FROM_PYTHON_DWA200265_HPP -# define RETURN_FROM_PYTHON_DWA200265_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -template struct is_object_manager; - -namespace detail -{ - template - struct return_pointer_from_python - { - typedef T result_type; - T operator()(PyObject*) const; - }; - - template - struct return_reference_from_python - { - typedef T result_type; - T operator()(PyObject*) const; - }; - - template - struct return_rvalue_from_python - { - typedef T result_type; - - return_rvalue_from_python(); - result_type operator()(PyObject*); - private: - rvalue_from_python_data m_data; - }; - - template - struct return_object_manager_from_python - { - typedef T result_type; - result_type operator()(PyObject*) const; - }; - - template - struct select_return_from_python - { - BOOST_STATIC_CONSTANT( - bool, obj_mgr = is_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ref = is_reference::value); - - typedef typename mpl::if_c< - obj_mgr - , return_object_manager_from_python - , typename mpl::if_c< - ptr - , return_pointer_from_python - , typename mpl::if_c< - ref - , return_reference_from_python - , return_rvalue_from_python - >::type - >::type - >::type type; - }; -} - -template -struct return_from_python - : detail::select_return_from_python::type -{ -}; - -// Specialization as a convenience for call and call_method -template <> -struct return_from_python -{ - typedef python::detail::returnable::type result_type; - - result_type operator()(PyObject* x) const - { - (void_result_from_python)(x); -# ifdef BOOST_NO_VOID_RETURNS - return result_type(); -# endif - } -}; - -// -// Implementations -// -namespace detail -{ - template - inline return_rvalue_from_python::return_rvalue_from_python() - : m_data( - const_cast(®istered::converters) - ) - { - } - - template - inline typename return_rvalue_from_python::result_type - return_rvalue_from_python::operator()(PyObject* obj) - { - // Take possession of the source object here. If the result is in - // fact going to be a copy of an lvalue embedded in the object, - // and we take possession inside rvalue_result_from_python, it - // will be destroyed too early. - handle<> holder(obj); - - return *(T*) - (rvalue_result_from_python)(obj, m_data.stage1); - } - - template - inline T return_reference_from_python::operator()(PyObject* obj) const - { - return python::detail::void_ptr_to_reference( - (reference_result_from_python)(obj, registered::converters) - , (T(*)())0); - } - - template - inline T return_pointer_from_python::operator()(PyObject* obj) const - { - return T( - (pointer_result_from_python)(obj, registered_pointee::converters) - ); - } - - template - inline T return_object_manager_from_python::operator()(PyObject* obj) const - { - return T( - object_manager_traits::adopt(expect_non_null(obj)) - ); - } -} - -}}} // namespace boost::python::converter - -#endif // RETURN_FROM_PYTHON_DWA200265_HPP diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp deleted file mode 100644 index 91b5afd8..00000000 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP -# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP - -# include -# include -# include -# include -# include -# include -# include - -// Data management for potential rvalue conversions from Python to C++ -// types. When a client requests a conversion to T* or T&, we -// generally require that an object of type T exists in the source -// Python object, and the code here does not apply**. This implements -// conversions which may create new temporaries of type T. The classic -// example is a conversion which converts a Python tuple to a -// std::vector. Since no std::vector lvalue exists in the Python -// object -- it must be created "on-the-fly" by the converter, and -// which must manage the lifetime of the created object. -// -// Note that the client is not precluded from using a registered -// lvalue conversion to T in this case. In other words, we will -// happily accept a Python object which /does/ contain a std::vector -// lvalue, provided an appropriate converter is registered. So, while -// this is an rvalue conversion from the client's point-of-view, the -// converter registry may serve up lvalue or rvalue conversions for -// the target type. -// -// ** C++ argument from_python conversions to T const& are an -// exception to the rule for references: since in C++, const -// references can bind to temporary rvalues, we allow rvalue -// converters to be chosen when the target type is T const& for some -// T. -namespace boost { namespace python { namespace converter { - -// Conversions begin by filling in and returning a copy of this -// structure. The process looks up a converter in the rvalue converter -// registry for the target type. It calls the convertible() function -// of each registered converter, passing the source PyObject* as an -// argument, until a non-null result is returned. This result goes in -// the convertible field, and the converter's construct() function is -// stored in the construct field. -// -// If no appropriate converter is found, conversion fails and the -// convertible field is null. When used in argument conversion for -// wrapped C++ functions, it causes overload resolution to reject the -// current function but not to fail completely. If an exception is -// thrown, overload resolution stops and the exception propagates back -// through the caller. -// -// If an lvalue converter is matched, its convertible() function is -// expected to return a pointer to the stored T object; its -// construct() function will be NULL. The convertible() function of -// rvalue converters may return any non-singular pointer; the actual -// target object will only be available once the converter's -// construct() function is called. -struct rvalue_from_python_stage1_data -{ - void* convertible; - constructor_function construct; -}; - -// Augments rvalue_from_python_stage1_data by adding storage for -// constructing an object of remove_reference::type. The -// construct() function of rvalue converters (stored in m_construct -// above) will cast the rvalue_from_python_stage1_data to an -// appropriate instantiation of this template in order to access that -// storage. -template -struct rvalue_from_python_storage -{ - rvalue_from_python_stage1_data stage1; - - // Storage for the result, in case an rvalue must be constructed - typename python::detail::referent_storage< - typename add_reference::type - >::type storage; -}; - -// Augments rvalue_from_python_storage with a destructor. If -// stage1.convertible == storage.bytes, it indicates that an object of -// remove_reference::type has been constructed in storage and -// should will be destroyed in ~rvalue_from_python_data(). It is -// crucial that successful rvalue conversions establish this equality -// and that unsuccessful ones do not. -template -struct rvalue_from_python_data : rvalue_from_python_storage -{ -# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ - && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ - && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ - && !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */ - // This must always be a POD struct with m_data its first member. - BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage,stage1) == 0); -# endif - - // The usual constructor - rvalue_from_python_data(rvalue_from_python_stage1_data const&); - - // This constructor just sets m_convertible -- used by - // implicitly_convertible<> to perform the final step of the - // conversion, where the construct() function is already known. - rvalue_from_python_data(void* convertible); - - // Destroys any object constructed in the storage. - ~rvalue_from_python_data(); - private: - typedef typename add_reference::type>::type ref_type; -}; - -// -// Implementataions -// -template -inline rvalue_from_python_data::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1) -{ - this->stage1 = stage1; -} - -template -inline rvalue_from_python_data::rvalue_from_python_data(void* convertible) -{ - this->stage1.convertible = convertible; -} - -template -inline rvalue_from_python_data::~rvalue_from_python_data() -{ - if (this->stage1.convertible == this->storage.bytes) - python::detail::destroy_referent(this->storage.bytes); -} - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/converter/shared_ptr_deleter.hpp b/include/boost/python/converter/shared_ptr_deleter.hpp deleted file mode 100644 index f2ebfc40..00000000 --- a/include/boost/python/converter/shared_ptr_deleter.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SHARED_PTR_DELETER_DWA2002121_HPP -# define SHARED_PTR_DELETER_DWA2002121_HPP - -namespace boost { namespace python { namespace converter { - -struct BOOST_PYTHON_DECL shared_ptr_deleter -{ - shared_ptr_deleter(handle<> owner); - ~shared_ptr_deleter(); - - void operator()(void const*); - - handle<> owner; -}; - -}}} // namespace boost::python::converter - -#endif // SHARED_PTR_DELETER_DWA2002121_HPP diff --git a/include/boost/python/converter/shared_ptr_from_python.hpp b/include/boost/python/converter/shared_ptr_from_python.hpp deleted file mode 100644 index 1535740a..00000000 --- a/include/boost/python/converter/shared_ptr_from_python.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SHARED_PTR_FROM_PYTHON_DWA20021130_HPP -# define SHARED_PTR_FROM_PYTHON_DWA20021130_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -template -struct shared_ptr_from_python -{ - shared_ptr_from_python() - { - converter::registry::insert(&convertible, &construct, type_id >()); - } - - static shared_ptr_from_python const registration; - private: - static void* convertible(PyObject* p) - { - return p == Py_None - ? p - : converter::get_lvalue_from_python(p, registered::converters) - ; - } - - static void construct(PyObject* source, rvalue_from_python_stage1_data* data) - { - void* const storage = ((converter::rvalue_from_python_storage >*)data)->storage.bytes; - // Deal with the "None" case. - if (data->convertible == source) - new (storage) shared_ptr(); - else - new (storage) shared_ptr( - static_cast(data->convertible), - shared_ptr_deleter(handle<>(borrowed(source))) - ); - - data->convertible = storage; - } -}; - -template -shared_ptr_from_python const shared_ptr_from_python::registration; - -}}} // namespace boost::python::converter - -#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP diff --git a/include/boost/python/converter/shared_ptr_to_python.hpp b/include/boost/python/converter/shared_ptr_to_python.hpp deleted file mode 100644 index 0002fa91..00000000 --- a/include/boost/python/converter/shared_ptr_to_python.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SHARED_PTR_TO_PYTHON_DWA2003224_HPP -# define SHARED_PTR_TO_PYTHON_DWA2003224_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -template -PyObject* shared_ptr_to_python(shared_ptr const& x) -{ - if (shared_ptr_deleter* d = boost::get_deleter(x)) - return incref(d->owner.get()); - else - return converter::registered const&>::converters.to_python(&x); -} - -}}} // namespace boost::python::converter - -#endif // SHARED_PTR_TO_PYTHON_DWA2003224_HPP diff --git a/include/boost/python/converter/to_python_function_type.hpp b/include/boost/python/converter/to_python_function_type.hpp deleted file mode 100644 index b53ff649..00000000 --- a/include/boost/python/converter/to_python_function_type.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP -# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP -# include -# include - -namespace boost { namespace python { namespace converter { - -// The type of stored function pointers which actually do conversion -// by-value. The void* points to the object to be converted, and -// type-safety is preserved through runtime registration. -typedef PyObject* (*to_python_function_t)(void const*); - -}}} // namespace boost::python::converter - -#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP diff --git a/include/boost/python/copy_const_reference.hpp b/include/boost/python/copy_const_reference.hpp deleted file mode 100644 index 8eecd2ce..00000000 --- a/include/boost/python/copy_const_reference.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef COPY_CONST_REFERENCE_DWA2002131_HPP -# define COPY_CONST_REFERENCE_DWA2002131_HPP -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct copy_const_reference_expects_a_const_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template struct to_python_value; - -struct copy_const_reference -{ - template - struct apply - { - typedef typename mpl::if_c< - detail::is_reference_to_const::value - , to_python_value - , detail::copy_const_reference_expects_a_const_reference_return_type - >::type type; - }; -}; - - -}} // namespace boost::python - -#endif // COPY_CONST_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/copy_non_const_reference.hpp b/include/boost/python/copy_non_const_reference.hpp deleted file mode 100644 index 53c576e0..00000000 --- a/include/boost/python/copy_non_const_reference.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef COPY_NON_CONST_REFERENCE_DWA2002131_HPP -# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct copy_non_const_reference_expects_a_non_const_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template struct to_python_value; - -struct copy_non_const_reference -{ - template - struct apply - { - typedef typename mpl::if_c< - boost::python::detail::is_reference_to_non_const::value - , to_python_value - , detail::copy_non_const_reference_expects_a_non_const_reference_return_type - >::type type; - }; -}; - - -}} // namespace boost::python - -#endif // COPY_NON_CONST_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp deleted file mode 100644 index 9c4574b4..00000000 --- a/include/boost/python/data_members.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DATA_MEMBERS_DWA2002328_HPP -# define DATA_MEMBERS_DWA2002328_HPP - -# include -# include -# include -# include - -# include - -# include - -# include -# include -# include - -# include -# include -# include - -# include - -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct member - { - static PyObject* get(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) - { - arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename Policies::result_converter result_converter; - typedef typename boost::add_reference::type source; - typename mpl::apply1::type cr; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (c0(PyTuple_GET_ITEM(args_, 0)))->*pm ); - - return policies.postcall(args_, result); - } - - static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) - { - // check that each of the arguments is convertible - arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - typedef typename add_const::type target1; - typedef typename add_reference::type target; - arg_from_python c1(PyTuple_GET_ITEM(args_, 1)); - - if (!c1.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - (c0(PyTuple_GET_ITEM(args_, 0))).*pm = c1(PyTuple_GET_ITEM(args_, 1)); - - return policies.postcall(args_, detail::none()); - } - }; - - // If it's a regular class type (not an object manager or other - // type for which we have to_python specializations, use - // return_internal_reference so that we can do things like - // x.y.z = 1 - // and get the right result. - template - struct default_getter_policy - { - typedef typename add_reference< - typename add_const::type - >::type t_cref; - - BOOST_STATIC_CONSTANT( - bool, by_ref = to_python_value::uses_registry - && is_reference_to_class::value); - - typedef typename mpl::if_c< - by_ref - , return_internal_reference<> - , return_value_policy - >::type type; - }; -} - -template -object make_getter(D C::*pm) -{ - typedef typename detail::default_getter_policy::type policy; - - return objects::function_object( - ::boost::bind( - &detail::member::get, pm, _1, _2 - , policy()) - , 1); - -} - -template -object make_getter(D C::*pm, Policies const& policies) -{ - return objects::function_object( - ::boost::bind( - &detail::member::get, pm, _1, _2 - , policies) - , 1); -} - -template -object make_setter(D C::*pm) -{ - return objects::function_object( - ::boost::bind( - &detail::member::set, pm, _1, _2 - , default_call_policies()) - , 2); -} - -template -object make_setter(D C::*pm, Policies const& policies) -{ - return objects::function_object( - ::boost::bind( - &detail::member::set, pm, _1, _2 - , policies) - , 2); -} - - -}} // namespace boost::python - -#endif // DATA_MEMBERS_DWA2002328_HPP diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp deleted file mode 100644 index d0db5528..00000000 --- a/include/boost/python/def.hpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DEF_DWA200292_HPP -# define DEF_DWA200292_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - namespace error - { - // Compile-time error messages - template struct multiple_functions_passed_to_def; - template <> struct multiple_functions_passed_to_def { typedef char type; }; - } - - // - // def_from_helper -- - // - // Use a def_helper to define a regular wrapped function in the current scope. - template - void def_from_helper( - char const* name, F const& fn, Helper const& helper) - { - // Must not try to use default implementations except with method definitions. - typedef typename error::multiple_functions_passed_to_def< - Helper::has_default_implementation - >::type assertion; - - detail::scope_setattr_doc( - name, boost::python::make_function( - fn - , helper.policies() - , helper.keywords()) - , helper.doc() - ); - } - - // - // These two overloads discriminate between def() as applied to - // regular functions and def() as applied to the result of - // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to - // discriminate. - // - template - void - def_maybe_overloads( - char const* name - , Fn fn - , A1 const& a1 - , ...) - { - detail::def_from_helper(name, fn, def_helper(a1)); - } - - template - void def_maybe_overloads( - char const* name - , SigT sig - , StubsT const& stubs - , detail::overloads_base const*) - { - scope current; - - detail::define_with_defaults( - name, stubs, current, detail::get_signature(sig)); - } - - template - object make_function1(T fn, ...) { return make_function(fn); } - - inline - object make_function1(object const& x, object const*) { return x; } -} - -template -void def(char const* name, Fn fn) -{ - detail::scope_setattr_doc(name, detail::make_function1(fn, &fn), 0); -} - -template -void def(char const* name, Arg1T arg1, Arg2T const& arg2) -{ - detail::def_maybe_overloads(name, arg1, arg2, &arg2); -} - -template -void def(char const* name, F f, A1 const& a1, A2 const& a2) -{ - detail::def_from_helper(name, f, detail::def_helper(a1,a2)); -} - -template -void def(char const* name, F f, A1 const& a1, A2 const& a2, A3 const& a3) -{ - detail::def_from_helper(name, f, detail::def_helper(a1,a2,a3)); -} - -}} // namespace boost::python - -#endif // DEF_DWA200292_HPP diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp deleted file mode 100644 index e796bee5..00000000 --- a/include/boost/python/default_call_policies.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP -# define DEFAULT_CALL_POLICIES_DWA2002131_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -template struct to_python_value; - -namespace detail -{ -// for "readable" error messages - template struct specify_a_return_value_policy_to_wrap_functions_returning -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -struct default_result_converter; - -struct default_call_policies -{ - // Nothing to do - static bool precall(PyObject*) - { - return true; - } - - // Pass the result through - static PyObject* postcall(PyObject*, PyObject* result) - { - return result; - } - - typedef default_result_converter result_converter; -}; - -struct default_result_converter -{ - template - struct apply - { - BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference::value || is_pointer::value); - - typedef typename mpl::if_c< - is_illegal - , detail::specify_a_return_value_policy_to_wrap_functions_returning - , boost::python::to_python_value< - typename add_reference::type>::type - > - >::type type; - }; -}; - -// Exceptions for c strings an PyObject*s -template <> -struct default_result_converter::apply -{ - typedef boost::python::to_python_value type; -}; - -template <> -struct default_result_converter::apply -{ - typedef boost::python::to_python_value type; -}; - -}} // namespace boost::python - -#endif // DEFAULT_CALL_POLICIES_DWA2002131_HPP diff --git a/include/boost/python/detail/aix_init_module.hpp b/include/boost/python/detail/aix_init_module.hpp deleted file mode 100644 index 06071c1f..00000000 --- a/include/boost/python/detail/aix_init_module.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef AIX_INIT_MODULE_DWA2002529_HPP -# define AIX_INIT_MODULE_DWA2002529_HPP -# ifdef _AIX -# include -# include -# ifdef __KCC -# include // this works around a problem in KCC 4.0f -# endif - -namespace boost { namespace python { namespace detail { - -extern "C" -{ - typedef PyObject* (*so_load_function)(char*,char*,FILE*); -} - -void aix_init_module(so_load_function, char const* name, void (*init_module)()); - -}}} // namespace boost::python::detail -# endif - -#endif // AIX_INIT_MODULE_DWA2002529_HPP diff --git a/include/boost/python/detail/api_placeholder.hpp b/include/boost/python/detail/api_placeholder.hpp deleted file mode 100644 index 38a0d029..00000000 --- a/include/boost/python/detail/api_placeholder.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BOOST_PYTHON_API_PLACE_HOLDER_HPP -#define BOOST_PYTHON_API_PLACE_HOLDER_HPP - -namespace boost { namespace python { - - inline long len(object const& obj) - { - long result = PyObject_Length(obj.ptr()); - if (PyErr_Occurred()) throw_error_already_set(); - return result; - } -}} // namespace boost::python - -#endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP diff --git a/include/boost/python/detail/borrowed_ptr.hpp b/include/boost/python/detail/borrowed_ptr.hpp deleted file mode 100755 index 6b35c862..00000000 --- a/include/boost/python/detail/borrowed_ptr.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef BORROWED_PTR_DWA20020601_HPP -# define BORROWED_PTR_DWA20020601_HPP -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -template class borrowed -{ - typedef T type; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_borrowed_ptr -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -# if !defined(__MWERKS__) || __MWERKS__ > 0x3000 -template -struct is_borrowed_ptr*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_borrowed_ptr const*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_borrowed_ptr volatile*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_borrowed_ptr const volatile*> -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; -# else -template -struct is_borrowed -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; -template -struct is_borrowed > -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; -template -struct is_borrowed_ptr - : is_borrowed::type> -{ -}; -# endif - -# else // no partial specialization - -typedef char (&yes_borrowed_ptr_t)[1]; -typedef char (&no_borrowed_ptr_t)[2]; - -no_borrowed_ptr_t is_borrowed_ptr_test(...); - -template -typename mpl::if_c< - is_pointer::value - , T - , int - >::type -is_borrowed_ptr_test1(boost::type); - -template -yes_borrowed_ptr_t is_borrowed_ptr_test(borrowed const volatile*); - -template -class is_borrowed_ptr -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_borrowed_ptr_test(is_borrowed_ptr_test1(boost::type()))) - == sizeof(detail::yes_borrowed_ptr_t))); -}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -} - -template -inline T* get_managed_object(detail::borrowed const volatile* p, tag_t) -{ - return (T*)p; -} - -}} // namespace boost::python::detail - -#endif // #ifndef BORROWED_PTR_DWA20020601_HPP diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp deleted file mode 100644 index 3477f64d..00000000 --- a/include/boost/python/detail/caller.hpp +++ /dev/null @@ -1,175 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef CALLER_DWA20021121_HPP -# define CALLER_DWA20021121_HPP - -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include -# include -# include - -# include - -namespace boost { namespace python { namespace detail { - -// This "result converter" is really just used as -// a dispatch tag to invoke(...), selecting the appropriate -// implementation -typedef int void_result_to_python; - -// A metafunction taking an iterator FunctionIter to a metafunction -// class and an iterator ArgIter to an argument, which applies the -// result of dereferencing FunctionIter to the result of dereferencing -// ArgIter -template -struct apply_iter1 - : mpl::apply1 {}; - -// Given a model of CallPolicies and a C++ result type, this -// metafunction selects the appropriate converter to use for -// converting the result to python. -template -struct select_result_converter - : mpl::if_< - is_same - , void_result_to_python - , typename mpl::apply1::type* - > -{ -}; - - -template struct caller_arity; - -# define BOOST_PYTHON_NEXT(init,name,n) \ - typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n; - -# define BOOST_PYTHON_ARG_CONVERTER(n) \ - BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \ - BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \ - typedef typename apply_iter1::type c_t##n; \ - c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \ - if (!c##n.convertible()) \ - return 0; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY + 1, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_ARG_CONVERTER -# undef BOOST_PYTHON_NEXT - -// A metafunction returning the base class used for caller. -template -struct caller_base_select -{ - enum { arity = mpl::size::value - 1 }; - typedef typename caller_arity::template impl type; -}; - -// A function object type which wraps C++ objects as Python callable -// objects. -// -// Template Arguments: -// -// F - -// the C++ `function object' that will be called. Might -// actually be any data for which an appropriate invoke_tag() can -// be generated. invoke(...) takes care of the actual invocation syntax. -// -// ConverterGenerators - -// An MPL iterator type over a sequence of metafunction classes -// that can be applied to element 1...N of Sig to produce -// argument from_python converters for the arguments -// -// CallPolicies - -// The precall, postcall, and what kind of resultconverter to -// generate for mpl::front::type -// -// Sig - -// The `intended signature' of the function. An MPL sequence -// beginning with a result type and continuing with a list of -// argument types. -template -struct caller - : caller_base_select::type -{ - typedef typename caller_base_select< - F,ConverterGenerators,CallPolicies,Sig - >::type base; - - typedef PyObject* result_type; - - caller(F f, CallPolicies p) : base(f,p) {} -}; - - -}}} // namespace boost::python::detail - -# endif // CALLER_DWA20021121_HPP - -#else - -# define N BOOST_PP_ITERATION() - -template <> -struct caller_arity -{ - template - struct impl - { - impl(F f, Policies p) : m_data(f,p) {} - - PyObject* operator()(PyObject* args_, PyObject*) // eliminate - // this - // trailing - // keyword dict - { - typedef typename mpl::begin::type first; - typedef typename first::type result_t; - typedef typename select_result_converter::type result_converter; -# if N -# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i) -# define BOOST_PP_LOCAL_LIMITS (0, N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - // all converters have been checked. Now we can do the - // precall part of the policy - if (!m_data.second().precall(args_)) - return 0; - - typedef typename detail::invoke_tag::type tag; - - PyObject* result = detail::invoke( - tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c)); - - return m_data.second().postcall(args_, result); - } - private: - compressed_pair m_data; - }; -}; - - - -#endif // BOOST_PP_IS_ITERATING - - diff --git a/include/boost/python/detail/char_array.hpp b/include/boost/python/detail/char_array.hpp deleted file mode 100644 index d68aea47..00000000 --- a/include/boost/python/detail/char_array.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CHAR_ARRAY_DWA2002129_HPP -# define CHAR_ARRAY_DWA2002129_HPP - -namespace boost { namespace python { namespace detail { - -// This little package is used to transmit the number of arguments -// from the helper functions below to the sizeof() expression below. -// Because we can never have an array of fewer than 1 element, we -// add 1 to n and then subtract 1 from the result of sizeof() below. -template -struct char_array -{ - char elements[n+1]; -}; - -}}} // namespace boost::python::detail - -#endif // CHAR_ARRAY_DWA2002129_HPP diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp deleted file mode 100644 index 4e2b85ab..00000000 --- a/include/boost/python/detail/config.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// Revision History: -// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams) - -#ifndef CONFIG_DWA052200_H_ -# define CONFIG_DWA052200_H_ - -# include - -# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE - // A gcc bug forces some symbols into the global namespace -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE -# define BOOST_PYTHON_CONVERSION -# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x -# else -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python { -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python -# define BOOST_PYTHON_CONVERSION boost::python -# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';' -# endif - -# if defined(BOOST_MSVC) -# if _MSC_VER <= 1200 -# define BOOST_MSVC6_OR_EARLIER 1 -# endif - -# pragma warning (disable : 4786) // disable truncated debug symbols -# pragma warning (disable : 4251) // disable exported dll function -# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or 'false' -# pragma warning (disable : 4275) // non dll-interface class - -# elif defined(__ICL) && __ICL < 600 // Intel C++ 5 - -# pragma warning(disable: 985) // identifier was truncated in debug information - -# endif - -// The STLport puts all of the standard 'C' library names in std (as far as the -// user is concerned), but without it you need a fix if you're using MSVC or -// Intel C++ -# if defined(BOOST_MSVC_STD_ITERATOR) -# define BOOST_CSTD_ -# else -# define BOOST_CSTD_ std -# endif - -/***************************************************************************** - * - * Set up dll import/export options: - * - ****************************************************************************/ - -// backwards compatibility: -#ifdef BOOST_PYTHON_STATIC_LIB -# define BOOST_PYTHON_STATIC_LINK -# elif !defined(BOOST_PYTHON_DYNAMIC_LIB) -# define BOOST_PYTHON_DYNAMIC_LIB -#endif - -#if defined(__MWERKS__) \ - || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \ - || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) -# define BOOST_PYTHON_NO_TEMPLATE_EXPORT -#endif - -#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) -# if defined(BOOST_PYTHON_SOURCE) -# define BOOST_PYTHON_DECL __declspec(dllexport) -# define BOOST_PYTHON_BUILD_DLL -# else -# define BOOST_PYTHON_DECL __declspec(dllimport) -# endif - -// MinGW, at least, has some problems exporting template instantiations -# if defined(__GNUC__) && __GNUC__ < 3 && !defined(__CYGWIN__) -# define BOOST_PYTHON_NO_TEMPLATE_EXPORT -# endif - -#endif - -#ifndef BOOST_PYTHON_DECL -# define BOOST_PYTHON_DECL -#endif - -#ifndef BOOST_PYTHON_EXPORT -# define BOOST_PYTHON_EXPORT extern -#endif - -#if !defined(BOOST_PYTHON_NO_TEMPLATE_EXPORT) -# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL instantiation -#else -# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD -#endif - -#if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) -// Replace broken Tru64/cxx offsetof macro -# define BOOST_PYTHON_OFFSETOF(s_name, s_member) \ - ((size_t)__INTADDR__(&(((s_name *)0)->s_member))) -#else -# define BOOST_PYTHON_OFFSETOF offsetof -#endif - -#endif // CONFIG_DWA052200_H_ diff --git a/include/boost/python/detail/construct.hpp b/include/boost/python/detail/construct.hpp deleted file mode 100644 index f7b747f6..00000000 --- a/include/boost/python/detail/construct.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CONSTRUCT_REFERENCE_DWA2002716_HPP -# define CONSTRUCT_REFERENCE_DWA2002716_HPP - -namespace boost { namespace python { namespace detail { - -template -void construct_pointee(void* storage, Arg& x -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - , T const volatile* -# else - , T const* -# endif - ) -{ - new (storage) T(x); -} - -template -void construct_referent_impl(void* storage, Arg& x, T&(*)()) -{ - construct_pointee(storage, x, (T*)0); -} - -template -void construct_referent(void* storage, Arg const& x, T(*tag)() = 0) -{ - construct_referent_impl(storage, x, tag); -} - -template -void construct_referent(void* storage, Arg& x, T(*tag)() = 0) -{ - construct_referent_impl(storage, x, tag); -} - -}}} // namespace boost::python::detail - -#endif // CONSTRUCT_REFERENCE_DWA2002716_HPP diff --git a/include/boost/python/detail/convertible.hpp b/include/boost/python/detail/convertible.hpp deleted file mode 100755 index 74440090..00000000 --- a/include/boost/python/detail/convertible.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CONVERTIBLE_DWA2002614_HPP -# define CONVERTIBLE_DWA2002614_HPP - -# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241 -# include -# include -# endif - -// Supplies a runtime is_convertible check which can be used with tag -// dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible -namespace boost { namespace python { namespace detail { - -typedef char* yes_convertible; -typedef int* no_convertible; - -template -struct convertible -{ -# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 || __EDG_VERSION__ == 238 - static inline no_convertible check(...) { return 0; } - static inline yes_convertible check(Target) { return 0; } -# else - template - static inline typename mpl::if_c< - is_convertible::value - , yes_convertible - , no_convertible - >::type check(X const&) { return 0; } -# endif -}; - -}}} // namespace boost::python::detail - -#endif // CONVERTIBLE_DWA2002614_HPP diff --git a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp b/include/boost/python/detail/copy_ctor_mutates_rhs.hpp deleted file mode 100755 index b1613924..00000000 --- a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef COPY_CTOR_MUTATES_RHS_DWA2003219_HPP -# define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP - -#include -#include - -namespace boost { namespace python { namespace detail { - -template -struct copy_ctor_mutates_rhs - : is_auto_ptr -{ -}; - -}}} // namespace boost::python::detail - -#endif // COPY_CTOR_MUTATES_RHS_DWA2003219_HPP diff --git a/include/boost/python/detail/cv_category.hpp b/include/boost/python/detail/cv_category.hpp deleted file mode 100644 index f4ac4b92..00000000 --- a/include/boost/python/detail/cv_category.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CV_CATEGORY_DWA200222_HPP -# define CV_CATEGORY_DWA200222_HPP -# include - -namespace boost { namespace python { namespace detail { - -template -struct cv_tag -{ - BOOST_STATIC_CONSTANT(bool, is_const = is_const_); - BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_); -}; - -typedef cv_tag cv_unqualified; -typedef cv_tag const_; -typedef cv_tag volatile_; -typedef cv_tag const_volatile_; - -template -struct cv_category -{ - BOOST_STATIC_CONSTANT(bool, c = is_const::value); - BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); - typedef cv_tag type; -}; - -}}} // namespace boost::python::detail - -#endif // CV_CATEGORY_DWA200222_HPP diff --git a/include/boost/python/detail/decorated_type_id.hpp b/include/boost/python/detail/decorated_type_id.hpp deleted file mode 100755 index c43a4160..00000000 --- a/include/boost/python/detail/decorated_type_id.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DECORATED_TYPE_ID_DWA2002517_HPP -# define DECORATED_TYPE_ID_DWA2002517_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -struct decorated_type_info : totally_ordered -{ - enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; - - decorated_type_info(type_info, decoration = decoration()); - - inline bool operator<(decorated_type_info const& rhs) const; - inline bool operator==(decorated_type_info const& rhs) const; - - friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); - - operator type_info const&() const; - private: // type - typedef type_info base_id_t; - - private: // data members - decoration m_decoration; - base_id_t m_base_type; -}; - -template -inline decorated_type_info decorated_type_id(boost::type* = 0) -{ - return decorated_type_info( - type_id() - , decorated_type_info::decoration( - (is_const::value || python::detail::is_reference_to_const::value - ? decorated_type_info::const_ : 0) - | (is_volatile::value || python::detail::is_reference_to_volatile::value - ? decorated_type_info::volatile_ : 0) - | (is_reference::value ? decorated_type_info::reference : 0) - ) - ); -} - -inline decorated_type_info::decorated_type_info(type_info base_t, decoration decoration) - : m_decoration(decoration) - , m_base_type(base_t) -{ -} - -inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const -{ - return m_decoration < rhs.m_decoration - || m_decoration == rhs.m_decoration - && m_base_type < rhs.m_base_type; -} - -inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const -{ - return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; -} - -inline decorated_type_info::operator type_info const&() const -{ - return m_base_type; -} - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); - -}}} // namespace boost::python::detail - -#endif // DECORATED_TYPE_ID_DWA2002517_HPP diff --git a/include/boost/python/detail/decref_guard.hpp b/include/boost/python/detail/decref_guard.hpp deleted file mode 100644 index 67455706..00000000 --- a/include/boost/python/detail/decref_guard.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DECREF_GUARD_DWA20021220_HPP -# define DECREF_GUARD_DWA20021220_HPP - -namespace boost { namespace python { namespace detail { - -struct decref_guard -{ - decref_guard(PyObject* o) : obj(o) {} - ~decref_guard() { Py_XDECREF(obj); } - void cancel() { obj = 0; } - private: - PyObject* obj; -}; - -}}} // namespace boost::python::detail - -#endif // DECREF_GUARD_DWA20021220_HPP diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp deleted file mode 100644 index 98933bd4..00000000 --- a/include/boost/python/detail/def_helper.hpp +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DEF_HELPER_DWA200287_HPP -# define DEF_HELPER_DWA200287_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -struct default_call_policies; - -namespace detail -{ - // tuple_extract::extract(t) returns the first - // element of a Tuple whose type E satisfies the given Predicate - // applied to add_reference. The Predicate must be an MPL - // metafunction class. - template - struct tuple_extract; - - // Implementation class for when the tuple's head type does not - // satisfy the Predicate - template - struct tuple_extract_impl - { - template - struct apply - { - typedef typename Tuple::head_type result_type; - - static typename Tuple::head_type extract(Tuple const& x) - { - return x.get_head(); - } - }; - }; - - // Implementation specialization for when the tuple's head type - // satisfies the predicate - template <> - struct tuple_extract_impl - { - template - struct apply - { - // recursive application of tuple_extract on the tail of the tuple - typedef tuple_extract next; - typedef typename next::result_type result_type; - - static result_type extract(Tuple const& x) - { - return next::extract(x.get_tail()); - } - }; - }; - - // A metafunction which selects a version of tuple_extract_impl to - // use for the implementation of tuple_extract - template - struct tuple_extract_base_select - { - typedef typename Tuple::head_type head_type; - typedef typename mpl::apply1::type>::type match_t; - BOOST_STATIC_CONSTANT(bool, match = match_t::value); - typedef typename tuple_extract_impl::template apply type; - }; - - template - struct tuple_extract - : tuple_extract_base_select< - Tuple - , typename mpl::lambda::type - >::type - { - }; - - - // - // Specialized extractors for the docstring, keywords, CallPolicies, - // and default implementation of virtual functions - // - - template - struct doc_extract - : tuple_extract< - Tuple - , mpl::not_< - mpl::or_< - is_reference_to_class - , is_reference_to_member_function_pointer - > - > - > - { - }; - - template - struct keyword_extract - : tuple_extract > - { - }; - - template - struct policy_extract - : tuple_extract< - Tuple - , mpl::and_< - mpl::not_ > - , is_reference_to_class - , mpl::not_ > - > - > - { - }; - - template - struct default_implementation_extract - : tuple_extract< - Tuple - , is_reference_to_member_function_pointer - > - { - }; - - // - // A helper class for decoding the optional arguments to def() - // invocations, which can be supplied in any order and are - // discriminated by their type properties. The template parameters - // are expected to be the types of the actual (optional) arguments - // passed to def(). - // - template - struct def_helper - { - // A tuple type which begins with references to the supplied - // arguments and ends with actual representatives of the default - // types. - typedef boost::tuples::tuple< - T1 const& - , T2 const& - , T3 const& - , T4 const& - , default_call_policies - , keywords<0> - , char const* - , void(not_specified::*)() // A function pointer type which is never an - // appropriate default implementation - > all_t; - - // Constructors; these initialize an member of the tuple type - // shown above. - def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {} - def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {} - def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {} - def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {} - - private: // types - typedef typename default_implementation_extract::result_type default_implementation_t; - - public: // Constants which can be used for static assertions. - - // Users must not supply a default implementation for non-class - // methods. - BOOST_STATIC_CONSTANT( - bool, has_default_implementation = ( - !is_same::value)); - - public: // Extractor functions which pull the appropriate value out - // of the tuple - char const* doc() const - { - return doc_extract::extract(m_all); - } - - typename keyword_extract::result_type keywords() const - { - return keyword_extract::extract(m_all); - } - - typename policy_extract::result_type policies() const - { - return policy_extract::extract(m_all); - } - - default_implementation_t default_implementation() const - { - return default_implementation_extract::extract(m_all); - } - - private: // data members - all_t m_all; - not_specified m_nil; // for filling in not_specified slots - }; -} - -}} // namespace boost::python::detail - -#endif // DEF_HELPER_DWA200287_HPP diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp deleted file mode 100644 index ac963cb6..00000000 --- a/include/boost/python/detail/defaults_def.hpp +++ /dev/null @@ -1,280 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, -// use, modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided "as is" -// without express or implied warranty, and with no claim as to its -// suitability for any purpose. -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(BOOST_PP_IS_ITERATING) - -#ifndef DEFAULTS_DEF_JDG20020811_HPP -#define DEFAULTS_DEF_JDG20020811_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -namespace boost { namespace python { - -struct module; - -namespace objects -{ - struct class_base; -} - -namespace detail -{ - template struct member_function_cast; - - template - static void name_space_def( - NameSpaceT& name_space - , char const* name - , Func f - , keyword_range const& kw - , CallPolicies const& policies - , char const* doc - , objects::class_base* - ) - { - typedef typename NameSpaceT::wrapped_type wrapped_type; - - objects::add_to_namespace( - name_space, name, - detail::make_keyword_range_function( - // This bit of nastiness casts F to a member function of T if possible. - member_function_cast::stage1(f).stage2((wrapped_type*)0).stage3(f) - , policies, kw) - , doc); - } - - template - static void name_space_def( - object& name_space - , char const* name - , Func f - , keyword_range const& kw - , CallPolicies const& policies - , char const* doc - , ... - ) - { - scope within(name_space); - - detail::scope_setattr_doc( - name - , detail::make_keyword_range_function(f, policies, kw) - , doc); - } - - // For backward compatibility - template - static void name_space_def( - NameSpaceT& name_space - , char const* name - , Func f - , keyword_range const& kw // ignored - , CallPolicies const& policies - , char const* doc - , module* - ) - { - name_space.def(name, f, policies, doc); - } - - /////////////////////////////////////////////////////////////////////////////// - // - // This Boost PP code generates expansions for - // - // template - // inline void - // define_stub_function( - // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_) - // { - // name_space.def(name, &OverloadsT::func_N); - // } - // - // where N runs from 0 to BOOST_PYTHON_MAX_ARITY - // - // The set of overloaded functions (define_stub_function) expects: - // - // 1. char const* name: function name that will be visible to python - // 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) - // 3. NameSpaceT& name_space: a python::class_ or python::module instance - // 4. int_t: the Nth overloaded function (OverloadsT::func_N) - // (see defaults_gen.hpp) - // 5. char const* name: doc string - // - /////////////////////////////////////////////////////////////////////////////// - template - struct define_stub_function {}; - -#define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) - -#include BOOST_PP_ITERATE() - -/////////////////////////////////////////////////////////////////////////////// -// -// define_with_defaults_helper -// -// This helper template struct does the actual recursive definition. -// There's a generic version define_with_defaults_helper and a -// terminal case define_with_defaults_helper<0>. The struct and its -// specialization has a sole static member function def that expects: -// -// 1. char const* name: function name that will be visible to python -// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) -// 3. NameSpaceT& name_space: a python::class_ or python::module instance -// 4. char const* name: doc string -// -// The def static member function calls a corresponding -// define_stub_function. The general case recursively calls -// define_with_defaults_helper::def until it reaches the -// terminal case case define_with_defaults_helper<0>. -// -/////////////////////////////////////////////////////////////////////////////// - template - struct define_with_defaults_helper { - - template - static void - def( - char const* name, - StubsT stubs, - keyword_range kw, - CallPolicies const& policies, - NameSpaceT& name_space, - char const* doc) - { - // define the NTH stub function of stubs - define_stub_function::define(name, stubs, kw, policies, name_space, doc); - - if (kw.second > kw.first) - --kw.second; - - // call the next define_with_defaults_helper - define_with_defaults_helper::def(name, stubs, kw, policies, name_space, doc); - } - }; - -/////////////////////////////////////// - template <> - struct define_with_defaults_helper<0> { - - template - static void - def( - char const* name, - StubsT stubs, - keyword_range const& kw, - CallPolicies const& policies, - NameSpaceT& name_space, - char const* doc) - { - // define the Oth stub function of stubs - define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc); - // return - } - }; - -/////////////////////////////////////////////////////////////////////////////// -// -// define_with_defaults -// -// 1. char const* name: function name that will be visible to python -// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) -// 3. CallPolicies& policies: Call policies -// 4. NameSpaceT& name_space: a python::class_ or python::module instance -// 5. SigT sig: Function signature typelist (see defaults_gen.hpp) -// 6. char const* name: doc string -// -// This is the main entry point. This function recursively defines all -// stub functions of StubT (see defaults_gen.hpp) in NameSpaceT name_space which -// can be either a python::class_ or a python::module. The sig argument -// is a typelist that specifies the return type, the class (for member -// functions, and the arguments. Here are some SigT examples: -// -// int foo(int) mpl::list -// void bar(int, int) mpl::list -// void C::foo(int) mpl::list -// -/////////////////////////////////////////////////////////////////////////////// - template - inline void - define_with_defaults( - char const* name, - OverloadsT const& overloads, - NameSpaceT& name_space, - SigT const& sig) - { - typedef typename mpl::front::type return_type; - typedef typename OverloadsT::void_return_type void_return_type; - typedef typename OverloadsT::non_void_return_type non_void_return_type; - - typedef typename mpl::if_c< - boost::is_same::value - , void_return_type - , non_void_return_type - >::type stubs_type; - - BOOST_STATIC_ASSERT( - (stubs_type::max_args) <= mpl::size::value); - - typedef typename stubs_type::template gen gen_type; - define_with_defaults_helper::def( - name - , gen_type() - , overloads.keywords() - , overloads.call_policies() - , name_space - , overloads.doc_string()); - } - -} // namespace detail - -}} // namespace boost::python - -/////////////////////////////////////////////////////////////////////////////// -#endif // DEFAULTS_DEF_JDG20020811_HPP - -#else // defined(BOOST_PP_IS_ITERATING) -// PP vertical iteration code - - -template <> -struct define_stub_function { - template - static void define( - char const* name - , StubsT const& - , keyword_range const& kw - , CallPolicies const& policies - , NameSpaceT& name_space - , char const* doc) - { - detail::name_space_def( - name_space - , name - , &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()) - , kw - , policies - , doc - , &name_space); - } -}; - -#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp deleted file mode 100644 index f1a367a4..00000000 --- a/include/boost/python/detail/defaults_gen.hpp +++ /dev/null @@ -1,388 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, -// use, modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided "as is" -// without express or implied warranty, and with no claim as to its -// suitability for any purpose. -// -/////////////////////////////////////////////////////////////////////////////// -#ifndef DEFAULTS_GEN_JDG20020807_HPP -#define DEFAULTS_GEN_JDG20020807_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace detail -{ - // overloads_base is used as a base class for all function - // stubs. This class holds the doc_string of the stubs. - struct overloads_base - { - overloads_base(char const* doc_) - : m_doc(doc_) {} - - overloads_base(char const* doc_, detail::keyword_range const& kw) - : m_doc(doc_), m_keywords(kw) {} - - char const* doc_string() const - { - return m_doc; - } - - detail::keyword_range const& keywords() const - { - return m_keywords; - } - - private: - char const* m_doc; - detail::keyword_range m_keywords; - }; - - // overloads_proxy is generated by the overloads_common operator[] (see - // below). This class holds a user defined call policies of the stubs. - template - struct overloads_proxy - : public overloads_base - { - typedef typename OverloadsT::non_void_return_type non_void_return_type; - typedef typename OverloadsT::void_return_type void_return_type; - - overloads_proxy( - CallPoliciesT const& policies_ - , char const* doc - , keyword_range const& kw - ) - : overloads_base(doc, kw) - , policies(policies_) - {} - - CallPoliciesT - call_policies() const - { - return policies; - } - - CallPoliciesT policies; - }; - - // overloads_common is our default function stubs base class. This - // class returns the default_call_policies in its call_policies() - // member function. It can generate a overloads_proxy however through - // its operator[] - template - struct overloads_common - : public overloads_base - { - overloads_common(char const* doc) - : overloads_base(doc) {} - - overloads_common(char const* doc, keyword_range const& kw) - : overloads_base(doc, kw) {} - - default_call_policies - call_policies() const - { - return default_call_policies(); - } - - template - overloads_proxy - operator[](CallPoliciesT const& policies) const - { - return overloads_proxy( - policies, this->doc_string(), this->keywords()); - } - }; - -}}} // namespace boost::python::detail - - -#define BOOST_PYTHON_TYPEDEF_GEN(z, index, data) \ - typedef typename ::boost::mpl::next::type \ - BOOST_PP_CAT(iter, BOOST_PP_INC(index)); \ - typedef typename ::boost::mpl::apply0::type \ - BOOST_PP_CAT(T, index); - -#define BOOST_PYTHON_FUNC_WRAPPER_GEN(z, index, data) \ - static RT BOOST_PP_CAT(func_, \ - BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \ - BOOST_PP_ENUM_BINARY_PARAMS_Z( \ - 1, index, T, arg)) \ - { \ - BOOST_PP_TUPLE_ELEM(3, 2, data) \ - BOOST_PP_TUPLE_ELEM(3, 0, data)( \ - BOOST_PP_ENUM_PARAMS( \ - index, \ - arg)); \ - } - -#define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ - struct fstubs_name \ - { \ - BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \ - BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \ - \ - template \ - struct gen \ - { \ - typedef typename ::boost::mpl::begin::type rt_iter; \ - typedef typename ::boost::mpl::apply0::type RT; \ - typedef typename ::boost::mpl::next::type iter0; \ - \ - BOOST_PP_REPEAT_2ND( \ - n_args, \ - BOOST_PYTHON_TYPEDEF_GEN, \ - 0) \ - \ - BOOST_PP_REPEAT_FROM_TO_2( \ - BOOST_PP_SUB_D(1, n_args, n_dflts), \ - BOOST_PP_INC(n_args), \ - BOOST_PYTHON_FUNC_WRAPPER_GEN, \ - (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \ - }; \ - }; \ - -/////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN(z, index, data) \ - static RT BOOST_PP_CAT(func_, \ - BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \ - ClassT obj BOOST_PP_COMMA_IF(index) \ - BOOST_PP_ENUM_BINARY_PARAMS_Z(1, index, T, arg) \ - ) \ - { \ - BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)( \ - BOOST_PP_ENUM_PARAMS(index, arg) \ - ); \ - } - -#define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ - struct fstubs_name \ - { \ - BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \ - BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \ - \ - template \ - struct gen \ - { \ - typedef typename ::boost::mpl::begin::type rt_iter; \ - typedef typename ::boost::mpl::apply0::type RT; \ - \ - typedef typename ::boost::mpl::next::type class_iter; \ - typedef typename ::boost::mpl::apply0::type ClassT; \ - typedef typename ::boost::mpl::next::type iter0; \ - \ - BOOST_PP_REPEAT_2ND( \ - n_args, \ - BOOST_PYTHON_TYPEDEF_GEN, \ - 0) \ - \ - BOOST_PP_REPEAT_FROM_TO_2( \ - BOOST_PP_SUB_D(1, n_args, n_dflts), \ - BOOST_PP_INC(n_args), \ - BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN, \ - (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \ - }; \ - }; - -#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - fstubs_name(char const* doc = 0) \ - : ::boost::python::detail::overloads_common(doc) {} \ - template \ - fstubs_name(char const* doc, Keywords const& keywords) \ - : ::boost::python::detail::overloads_common( \ - doc, keywords.range()) \ - { \ - typedef typename ::boost::python::detail:: \ - error::more_keywords_than_function_arguments< \ - Keywords::size,n_args>::too_many_keywords assertion; \ - } \ - template \ - fstubs_name(Keywords const& keywords, char const* doc = 0) \ - : ::boost::python::detail::overloads_common( \ - doc, keywords.range()) \ - { \ - typedef typename ::boost::python::detail:: \ - error::more_keywords_than_function_arguments< \ - Keywords::size,n_args>::too_many_keywords assertion; \ - } - -# if defined(BOOST_NO_VOID_RETURNS) - -# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - BOOST_PYTHON_GEN_FUNCTION( \ - fname, void_return_type, n_args, n_dflts, ;) \ - \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - -# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_MEM_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - BOOST_PYTHON_GEN_MEM_FUNCTION( \ - fname, void_return_type, n_args, n_dflts, ;) \ - \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - -# else // !defined(BOOST_NO_VOID_RETURNS) - -# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - \ - typedef non_void_return_type void_return_type; \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - - -# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ - struct fstubs_name \ - : public ::boost::python::detail::overloads_common \ - { \ - BOOST_PYTHON_GEN_MEM_FUNCTION( \ - fname, non_void_return_type, n_args, n_dflts, return) \ - \ - typedef non_void_return_type void_return_type; \ - BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ - }; - -# endif // !defined(BOOST_NO_VOID_RETURNS) - -/////////////////////////////////////////////////////////////////////////////// -// -// MAIN MACROS -// -// Given generator_name, fname, min_args and max_args, These macros -// generate function stubs that forward to a function or member function -// named fname. max_args is the arity of the function or member function -// fname. fname can have default arguments. min_args is the minimum -// arity that fname can accept. -// -// There are two versions: -// -// 1. BOOST_PYTHON_FUNCTION_OVERLOADS for free functions -// 2. BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for member functions. -// -// For instance, given a function: -// -// int -// foo(int a, char b = 1, unsigned c = 2, double d = 3) -// { -// return a + b + c + int(d); -// } -// -// The macro invocation: -// -// BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) -// -// Generates this code: -// -// struct foo_stubsNonVoid -// { -// static const int n_funcs = 4; -// static const int max_args = n_funcs; -// -// template -// struct gen -// { -// typedef typename ::boost::mpl::begin::type rt_iter; -// typedef typename rt_iter::type RT; -// typedef typename rt_iter::next iter0; -// typedef typename iter0::type T0; -// typedef typename iter0::next iter1; -// typedef typename iter1::type T1; -// typedef typename iter1::next iter2; -// typedef typename iter2::type T2; -// typedef typename iter2::next iter3; -// typedef typename iter3::type T3; -// typedef typename iter3::next iter4; -// -// static RT func_0(T0 arg0) -// { return foo(arg0); } -// -// static RT func_1(T0 arg0, T1 arg1) -// { return foo(arg0, arg1); } -// -// static RT func_2(T0 arg0, T1 arg1, T2 arg2) -// { return foo(arg0, arg1, arg2); } -// -// static RT func_3(T0 arg0, T1 arg1, T2 arg2, T3 arg3) -// { return foo(arg0, arg1, arg2, arg3); } -// }; -// }; -// -// struct foo_overloads -// : public boost::python::detail::overloads_common -// { -// typedef foo_overloadsNonVoid non_void_return_type; -// typedef foo_overloadsNonVoid void_return_type; -// -// foo_overloads(char const* doc = 0) -// : boost::python::detail::overloads_common(doc) {} -// }; -// -// The typedefs non_void_return_type and void_return_type are -// used to handle compilers that do not support void returns. The -// example above typedefs non_void_return_type and -// void_return_type to foo_overloadsNonVoid. On compilers that do -// not support void returns, there are two versions: -// foo_overloadsNonVoid and foo_overloadsVoid. The "Void" -// version is almost identical to the "NonVoid" version except -// for the return type (void) and the lack of the return keyword. -// -// See the overloads_common above for a description of the -// foo_overloads' base class. -// -/////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \ - BOOST_PYTHON_GEN_FUNCTION_STUB( \ - fname, \ - generator_name, \ - max_args, \ - BOOST_PP_SUB_D(1, max_args, min_args)) - -#define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \ - BOOST_PYTHON_GEN_MEM_FUNCTION_STUB( \ - fname, \ - generator_name, \ - max_args, \ - BOOST_PP_SUB_D(1, max_args, min_args)) - -// deprecated macro names (to be removed) -#define BOOST_PYTHON_FUNCTION_GENERATOR BOOST_PYTHON_FUNCTION_OVERLOADS -#define BOOST_PYTHON_MEM_FUN_GENERATOR BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - -/////////////////////////////////////////////////////////////////////////////// -#endif // DEFAULTS_GEN_JDG20020807_HPP - - diff --git a/include/boost/python/detail/dependent.hpp b/include/boost/python/detail/dependent.hpp deleted file mode 100644 index 4fc48766..00000000 --- a/include/boost/python/detail/dependent.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DEPENDENT_DWA200286_HPP -# define DEPENDENT_DWA200286_HPP - -namespace boost { namespace python { namespace detail { - -// A way to turn a concrete type T into a type dependent on U. This -// keeps conforming compilers (those implementing proper 2-phase -// name lookup for templates) from complaining about incomplete -// types in situations where it would otherwise be inconvenient or -// impossible to re-order code so that all types are defined in time. - -// One such use is when we must return an incomplete T from a member -// function template (which must be defined in the class body to -// keep MSVC happy). -template -struct dependent -{ - typedef T type; -}; - -}}} // namespace boost::python::detail - -#endif // DEPENDENT_DWA200286_HPP diff --git a/include/boost/python/detail/destroy.hpp b/include/boost/python/detail/destroy.hpp deleted file mode 100644 index 7b107550..00000000 --- a/include/boost/python/detail/destroy.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DESTROY_DWA2002221_HPP -# define DESTROY_DWA2002221_HPP - -# include -# include - -namespace boost { namespace python { namespace detail { - -template struct value_destroyer; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile* p) - { - p->T::~T(); - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(A*, T const volatile* const first) - { - for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p) - value_destroyer< - boost::is_array::value - ,boost::has_trivial_destructor::value - >::execute(p); - } - - template - static void execute(T const volatile* p) - { - execute(p, *p); - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile* p) - { - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile* p) - { - } -}; - -template -inline void destroy_referent_impl(void* p, T& (*)()) -{ - // note: cv-qualification needed for MSVC6 - // must come *before* T for metrowerks - value_destroyer< - (boost::is_array::value) - ,(boost::has_trivial_destructor::value) - >::execute((const volatile T*)p); -} - -template -inline void destroy_referent(void* p, T(*)() = 0) -{ - destroy_referent_impl(p, (T(*)())0); -} - -}}} // namespace boost::python::detail - -#endif // DESTROY_DWA2002221_HPP diff --git a/include/boost/python/detail/exception_handler.hpp b/include/boost/python/detail/exception_handler.hpp deleted file mode 100644 index 3e36a7a5..00000000 --- a/include/boost/python/detail/exception_handler.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef EXCEPTION_HANDLER_DWA2002810_HPP -# define EXCEPTION_HANDLER_DWA2002810_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -struct BOOST_PYTHON_DECL exception_handler; - -typedef function2 const&> handler_function; - -struct BOOST_PYTHON_DECL exception_handler -{ - private: // types - - public: - explicit exception_handler(handler_function const& impl); - - inline bool handle(function0 const& f) const; - - bool operator()(function0 const& f) const; - - static exception_handler* chain; - - private: - static exception_handler* tail; - - handler_function m_impl; - exception_handler* m_next; -}; - - -inline bool exception_handler::handle(function0 const& f) const -{ - return this->m_impl(*this, f); -} - -BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f); - -}}} // namespace boost::python::detail - -#endif // EXCEPTION_HANDLER_DWA2002810_HPP diff --git a/include/boost/python/detail/force_instantiate.hpp b/include/boost/python/detail/force_instantiate.hpp deleted file mode 100755 index 62446c32..00000000 --- a/include/boost/python/detail/force_instantiate.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FORCE_INSTANTIATE_DWA200265_HPP -# define FORCE_INSTANTIATE_DWA200265_HPP - -namespace boost { namespace python { namespace detail { - -// Allows us to force the argument to be instantiated without -// incurring unused variable warnings - -# if !defined(BOOST_MSVC) || BOOST_MSVC == 1200 || _MSC_FULL_VER > 13102196 - -template -inline void force_instantiate(T const&) {} - -# else - -# pragma optimize("g", off) -inline void force_instantiate_impl(...) {} -# pragma optimize("", on) -template -inline void force_instantiate(T const& x) -{ - detail::force_instantiate_impl(&x); -} -# endif - -}}} // namespace boost::python::detail - -#endif // FORCE_INSTANTIATE_DWA200265_HPP diff --git a/include/boost/python/detail/if_else.hpp b/include/boost/python/detail/if_else.hpp deleted file mode 100644 index 6668617c..00000000 --- a/include/boost/python/detail/if_else.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef IF_ELSE_DWA2002322_HPP -# define IF_ELSE_DWA2002322_HPP -# include - -namespace boost { namespace python { namespace detail { - -template struct elif_selected; - -template -struct if_selected -{ - template - struct elif : elif_selected - { - }; - - template - struct else_ - { - typedef T type; - }; -}; - -# if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) -namespace msvc70_aux { - -template< bool > struct inherit_from -{ - template< typename T > struct result - { - typedef T type; - }; -}; - -template<> struct inherit_from -{ - template< typename T > struct result - { - struct type {}; - }; -}; - -template< typename T > -struct never_true -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -} // namespace msvc70_aux - -#endif // # if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) - -template -struct elif_selected -{ -# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) - template class then; -# elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300) - template - struct then : msvc70_aux::inherit_from< msvc70_aux::never_true::value > - ::template result< if_selected >::type - { - }; -# else - template - struct then : if_selected - { - }; -# endif -}; - -# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) -template -template -class elif_selected::then : public if_selected -{ -}; -# endif - -template struct if_ -{ - template - struct then : if_selected - { - }; -}; - -struct if_unselected -{ - template struct elif : if_ - { - }; - - template - struct else_ - { - typedef U type; - }; -}; - -template <> -struct if_ -{ - template - struct then : if_unselected - { - }; -}; - -}}} // namespace boost::python::detail - -#endif // IF_ELSE_DWA2002322_HPP diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp deleted file mode 100644 index 170f3662..00000000 --- a/include/boost/python/detail/indirect_traits.hpp +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef INDIRECT_TRAITS_DWA2002131_HPP -# define INDIRECT_TRAITS_DWA2002131_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include - -# include -# if 0 && BOOST_WORKAROUND(__MWERKS__, <= 0x2407) -# include -# endif - -# include -# include -# include -# include -# include - -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# include -# endif - -namespace boost { namespace python { namespace detail { - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_reference_to_const : mpl::false_ -{ -}; - -template -struct is_reference_to_const : mpl::true_ -{ -}; - -# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround -template -struct is_reference_to_const : mpl::true_ -{ -}; -# endif - -template -struct is_reference_to_function : mpl::false_ -{ -}; - -template -struct is_reference_to_function : is_function -{ -}; - -template -struct is_pointer_to_function : mpl::false_ -{ -}; - -// There's no such thing as a pointer-to-cv-function, so we don't need -// specializations for those -template -struct is_pointer_to_function : is_function -{ -}; - -template -struct is_reference_to_member_function_pointer_impl : mpl::false_ -{ -}; - -template -struct is_reference_to_member_function_pointer_impl - : is_member_function_pointer::type> -{ -}; - - -template -struct is_reference_to_member_function_pointer - : is_reference_to_member_function_pointer_impl -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) -}; - -template -struct is_reference_to_function_pointer_aux - : mpl::and_< - is_reference - , is_pointer_to_function< - typename remove_cv< - typename remove_reference::type - >::type - > - > -{ - // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those -}; - -template -struct is_reference_to_function_pointer - : mpl::if_< - is_reference_to_function - , mpl::false_ - , is_reference_to_function_pointer_aux - >::type -{ -}; - -template -struct is_reference_to_non_const - : mpl::and_< - is_reference - , mpl::not_< - is_reference_to_const - > - > -{ -}; - -template -struct is_reference_to_volatile : mpl::false_ -{ -}; - -template -struct is_reference_to_volatile : mpl::true_ -{ -}; - -# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround -template -struct is_reference_to_volatile : mpl::true_ -{ -}; -# endif - - -template -struct is_reference_to_pointer : mpl::false_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_pointer : mpl::true_ -{ -}; - -template -struct is_reference_to_class - : mpl::and_< - is_reference - , is_class< - typename remove_cv< - typename remove_reference::type - >::type - > - > -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) -}; - -template -struct is_pointer_to_class - : mpl::and_< - is_pointer - , is_class< - typename remove_cv< - typename remove_pointer::type - >::type - > - > -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T)) -}; - -# else - -typedef char (&inner_yes_type)[3]; -typedef char (&inner_no_type)[2]; -typedef char (&outer_no_type)[1]; - -template -struct is_const_help -{ - typedef typename mpl::if_< - is_const - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_volatile_help -{ - typedef typename mpl::if_< - is_volatile - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_pointer_help -{ - typedef typename mpl::if_< - is_pointer - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_class_help -{ - typedef typename mpl::if_< - is_class - , inner_yes_type - , inner_no_type - >::type type; -}; - -template -struct is_reference_to_function_aux -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); - }; - -template -struct is_reference_to_function - : mpl::if_, is_reference_to_function_aux, mpl::bool_ >::type -{ -}; - -template -struct is_pointer_to_function_aux -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); - typedef mpl::bool_ type; -}; - -template -struct is_pointer_to_function - : mpl::if_, is_pointer_to_function_aux, mpl::bool_ >::type -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) -}; - -struct false_helper1 -{ - template - struct apply - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; -}; - -template -typename is_const_help::type reference_to_const_helper(V&); -outer_no_type -reference_to_const_helper(...); - -struct true_helper1 -{ - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); - }; -}; - -template -struct is_reference_to_const_helper1 : true_helper1 -{ -# if 0 - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); - }; -# endif -}; - -template <> -struct is_reference_to_const_helper1 : false_helper1 -{ -}; - - -template -struct is_reference_to_const - : is_reference_to_const_helper1::value>::template apply -{ -}; - - - -template -struct is_reference_to_non_const_helper1 -{ - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); - }; -}; - -template <> -struct is_reference_to_non_const_helper1 : false_helper1 -{ -}; - - -template -struct is_reference_to_non_const - : is_reference_to_non_const_helper1::value>::template apply -{ -}; - - -template -typename is_volatile_help::type reference_to_volatile_helper(V&); -outer_no_type -reference_to_volatile_helper(...); - -template -struct is_reference_to_volatile_helper1 -{ - template - struct apply - { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); - }; -}; - -template <> -struct is_reference_to_volatile_helper1 : false_helper1 -{ -}; - - -template -struct is_reference_to_volatile - : is_reference_to_volatile_helper1::value>::template apply -{ -}; - -template -typename is_pointer_help::type reference_to_pointer_helper(V&); -outer_no_type reference_to_pointer_helper(...); - -template -struct is_reference_to_pointer -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_reference::value - && sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type)) - ); -}; - -template -struct is_reference_to_function_pointer - : mpl::if_< - is_reference - , is_pointer_to_function_aux - , mpl::bool_ - >::type -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) -}; - - -template -struct is_member_function_pointer_help - : mpl::if_, inner_yes_type, inner_no_type> -{}; - -template -typename is_member_function_pointer_help::type member_function_pointer_helper(V&); -outer_no_type member_function_pointer_helper(...); - -template -struct is_pointer_to_member_function_aux -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type)); - typedef mpl::bool_ type; -}; - -template -struct is_reference_to_member_function_pointer - : mpl::if_< - is_reference - , is_pointer_to_member_function_aux - , mpl::bool_ - >::type -{ - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) -}; - -template -typename is_class_help::type reference_to_class_helper(V const volatile&); -outer_no_type reference_to_class_helper(...); - -template -struct is_reference_to_class -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_reference::value - & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) - ); - typedef mpl::bool_ type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) -}; - -template -typename is_class_help::type pointer_to_class_helper(V const volatile*); -outer_no_type pointer_to_class_helper(...); - -template -struct is_pointer_to_class -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_pointer::value - && sizeof(pointer_to_class_helper(t)) == sizeof(inner_yes_type)) - ); -}; -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}}} // namespace boost::python::detail - -#endif // INDIRECT_TRAITS_DWA2002131_HPP diff --git a/include/boost/python/detail/invoke.hpp b/include/boost/python/detail/invoke.hpp deleted file mode 100644 index b83c6e34..00000000 --- a/include/boost/python/detail/invoke.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -# ifndef INVOKE_DWA20021122_HPP -# define INVOKE_DWA20021122_HPP - -# include -# include -# include - -# include - -# include -# include -# include -# include -# include -# include - -// This file declares a series of overloaded invoke(...) functions, -// used to invoke wrapped C++ function (object)s from Python. Each one -// accepts: -// -// - a tag which identifies the invocation syntax (e.g. member -// functions must be invoked with a different syntax from regular -// functions) -// -// - a pointer to a result converter type, used solely as a way of -// transmitting the type of the result converter to the function (or -// an int, if the return type is void). -// -// - the "function", which may be a function object, a function or -// member function pointer, or a defaulted_virtual_fn. -// -// - The arg_from_python converters for each of the arguments to be -// passed to the function being invoked. - -namespace boost { namespace python { namespace detail { - -// This "result converter" is really just used as a dispatch tag to -// invoke(...), selecting the appropriate implementation -typedef int void_result_to_python; - -// Trait forward declaration. -template struct is_defaulted_virtual_fn; - -// Tag types describing invocation methods -struct fn_tag {}; -struct mem_fn_tag {}; - -// A metafunction returning the appropriate tag type for invoking an -// object of type T. -template -struct invoke_tag - : mpl::if_< - is_member_function_pointer - , mem_fn_tag - , fn_tag - > -{}; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}}} // namespace boost::python::detail - -# endif // INVOKE_DWA20021122_HPP -#else - -# define N BOOST_PP_ITERATION() - -template -inline PyObject* invoke(fn_tag, RC*, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - return RC()(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) )); -} - -template -inline PyObject* invoke(fn_tag, void_result_to_python, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ); - return none(); -} - -template -inline PyObject* invoke(mem_fn_tag, RC*, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - return RC()( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) ); -} - -template -inline PyObject* invoke(mem_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)); - return none(); -} - -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/is_auto_ptr.hpp b/include/boost/python/detail/is_auto_ptr.hpp deleted file mode 100644 index 986a6309..00000000 --- a/include/boost/python/detail/is_auto_ptr.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef IS_AUTO_PTR_DWA2003224_HPP -# define IS_AUTO_PTR_DWA2003224_HPP - -# ifndef BOOST_NO_AUTO_PTR -# include -# include -# endif - -namespace boost { namespace python { namespace detail { - -# if !defined(BOOST_NO_AUTO_PTR) - -BOOST_PYTHON_IS_XXX_DEF(auto_ptr, std::auto_ptr, 1) - -# else - -template -struct is_auto_ptr : mpl::false_ -{ -}; - -# endif - -}}} // namespace boost::python::detail - -#endif // IS_AUTO_PTR_DWA2003224_HPP diff --git a/include/boost/python/detail/is_function_ref_tester.hpp b/include/boost/python/detail/is_function_ref_tester.hpp deleted file mode 100644 index c9ab4818..00000000 --- a/include/boost/python/detail/is_function_ref_tester.hpp +++ /dev/null @@ -1,136 +0,0 @@ - -// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, -// Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied warranty, -// and with no claim as to its suitability for any purpose. - -#if !defined(BOOST_PP_IS_ITERATING) - -///// header body - -#ifndef BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED -#define BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED - -#include "boost/type_traits/detail/yes_no_type.hpp" -#include "boost/type_traits/config.hpp" - -#if defined(BOOST_TT_PREPROCESSING_MODE) -# include "boost/preprocessor/iterate.hpp" -# include "boost/preprocessor/enum_params.hpp" -# include "boost/preprocessor/comma_if.hpp" -#endif - -namespace boost { -namespace python { -namespace detail { - -template -boost::type_traits::no_type BOOST_TT_DECL is_function_ref_tester(T& ...); - -#if !defined(BOOST_TT_PREPROCESSING_MODE) -// preprocessor-generated part, don't edit by hand! - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23), int); - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24), int); - -#else - -#define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, 25, "boost/type_traits/detail/is_function_ref_tester.hpp")) -#include BOOST_PP_ITERATE() - -#endif // BOOST_TT_PREPROCESSING_MODE - -} // namespace detail -} // namespace python -} // namespace boost - -#endif // BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED - -///// iteration - -#else -#define i BOOST_PP_FRAME_ITERATION(1) - -template -boost::type_traits::yes_type is_function_ref_tester(R (&)(BOOST_PP_ENUM_PARAMS(i,T)), int); - -#undef i -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/is_shared_ptr.hpp b/include/boost/python/detail/is_shared_ptr.hpp deleted file mode 100755 index d3579a6a..00000000 --- a/include/boost/python/detail/is_shared_ptr.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef IS_SHARED_PTR_DWA2003224_HPP -# define IS_SHARED_PTR_DWA2003224_HPP - -# include -# include - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_IS_XXX_DEF(shared_ptr, shared_ptr, 1) - -}}} // namespace boost::python::detail - -#endif // IS_SHARED_PTR_DWA2003224_HPP diff --git a/include/boost/python/detail/is_xxx.hpp b/include/boost/python/detail/is_xxx.hpp deleted file mode 100644 index 0faea999..00000000 --- a/include/boost/python/detail/is_xxx.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef IS_XXX_DWA2003224_HPP -# define IS_XXX_DWA2003224_HPP - -# include -# include -# include - -# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -# include -# include - -# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct is_##name \ -{ \ - typedef char yes; \ - typedef char (&no)[2]; \ - \ - static typename add_reference::type dummy; \ - \ - template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ - static yes test( \ - qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) >&, int \ - ); \ - \ - template \ - static no test(U&, ...); \ - \ - BOOST_STATIC_CONSTANT( \ - bool, value \ - = !is_reference::value \ - & (sizeof(test(dummy, 0)) == sizeof(yes))); \ - \ - typedef mpl::bool_ type; \ -}; - -# else - -# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct is_##name : mpl::false_ \ -{ \ -}; \ - \ -template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) > \ -struct is_##name< \ - qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) > \ -> \ - : mpl::true_ \ -{ \ -}; - -# endif - -#endif // IS_XXX_DWA2003224_HPP diff --git a/include/boost/python/detail/make_keyword_range_fn.hpp b/include/boost/python/detail/make_keyword_range_fn.hpp deleted file mode 100644 index 9c749292..00000000 --- a/include/boost/python/detail/make_keyword_range_fn.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP -# define MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP - -# include -# include - -# include - -# include - - -namespace boost { namespace python { namespace detail { - -// Think of this as a version of make_function without a compile-time -// check that the size of kw is no greater than the expected arity of -// F. This version is needed when defining functions with default -// arguments, because compile-time information about the number of -// keywords is missing for all but the initial function definition. -template -object make_keyword_range_function(F f, Policies const& policies, keyword_range const& kw) -{ - return detail::make_function_aux( - f, policies, args_from_python(), detail::get_signature(f), kw, mpl::int_<0>()); -} - -// Builds an '__init__' function which inserts the given Holder type -// in a wrapped C++ class instance. ArgList is an MPL type sequence -// describing the C++ argument types to be passed to Holder's -// constructor. -// -// Holder and ArgList are intended to be explicitly specified. -template -object make_keyword_range_constructor( - CallPolicies const& policies // The CallPolicies with which to invoke the Holder's constructor - , detail::keyword_range const& kw // The (possibly empty) set of associated argument keywords - , Holder* = 0 - , ArgList* = 0) -{ - BOOST_STATIC_CONSTANT(unsigned, arity = mpl::size::value); - - return detail::make_keyword_range_function( - objects::make_holder - ::template apply::execute - , policies - , kw); -} - -}}} // namespace boost::python::detail - -#endif // MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP diff --git a/include/boost/python/detail/make_tuple.hpp b/include/boost/python/detail/make_tuple.hpp deleted file mode 100644 index 399498bc..00000000 --- a/include/boost/python/detail/make_tuple.hpp +++ /dev/null @@ -1,33 +0,0 @@ -# ifndef BOOST_PYTHON_SYNOPSIS -# // Copyright David Abrahams 2002. Permission to copy, use, -# // modify, sell and distribute this software is granted provided this -# // copyright notice appears in all copies. This software is provided -# // "as is" without express or implied warranty, and with no claim as -# // to its suitability for any purpose. - -# if !defined(BOOST_PP_IS_ITERATING) -# error Boost.Python - do not include this file! -# endif - -# define N BOOST_PP_ITERATION() - -# define BOOST_PYTHON_MAKE_TUPLE_ARG(z, N, ignored) \ - PyTuple_SET_ITEM( \ - result.ptr() \ - , N \ - , python::incref(python::object(a##N).ptr()) \ - ); - - template - tuple - make_tuple(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)) - { - tuple result((detail::new_reference)::PyTuple_New(N)); - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_MAKE_TUPLE_ARG, _) - return result; - } - -# undef BOOST_PYTHON_MAKE_TUPLE_ARG - -# undef N -# endif // BOOST_PYTHON_SYNOPSIS diff --git a/include/boost/python/detail/map_entry.hpp b/include/boost/python/detail/map_entry.hpp deleted file mode 100644 index 9249523a..00000000 --- a/include/boost/python/detail/map_entry.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MAP_ENTRY_DWA2002118_HPP -# define MAP_ENTRY_DWA2002118_HPP - -namespace boost { namespace python { namespace detail { - -// A trivial type that works well as the value_type of associative -// vector maps -template -struct map_entry -{ - map_entry() {} - map_entry(Key k) : key(k), value() {} - map_entry(Key k, Value v) : key(k), value(v) {} - - bool operator<(map_entry const& rhs) const - { - return this->key < rhs.key; - } - - Key key; - Value value; -}; - -template -bool operator<(map_entry const& e, Key const& k) -{ - return e.key < k; -} - -template -bool operator<(Key const& k, map_entry const& e) -{ - return k < e.key; -} - - -}}} // namespace boost::python::detail - -#endif // MAP_ENTRY_DWA2002118_HPP diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp deleted file mode 100644 index 568c13cc..00000000 --- a/include/boost/python/detail/member_function_cast.hpp +++ /dev/null @@ -1,118 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef MEMBER_FUNCTION_CAST_DWA2002311_HPP -# define MEMBER_FUNCTION_CAST_DWA2002311_HPP - -# include - -# include -# include - -# include -# include -# include - -# include -# include - -namespace boost { namespace python { namespace detail { - -template -struct cast_helper -{ - struct yes_helper - { - static FT stage3(FT x) { return x; } - }; - - struct no_helper - { - template - static T stage3(T x) { return x; } - }; - - static yes_helper stage2(S*) { return yes_helper(); } - static no_helper stage2(void*) { return no_helper(); } -}; - -struct non_member_function_cast_impl -{ - template - static non_member_function_cast_impl stage1(T) { return non_member_function_cast_impl(); } - - template - static non_member_function_cast_impl stage2(T) { return non_member_function_cast_impl(); } - - template - T stage3(T x) { return x; } -}; - -template -struct member_function_cast_impl -{ -# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - template - static non_member_function_cast_impl stage1(U) - { - return non_member_function_cast_impl(); - } -# endif - -// Member functions -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, )) -# include BOOST_PP_ITERATE() -}; - -template -struct member_function_cast -# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - : member_function_cast_impl -# else - : mpl::if_c< - is_member_function_pointer::value - , member_function_cast_impl - , non_member_function_cast_impl - >::type -# endif -{ -}; - -}}} // namespace boost::python::detail - -# endif // MEMBER_FUNCTION_CAST_DWA2002311_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -// outer over cv-qualifiers - -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 -# line BOOST_PP_LINE(__LINE__, member_function_cast.hpp) -// inner over arities - -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) -# define P BOOST_PP_ENUM_PARAMS_Z(1, N, A) - - template < - class S, class R - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > - static cast_helper - stage1(R (S::*)( P ) Q) - { - return cast_helper(); - } - -# undef P -# undef N -# undef Q - -#endif diff --git a/include/boost/python/detail/mpl_lambda.hpp b/include/boost/python/detail/mpl_lambda.hpp deleted file mode 100644 index 953bca63..00000000 --- a/include/boost/python/detail/mpl_lambda.hpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MPL_LAMBDA_DWA2002122_HPP -# define MPL_LAMBDA_DWA2002122_HPP - -// this header should go away soon -# include -# define BOOST_PYTHON_MPL_LAMBDA_SUPPORT BOOST_MPL_AUX_LAMBDA_SUPPORT - -#endif // MPL_LAMBDA_DWA2002122_HPP diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp deleted file mode 100644 index 0139984b..00000000 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MSVC_TYPEINFO_DWA200222_HPP -# define MSVC_TYPEINFO_DWA200222_HPP - -#include -#include -#include - -// -// Fix for MSVC's broken typeid() implementation which doesn't strip -// decoration. This fix doesn't handle cv-qualified array types. It -// could probably be done, but I haven't figured it out yet. -// - -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 700 - -namespace boost { namespace python { namespace detail { - -typedef std::type_info const& typeinfo; - -template -static typeinfo typeid_nonref(T const volatile*) { return typeid(T); } - -template -inline typeinfo typeid_ref_1(T&(*)()) -{ - return detail::typeid_nonref((T*)0); -} - -// A non-reference -template -inline typeinfo typeid_ref(type*, T&(*)(type)) -{ - return detail::typeid_nonref((T*)0); -} - -// A reference -template -inline typeinfo typeid_ref(type*, ...) -{ - return detail::typeid_ref_1((T(*)())0); -} - -template< typename T > T&(* is_ref_tester1(type) )(type) { return 0; } -inline char BOOST_TT_DECL is_ref_tester1(...) { return 0; } - -template -inline typeinfo msvc_typeid(boost::type* = 0) -{ - return detail::typeid_ref( - (boost::type*)0, detail::is_ref_tester1(type()) - ); -} - -# ifndef NDEBUG -inline typeinfo assert_array_typeid_compiles() -{ - return msvc_typeid(), msvc_typeid(); -} -# endif - -}}} // namespace boost::python::detail - -# endif // BOOST_MSVC -#endif // MSVC_TYPEINFO_DWA200222_HPP diff --git a/include/boost/python/detail/none.hpp b/include/boost/python/detail/none.hpp deleted file mode 100644 index 8cb21004..00000000 --- a/include/boost/python/detail/none.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef NONE_DWA_052000_H_ -# define NONE_DWA_052000_H_ - -# include -# include - -namespace boost { namespace python { namespace detail { - -inline PyObject* none() { Py_INCREF(Py_None); return Py_None; } - -}}} // namespace boost::python::detail - -#endif // NONE_DWA_052000_H_ diff --git a/include/boost/python/detail/not_specified.hpp b/include/boost/python/detail/not_specified.hpp deleted file mode 100644 index ce1b280d..00000000 --- a/include/boost/python/detail/not_specified.hpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef NOT_SPECIFIED_DWA2002321_HPP -# define NOT_SPECIFIED_DWA2002321_HPP - -namespace boost { namespace python { namespace detail { - - struct not_specified {}; - -}}} // namespace boost::python::detail - -#endif // NOT_SPECIFIED_DWA2002321_HPP diff --git a/include/boost/python/detail/operator_id.hpp b/include/boost/python/detail/operator_id.hpp deleted file mode 100755 index 8edb310b..00000000 --- a/include/boost/python/detail/operator_id.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OPERATOR_ID_DWA2002531_HPP -# define OPERATOR_ID_DWA2002531_HPP - -namespace boost { namespace python { namespace detail { - -enum operator_id -{ - op_add, - op_sub, - op_mul, - op_div, - op_mod, - op_divmod, - op_pow, - op_lshift, - op_rshift, - op_and, - op_xor, - op_or, - op_neg, - op_pos, - op_abs, - op_invert, - op_int, - op_long, - op_float, - op_str, - op_cmp, - op_gt, - op_ge, - op_lt, - op_le, - op_eq, - op_ne, - op_iadd, - op_isub, - op_imul, - op_idiv, - op_imod, - op_ilshift, - op_irshift, - op_iand, - op_ixor, - op_ior, - op_complex -}; - -}}} // namespace boost::python::detail - -#endif // OPERATOR_ID_DWA2002531_HPP diff --git a/include/boost/python/detail/overloads_fwd.hpp b/include/boost/python/detail/overloads_fwd.hpp deleted file mode 100644 index 94ec503f..00000000 --- a/include/boost/python/detail/overloads_fwd.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OVERLOADS_FWD_DWA2002101_HPP -# define OVERLOADS_FWD_DWA2002101_HPP - -namespace boost { namespace python { namespace detail { - -// forward declarations -struct overloads_base; - -template -inline void define_with_defaults(char const* name, OverloadsT const&, NameSpaceT&, SigT const&); - -}}} // namespace boost::python::detail - -#endif // OVERLOADS_FWD_DWA2002101_HPP diff --git a/include/boost/python/detail/pointee.hpp b/include/boost/python/detail/pointee.hpp deleted file mode 100644 index 2af1535f..00000000 --- a/include/boost/python/detail/pointee.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef POINTEE_DWA2002323_HPP -# define POINTEE_DWA2002323_HPP - -# include - -namespace boost { namespace python { namespace detail { - -template -struct pointee_impl -{ - template struct apply : remove_pointer {}; -}; - -template <> -struct pointee_impl -{ - template struct apply - { - typedef typename T::element_type type; - }; -}; - -template -struct pointee - : pointee_impl::value>::template apply -{ -}; - -}}} // namespace boost::python::detail - -#endif // POINTEE_DWA2002323_HPP diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp deleted file mode 100644 index 45e307d4..00000000 --- a/include/boost/python/detail/preprocessor.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PREPROCESSOR_DWA200247_HPP -# define PREPROCESSOR_DWA200247_HPP - -# include -# include -# include -# include - -// stuff that should be in the preprocessor library - -# define BOOST_PYTHON_APPLY(x) BOOST_PP_CAT(BOOST_PYTHON_APPLY_, x) - -# define BOOST_PYTHON_APPLY_BOOST_PYTHON_ITEM(v) v -# define BOOST_PYTHON_APPLY_BOOST_PYTHON_NIL - -// cv-qualifiers - -# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -# define BOOST_PYTHON_CV_COUNT 4 -# else -# define BOOST_PYTHON_CV_COUNT 1 -# endif - -# ifndef BOOST_PYTHON_MAX_ARITY -# define BOOST_PYTHON_MAX_ARITY 15 -# endif - -# ifndef BOOST_PYTHON_MAX_BASES -# define BOOST_PYTHON_MAX_BASES 10 -# endif - -# define BOOST_PYTHON_CV_QUALIFIER(i) \ - BOOST_PYTHON_APPLY( \ - BOOST_PP_TUPLE_ELEM(4, i, BOOST_PYTHON_CV_QUALIFIER_I) \ - ) - -# define BOOST_PYTHON_CV_QUALIFIER_I \ - ( \ - BOOST_PYTHON_NIL, \ - BOOST_PYTHON_ITEM(const), \ - BOOST_PYTHON_ITEM(volatile), \ - BOOST_PYTHON_ITEM(const volatile) \ - ) - -// enumerators -# define BOOST_PYTHON_UNARY_ENUM(c, text) BOOST_PP_REPEAT(c, BOOST_PYTHON_UNARY_ENUM_I, text) -# define BOOST_PYTHON_UNARY_ENUM_I(z, n, text) BOOST_PP_COMMA_IF(n) text ## n - -# define BOOST_PYTHON_BINARY_ENUM(c, a, b) BOOST_PP_REPEAT(c, BOOST_PYTHON_BINARY_ENUM_I, (a, b)) -# define BOOST_PYTHON_BINARY_ENUM_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, _), n) - -# define BOOST_PYTHON_ENUM_WITH_DEFAULT(c, text, def) BOOST_PP_REPEAT(c, BOOST_PYTHON_ENUM_WITH_DEFAULT_I, (text, def)) -# define BOOST_PYTHON_ENUM_WITH_DEFAULT_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) = BOOST_PP_TUPLE_ELEM(2, 1, _) - -// fixed text (no commas) -# define BOOST_PYTHON_FIXED(z, n, text) text - -// flags -# define BOOST_PYTHON_FUNCTION_POINTER 0x0001 -# define BOOST_PYTHON_POINTER_TO_MEMBER 0x0002 - -#endif // PREPROCESSOR_DWA200247_HPP diff --git a/include/boost/python/detail/python22_fixed.h b/include/boost/python/detail/python22_fixed.h deleted file mode 100644 index 74ba44e4..00000000 --- a/include/boost/python/detail/python22_fixed.h +++ /dev/null @@ -1,150 +0,0 @@ -// This file is a modified version of Python 2.2/2.2.1 Python.h. As -// such it is: -// -// Copyright (c) 2001, 2002 Python Software Foundation; All Rights -// Reserved -// -// Changes from the original: -// 1. #includes for Python 2.2.1 -// 2. Provides missing extern "C" wrapper for "iterobject.h" and "descrobject.h". -// - -// Changes marked with "Boost.Python modification" -#ifndef Py_PYTHON_H -#define Py_PYTHON_H -/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ - - -/* Enable compiler features; switching on C lib defines doesn't work - here, because the symbols haven't necessarily been defined yet. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -/* Forcing SUSv2 compatibility still produces problems on some - platforms, True64 and SGI IRIX begin two of them, so for now the - define is switched off. */ -#if 0 -#ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 500 -#endif -#endif - -/* Include nearly all Python header files */ - -#include "patchlevel.h" -#include "pyconfig.h" - -#ifdef HAVE_LIMITS_H -#include -#endif - -/* pyconfig.h may or may not define DL_IMPORT */ -#ifndef DL_IMPORT /* declarations for DLL import/export */ -#define DL_IMPORT(RTYPE) RTYPE -#endif -#ifndef DL_EXPORT /* declarations for DLL import/export */ -#define DL_EXPORT(RTYPE) RTYPE -#endif - -#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) -#define _SGI_MP_SOURCE -#endif - -#include -#ifndef NULL -# error "Python.h requires that stdio.h define NULL." -#endif - -#include -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#if PY_MICRO_VERSION == 1 // Boost.Python modification: emulate Python 2.2 -#ifdef HAVE_UNISTD_H -#include -#endif -#endif // Boost.Python modification: emulate Python 2.2 - -/* CAUTION: Build setups should ensure that NDEBUG is defined on the - * compiler command line when building Python in release mode; else - * assert() calls won't be removed. - */ -#include - -#include "pyport.h" - -#include "pymem.h" - -#include "object.h" -#include "objimpl.h" - -#include "pydebug.h" - -#include "unicodeobject.h" -#include "intobject.h" -#include "longobject.h" -#include "floatobject.h" -#ifndef WITHOUT_COMPLEX -#include "complexobject.h" -#endif -#include "rangeobject.h" -#include "stringobject.h" -#include "bufferobject.h" -#include "tupleobject.h" -#include "listobject.h" -#include "dictobject.h" -#include "methodobject.h" -#include "moduleobject.h" -#include "funcobject.h" -#include "classobject.h" -#include "fileobject.h" -#include "cobject.h" -#include "traceback.h" -#include "sliceobject.h" -#include "cellobject.h" -extern "C" { // Boost.Python modification: provide missing extern "C" -#include "iterobject.h" -#include "descrobject.h" -} // Boost.Python modification: provide missing extern "C" -#include "weakrefobject.h" - -#include "codecs.h" -#include "pyerrors.h" - -#include "pystate.h" - -#include "modsupport.h" -#include "pythonrun.h" -#include "ceval.h" -#include "sysmodule.h" -#include "intrcheck.h" -#include "import.h" - -#include "abstract.h" - -#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a)) -#define PyArg_NoArgs(v) PyArg_Parse(v, "") - -/* Convert a possibly signed character to a nonnegative int */ -/* XXX This assumes characters are 8 bits wide */ -#ifdef __CHAR_UNSIGNED__ -#define Py_CHARMASK(c) (c) -#else -#define Py_CHARMASK(c) ((c) & 0xff) -#endif - -#include "pyfpe.h" - -/* These definitions must match corresponding definitions in graminit.h. - There's code in compile.c that checks that they are the same. */ -#define Py_single_input 256 -#define Py_file_input 257 -#define Py_eval_input 258 - -#ifdef HAVE_PTH -/* GNU pth user-space thread support */ -#include -#endif -#endif /* !Py_PYTHON_H */ diff --git a/include/boost/python/detail/raw_pyobject.hpp b/include/boost/python/detail/raw_pyobject.hpp deleted file mode 100644 index e9d36901..00000000 --- a/include/boost/python/detail/raw_pyobject.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef RAW_PYOBJECT_DWA2002628_HPP -# define RAW_PYOBJECT_DWA2002628_HPP - -namespace boost { namespace python { namespace detail { - -// -// Define some types which we can use to get around the vagaries of -// PyObject*. We will use these to initialize object instances, and -// keep them in namespace detail to make sure they stay out of the -// hands of users. That is much simpler than trying to grant -// friendship to all the appropriate parties. -// - -// New references are normally checked for null -struct new_reference_t; -typedef new_reference_t* new_reference; - -// Borrowed references are assumed to be non-null -struct borrowed_reference_t; -typedef borrowed_reference_t* borrowed_reference; - -// New references which aren't checked for null -struct new_non_null_reference_t; -typedef new_non_null_reference_t* new_non_null_reference; - -}}} // namespace boost::python::detail - -#endif // RAW_PYOBJECT_DWA2002628_HPP diff --git a/include/boost/python/detail/referent_storage.hpp b/include/boost/python/detail/referent_storage.hpp deleted file mode 100644 index b93d888f..00000000 --- a/include/boost/python/detail/referent_storage.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REFERENT_STORAGE_DWA200278_HPP -# define REFERENT_STORAGE_DWA200278_HPP -# include -# include - -namespace boost { namespace python { namespace detail { - -struct alignment_dummy; -typedef void (*function_ptr)(); -typedef int (alignment_dummy::*member_ptr); -typedef int (alignment_dummy::*member_function_ptr)(); - -# define BOOST_PYTHON_ALIGNER(T, n) \ - typename mpl::if_c< \ - sizeof(T) <= size, T, char>::type t##n - -// Storage for size bytes, aligned to all fundamental types no larger than size -template -union aligned_storage -{ - BOOST_PYTHON_ALIGNER(char, 0); - BOOST_PYTHON_ALIGNER(short, 1); - BOOST_PYTHON_ALIGNER(int, 2); - BOOST_PYTHON_ALIGNER(long, 3); - BOOST_PYTHON_ALIGNER(float, 4); - BOOST_PYTHON_ALIGNER(double, 5); - BOOST_PYTHON_ALIGNER(long double, 6); - BOOST_PYTHON_ALIGNER(void*, 7); - BOOST_PYTHON_ALIGNER(function_ptr, 8); - BOOST_PYTHON_ALIGNER(member_ptr, 9); - BOOST_PYTHON_ALIGNER(member_function_ptr, 10); - char bytes[size]; -}; - -# undef BOOST_PYTHON_ALIGNER - - // Compute the size of T's referent. We wouldn't need this at all, - // but sizeof() is broken in CodeWarriors <= 8.0 - template struct referent_size; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct referent_size - { - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(T)); - }; - -# else - - template struct referent_size - { - static T f(); - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f())); - }; - -# endif - -// A metafunction returning a POD type which can store U, where T == -// U&. If T is not a reference type, returns a POD which can store T. -template -struct referent_storage -{ - typedef aligned_storage::value> type; -}; - -}}} // namespace boost::python::detail - -#endif // REFERENT_STORAGE_DWA200278_HPP diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp deleted file mode 100755 index bb66f13a..00000000 --- a/include/boost/python/detail/result.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef RESULT_DWA2002521_HPP -# define RESULT_DWA2002521_HPP - -# include - -# include - -# include -# include - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// Defines a family of overloaded function which, given x, a function -// pointer, member [function] pointer, or an AdaptableFunction object, -// returns a pointer to type*, where R is the result type of -// invoking the result of bind(x). -// -// In order to work around bugs in deficient compilers, if x might be -// an AdaptableFunction object, you must pass OL as a second argument -// to get this to work portably. - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) -# include BOOST_PP_ITERATE() - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) -# include BOOST_PP_ITERATE() - -template -boost::type* result(R (T::*), int = 0) { return 0; } - -# if (defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140) \ - || (defined(__GNUC__) && __GNUC__ < 3) \ - || (defined(__MWERKS__) && __MWERKS__ < 0x3000) -// This code actually works on all implementations, but why use it when we don't have to? -template -struct get_result_type -{ - typedef boost::type type; -}; - -struct void_type -{ - typedef void type; -}; - -template -struct result_result -{ - typedef typename mpl::if_c< - is_class::value - , get_result_type - , void_type - >::type t1; - - typedef typename t1::type* type; -}; - -template -typename result_result::type -result(X const&, short) { return 0; } - -# else // Simpler code for more-capable compilers -template -boost::type* -result(X const&, short = 0) { return 0; } - -# endif - -}}} // namespace boost::python::detail - -# endif // RESULT_DWA2002521_HPP - -/* --------------- function pointers --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER -# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers)) - -# define N BOOST_PP_ITERATION() - -template -boost::type* result(R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)), int = 0) -{ - return 0; -} - -# undef N - -/* --------------- pointers-to-members --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER -// Outer over cv-qualifiers - -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 -# line BOOST_PP_LINE(__LINE__, result.hpp(pointers-to-members)) -// Inner over arities - -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) - -template -boost::type* result(R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q, int = 0) -{ - return 0; -} - -# undef N -# undef Q - -#endif diff --git a/include/boost/python/detail/scope.hpp b/include/boost/python/detail/scope.hpp deleted file mode 100644 index 94528fa1..00000000 --- a/include/boost/python/detail/scope.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SCOPE_DWA2002927_HPP -# define SCOPE_DWA2002927_HPP - -# include - -namespace boost { namespace python { namespace detail { - -void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc); - -}}} // namespace boost::python::detail - -#endif // SCOPE_DWA2002927_HPP diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp deleted file mode 100644 index ee8cc0b6..00000000 --- a/include/boost/python/detail/string_literal.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef STRING_LITERAL_DWA2002629_HPP -# define STRING_LITERAL_DWA2002629_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_string_literal : mpl::false_ -{ -}; - -# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -template -struct is_string_literal : mpl::true_ -{ -}; - -# if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) \ - || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) -// This compiler mistakenly gets the type of string literals as char* -// instead of char[NN]. -template <> -struct is_string_literal : mpl::true_ -{ -}; -# endif - -# else - -// CWPro7 has trouble with the array type deduction above -template -struct is_string_literal - : is_same -{ -}; -# endif -# else -template -struct string_literal_helper -{ - typedef char (&yes_string_literal)[1]; - typedef char (&no_string_literal)[2]; - - template - struct apply - { - typedef apply self; - static T x; - static yes_string_literal check(char const*); - static no_string_literal check(char*); - static no_string_literal check(void const volatile*); - - BOOST_STATIC_CONSTANT( - bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal)); - typedef mpl::bool_ type; - }; -}; - -template <> -struct string_literal_helper -{ - template - struct apply : mpl::false_ - { - }; -}; - -template -struct is_string_literal - : string_literal_helper::value>::apply -{ -}; -# endif - -}}} // namespace boost::python::detail - -#endif // STRING_LITERAL_DWA2002629_HPP diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp deleted file mode 100644 index 67007720..00000000 --- a/include/boost/python/detail/target.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef TARGET_DWA2002521_HPP -# define TARGET_DWA2002521_HPP - -# include - -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) -# include BOOST_PP_ITERATE() - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) -# include BOOST_PP_ITERATE() - -template -boost::type* target(R (T::*)) { return 0; } - -}}} // namespace boost::python::detail - -# endif // TARGET_DWA2002521_HPP - -/* --------------- function pointers --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER -# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers)) - -# define N BOOST_PP_ITERATION() - -template -boost::type* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))) -{ - return 0; -} - -# undef N - -/* --------------- pointers-to-members --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER -// Outer over cv-qualifiers - -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 -# line BOOST_PP_LINE(__LINE__, target.hpp(pointers-to-members)) -// Inner over arities - -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) - -template -boost::type* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) -{ - return 0; -} - -# undef N -# undef Q - -#endif diff --git a/include/boost/python/detail/translate_exception.hpp b/include/boost/python/detail/translate_exception.hpp deleted file mode 100644 index 62f931a5..00000000 --- a/include/boost/python/detail/translate_exception.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TRANSLATE_EXCEPTION_DWA2002810_HPP -# define TRANSLATE_EXCEPTION_DWA2002810_HPP - -# include - -# include -# include - -# include - -namespace boost { namespace python { namespace detail { - -// A ternary function object used to translate C++ exceptions of type -// ExceptionType into Python exceptions by invoking an object of type -// Translate. Typically the translate function will be curried with -// boost::bind(). -template -struct translate_exception -{ - typedef typename add_reference< - typename add_const::type - >::type exception_cref; - - inline bool operator()( - exception_handler const& handler - , function0 const& f - , typename call_traits::param_type translate) const - { - try - { - return handler(f); - } - catch(exception_cref e) - { - translate(e); - return true; - } - } -}; - -}}} // namespace boost::python::detail - -#endif // TRANSLATE_EXCEPTION_DWA2002810_HPP diff --git a/include/boost/python/detail/type_list.hpp b/include/boost/python/detail/type_list.hpp deleted file mode 100644 index 4a09c0be..00000000 --- a/include/boost/python/detail/type_list.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TYPE_LIST_DWA2002913_HPP -# define TYPE_LIST_DWA2002913_HPP - -# include -# include -# include - -# if BOOST_PYTHON_MAX_ARITY + 2 > BOOST_PYTHON_MAX_BASES -# define BOOST_PYTHON_LIST_SIZE BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY)) -# else -# define BOOST_PYTHON_BASE_LIST_SIZE BOOST_PYTHON_MAX_BASES -# endif - -// Compute the MPL list header to use for lists up to BOOST_PYTHON_LIST_SIZE in length -# if BOOST_PYTHON_LIST_SIZE > 48 -# error Arities above 48 not supported by Boost.Python due to MPL internal limit -# elif BOOST_PYTHON_LIST_SIZE > 38 -# include -# elif BOOST_PYTHON_LIST_SIZE > 28 -# include -# elif BOOST_PYTHON_LIST_SIZE > 18 -# include -# elif BOOST_PYTHON_LIST_SIZE > 8 -# include -# else -# include -# endif - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# include -# else -# include -# endif - -#endif // TYPE_LIST_DWA2002913_HPP diff --git a/include/boost/python/detail/type_list_impl.hpp b/include/boost/python/detail/type_list_impl.hpp deleted file mode 100644 index 50ab2446..00000000 --- a/include/boost/python/detail/type_list_impl.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef BOOST_PP_IS_ITERATING -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -# ifndef TYPE_LIST_IMPL_DWA2002913_HPP -# define TYPE_LIST_IMPL_DWA2002913_HPP - -# include - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -template -struct type_list - : BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE) -{ -}; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PP_DEC(BOOST_PYTHON_LIST_SIZE), )) -# include BOOST_PP_ITERATE() - - -}}} // namespace boost::python::detail - -# endif // TYPE_LIST_IMPL_DWA2002913_HPP - -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define BOOST_PYTHON_VOID_ARGS BOOST_PP_SUB_D(1,BOOST_PYTHON_LIST_SIZE,N) - -template < - BOOST_PP_ENUM_PARAMS_Z(1, N, class T) - > -struct type_list< - BOOST_PP_ENUM_PARAMS_Z(1, N, T) - BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM( - BOOST_PYTHON_VOID_ARGS, BOOST_PYTHON_FIXED, mpl::void_) - > - : BOOST_PP_CAT(mpl::list,N) -{ -}; - -# undef BOOST_PYTHON_VOID_ARGS -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp deleted file mode 100644 index 7c9d7fab..00000000 --- a/include/boost/python/detail/type_list_impl_no_pts.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef BOOST_PP_IS_ITERATING -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -# ifndef TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP -# define TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP - -# include - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -template< typename T > -struct is_list_arg -{ - enum { value = true }; -}; - -template<> -struct is_list_arg -{ - enum { value = false }; -}; - -template struct type_list_impl_chooser; - -# define BOOST_PYTHON_LIST_ACTUAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,T) -# define BOOST_PYTHON_LIST_FORMAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,class T) - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_LIST_SIZE, )) -# include BOOST_PP_ITERATE() - -# define BOOST_PYTHON_PLUS() + -# define BOOST_PYTHON_IS_LIST_ARG(z, n, data) \ - BOOST_PP_IF(n, BOOST_PYTHON_PLUS, BOOST_PP_EMPTY)() \ - is_list_arg< BOOST_PP_CAT(T,n) >::value - -template< - BOOST_PYTHON_LIST_FORMAL_PARAMS - > -struct type_list_count_args -{ - enum { value = - BOOST_PP_REPEAT_1(BOOST_PYTHON_LIST_SIZE, BOOST_PYTHON_IS_LIST_ARG, _) - }; -}; - -template< - BOOST_PYTHON_LIST_FORMAL_PARAMS - > -struct type_list_impl -{ - typedef type_list_count_args< BOOST_PYTHON_LIST_ACTUAL_PARAMS > arg_num_; - typedef typename detail::type_list_impl_chooser< arg_num_::value > - ::template result_< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type type; -}; - -template< - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_) - > -struct type_list - : detail::type_list_impl< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type -{ - typedef typename detail::type_list_impl< - BOOST_PYTHON_LIST_ACTUAL_PARAMS - >::type type; -}; - -# undef BOOST_PYTHON_IS_LIST_ARG -# undef BOOST_PYTHON_PLUS -# undef BOOST_PYTHON_LIST_FORMAL_PARAMS -# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS - -}}} // namespace boost::python::detail - -# endif // TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP - -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() - -template<> -struct type_list_impl_chooser -{ - template< - BOOST_PYTHON_LIST_FORMAL_PARAMS - > - struct result_ - { - typedef typename BOOST_PP_CAT(mpl::list,N)< - BOOST_PP_ENUM_PARAMS(N, T) - >::type type; - }; -}; - -# undef N - -#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp deleted file mode 100644 index 878b6cc1..00000000 --- a/include/boost/python/detail/unwind_type.hpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef UNWIND_TYPE_DWA200222_HPP -# define UNWIND_TYPE_DWA200222_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -template -inline typename Generator::result_type -unwind_type_cv(U* p, cv_unqualified, Generator* = 0) -{ - return Generator::execute(p); -} - -template -inline typename Generator::result_type -unwind_type_cv(U const* p, const_, Generator* = 0) -{ - return unwind_type(const_cast(p), (Generator*)0); -} - -template -inline typename Generator::result_type -unwind_type_cv(U volatile* p, volatile_, Generator* = 0) -{ - return unwind_type(const_cast(p), (Generator*)0); -} - -template -inline typename Generator::result_type -unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0) -{ - return unwind_type(const_cast(p), (Generator*)0); -} - -template -inline typename Generator::result_type -unwind_ptr_type(U* p, Generator* = 0) -{ - typedef typename cv_category::type tag; - return unwind_type_cv(p, tag()); -} - -template -struct unwind_helper -{ - template - static typename Generator::result_type - execute(U p, Generator* = 0) - { - return unwind_ptr_type(p, (Generator*)0); - } -}; - -template <> -struct unwind_helper -{ - template - static typename Generator::result_type - execute(U& p, Generator* = 0) - { - return unwind_ptr_type(&p, (Generator*)0); - } -}; - -template -inline typename Generator::result_type -unwind_type(U const& p, Generator* = 0) -{ - return unwind_helper::value>::execute(p, (Generator*)0); -} - -enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 }; -template struct unwind_helper2; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U(*)(), Generator* = 0) - { - return unwind_ptr_type((U*)0, (Generator*)0); - } -}; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U*(*)(), Generator* = 0) - { - return unwind_ptr_type((U*)0, (Generator*)0); - } -}; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U&(*)(), Generator* = 0) - { - return unwind_ptr_type((U*)0, (Generator*)0); - } -}; - -template <> -struct unwind_helper2 -{ - template - static typename Generator::result_type - execute(U&(*)(), Generator* = 0) - { - return unwind_ptr_type(U(0), (Generator*)0); - } -}; - -// Call this one with both template parameters explicitly specified -// and no function arguments: -// -// return unwind_type(); -// -// Doesn't work if T is an array type; we could handle that case, but -// why bother? -template -inline typename Generator::result_type -unwind_type(boost::type*p = 0, Generator* = 0) -{ - BOOST_STATIC_CONSTANT(int, indirection - = (is_pointer::value ? pointer_ : 0) - + (is_reference_to_pointer::value - ? reference_to_pointer_ - : is_reference::value - ? reference_ - : 0)); - - return unwind_helper2::execute((U(*)())0,(Generator*)0); -} - -}}} // namespace boost::python::detail - -#endif // UNWIND_TYPE_DWA200222_HPP diff --git a/include/boost/python/detail/value_is_shared_ptr.hpp b/include/boost/python/detail/value_is_shared_ptr.hpp deleted file mode 100644 index 5d2c8abe..00000000 --- a/include/boost/python/detail/value_is_shared_ptr.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_IS_SHARED_PTR_DWA2003224_HPP -# define VALUE_IS_SHARED_PTR_DWA2003224_HPP - -# include -# include - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_VALUE_IS_XXX_DEF(shared_ptr, shared_ptr, 1) - -}}} // namespace boost::python::detail - -#endif // VALUE_IS_SHARED_PTR_DWA2003224_HPP diff --git a/include/boost/python/detail/value_is_xxx.hpp b/include/boost/python/detail/value_is_xxx.hpp deleted file mode 100644 index f0a9a11c..00000000 --- a/include/boost/python/detail/value_is_xxx.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_IS_XXX_DWA2003224_HPP -# define VALUE_IS_XXX_DWA2003224_HPP - -# include -# include -# include - -# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -# include -# include - -# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct value_is_##name \ -{ \ - typedef char yes; \ - typedef char (&no)[2]; \ - \ - static typename add_reference::type dummy; \ - \ - template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ - static yes test( \ - qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) > const&, int \ - ); \ - \ - template \ - static no test(U&, ...); \ - \ - BOOST_STATIC_CONSTANT( \ - bool, value \ - = (sizeof(test(dummy, 0)) == sizeof(yes))); \ - \ - typedef mpl::bool_ type; \ -}; - -# else - -# include -# include -# include - -# define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs) \ -template \ -struct value_is_##name \ -{ \ - BOOST_PYTHON_IS_XXX_DEF(name,qualified_name,nargs) \ - BOOST_STATIC_CONSTANT(bool, value = is_##name< \ - typename remove_cv< \ - typename remove_reference::type \ - >::type \ - >::value); \ - typedef mpl::bool_ type; \ - \ -}; - -# endif - -#endif // VALUE_IS_XXX_DWA2003224_HPP diff --git a/include/boost/python/detail/void_ptr.hpp b/include/boost/python/detail/void_ptr.hpp deleted file mode 100644 index 676a5cac..00000000 --- a/include/boost/python/detail/void_ptr.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VOID_PTR_DWA200239_HPP -# define VOID_PTR_DWA200239_HPP - -namespace boost { namespace python { namespace detail { - -template -inline U& void_ptr_to_reference(void const volatile* p, U&(*)()) -{ - return *(U*)p; -} - -template -inline void write_void_ptr(void const volatile* storage, void* ptr, T*) -{ - *(T**)storage = (T*)ptr; -} - -// writes U(ptr) into the storage -template -inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)()) -{ - // stripping CV qualification suppresses warnings on older EDGs - typedef typename remove_cv::type u_stripped; - write_void_ptr(storage, ptr, u_stripped(0)); -} - -}}} // namespace boost::python::detail - -#endif // VOID_PTR_DWA200239_HPP diff --git a/include/boost/python/detail/void_return.hpp b/include/boost/python/detail/void_return.hpp deleted file mode 100644 index 512aa636..00000000 --- a/include/boost/python/detail/void_return.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VOID_RETURN_DWA200274_HPP -# define VOID_RETURN_DWA200274_HPP - -# include - -namespace boost { namespace python { namespace detail { - -struct void_return -{ - void_return() {} - private: - void operator=(void_return const&); -}; - -template -struct returnable -{ - typedef T type; -}; - -# ifdef BOOST_NO_VOID_RETURNS -template <> -struct returnable -{ - typedef void_return type; -}; - -# ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS -template <> struct returnable : returnable {}; -template <> struct returnable : returnable {}; -template <> struct returnable : returnable {}; -# endif - -# endif // BOOST_NO_VOID_RETURNS - -}}} // namespace boost::python::detail - -#endif // VOID_RETURN_DWA200274_HPP diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp deleted file mode 100644 index 6cb8dee2..00000000 --- a/include/boost/python/detail/wrap_python.hpp +++ /dev/null @@ -1,157 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// This file serves as a wrapper around which allows it to be -// compiled with GCC 2.95.2 under Win32 and which disables the default MSVC -// behavior so that a program may be compiled in debug mode without requiring a -// special debugging build of the Python library. - - -// To use the Python debugging library, #define BOOST_DEBUG_PYTHON on the -// compiler command-line. - -// Revision History: -// 05 Mar 01 Suppress warnings under Cygwin with Python 2.0 (Dave Abrahams) -// 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) -// 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) - -// -// Python's LongObject.h helpfully #defines ULONGLONG_MAX for us, -// which confuses Boost's config -// -#include -#ifndef ULONG_MAX -# define BOOST_PYTHON_ULONG_MAX_UNDEFINED -#endif -#ifndef LONGLONG_MAX -# define BOOST_PYTHON_LONGLONG_MAX_UNDEFINED -#endif -#ifndef ULONGLONG_MAX -# define BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED -#endif - -// -// Get ahold of Python's version number -// -#include - -#ifdef _DEBUG -# ifndef BOOST_DEBUG_PYTHON -# undef _DEBUG // Don't let Python force the debug library just because we're debugging. -# define DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H -# endif -#endif - -// -// Some things we need in order to get Python.h to work with compilers other -// than MSVC on Win32 -// -#if defined(_WIN32) || defined(__CYGWIN__) -# if defined(__GNUC__) && defined(__CYGWIN__) - -# define SIZEOF_LONG 4 - -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 - -typedef int pid_t; - -# define WORD_BIT 32 -# define hypot _hypot -# include - -# if PY_MAJOR_VERSION < 2 -# define HAVE_CLOCK -# define HAVE_STRFTIME -# define HAVE_STRERROR -# endif - -# define NT_THREADS - -# ifndef NETSCAPE_PI -# define USE_SOCKET -# endif - -# ifdef USE_DL_IMPORT -# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE -# endif - -# ifdef USE_DL_EXPORT -# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE -# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE -# endif - -# define HAVE_LONG_LONG 1 -# define LONG_LONG long long -# endif - -# elif defined(__MWERKS__) - -# ifndef _MSC_VER -# define PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H 1 -# define _MSC_VER 900 -# endif - -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2 -# include -# else -# include -# endif -# undef hypot // undo the evil #define left by Python. - -# elif defined(__BORLANDC__) -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2 -# include -# else -# include -# endif -# undef HAVE_HYPOT -# define HAVE_HYPOT 1 -# endif - -#endif // _WIN32 - -#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2 && PY_MICRO_VERSION < 2 -# include -#else -# include -#endif - -#ifdef BOOST_PYTHON_ULONG_MAX_UNDEFINED -# undef ULONG_MAX -# undef BOOST_PYTHON_ULONG_MAX_UNDEFINED -#endif - -#ifdef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED -# undef LONGLONG_MAX -# undef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED -#endif - -#ifdef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED -# undef ULONGLONG_MAX -# undef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED -#endif - -#ifdef PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H -# undef _MSC_VER -#endif - -#ifdef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H -# undef DEBUG_UNDEFINED_FROM_WRAP_PYTHON_H -# define _DEBUG -#endif - -#if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 -# define PyObject_INIT(op, typeobj) \ - ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) -#endif - -#ifdef __MWERKS__ -# pragma warn_possunwant off -#elif _MSC_VER -# pragma warning(disable:4786) -#endif diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp deleted file mode 100644 index c1565bcc..00000000 --- a/include/boost/python/dict.hpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef DICT_20020706_HPP -#define DICT_20020706_HPP - -#include -#include -#include -#include - -namespace boost { namespace python { - -class dict; - -namespace detail -{ - struct BOOST_PYTHON_DECL dict_base : object - { - // D.clear() -> None. Remove all items from D. - void clear(); - - // D.copy() -> a shallow copy of D - dict copy(); - - // D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None. - object get(object_cref k) const; - - object get(object_cref k, object_cref d) const; - - // D.has_key(k) -> 1 if D has a key k, else 0 - bool has_key(object_cref k) const; - - // D.items() -> list of D's (key, value) pairs, as 2-tuples - list items() const; - - // D.iteritems() -> an iterator over the (key, value) items of D - object iteritems() const; - - // D.iterkeys() -> an iterator over the keys of D - object iterkeys() const; - - // D.itervalues() -> an iterator over the values of D - object itervalues() const; - - // D.keys() -> list of D's keys - list keys() const; - - // D.popitem() -> (k, v), remove and return some (key, value) pair as a - // 2-tuple; but raise KeyError if D is empty - tuple popitem(); - - // D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k) - object setdefault(object_cref k); - - object setdefault(object_cref k, object_cref d); - - // D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k] - void update(object_cref E); - - // D.values() -> list of D's values - list values() const; - - protected: - // dict() -> new empty dictionary. - // dict(mapping) -> new dictionary initialized from a mapping object's - // (key, value) pairs. - // dict(seq) -> new dictionary initialized as if via: - dict_base(); // new dict - explicit dict_base(object_cref data); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict_base, object) - private: - static detail::new_reference call(object const&); - }; -} - -class dict : public detail::dict_base -{ - typedef detail::dict_base base; - public: - // dict() -> new empty dictionary. - // dict(mapping) -> new dictionary initialized from a mapping object's - // (key, value) pairs. - // dict(seq) -> new dictionary initialized as if via: - dict() {} // new dict - - template - explicit dict(T const& data) - : base(object(data)) - { - } - - template - object get(T const& k) const - { - return base::get(object(k)); - } - - template - object get(T1 const& k, T2 const& d) const - { - return base::get(object(k),object(d)); - } - - template - bool has_key(T const& k) const - { - return base::has_key(object(k)); - } - - template - object setdefault(T const& k) - { - return base::setdefault(object(k)); - } - - template - object setdefault(T1 const& k, T2 const& d) - { - return base::setdefault(object(k),object(d)); - } - - template - void update(T const& E) - { - base::update(object(E)); - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyDict_Type,dict> - { - }; -} - -}} // namespace boost::python - -#endif - diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp deleted file mode 100644 index 02092510..00000000 --- a/include/boost/python/enum.hpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ENUM_DWA200298_HPP -# define ENUM_DWA200298_HPP - -# include -# include -# include - -namespace boost { namespace python { - -template -struct enum_ : public objects::enum_base -{ - typedef objects::enum_base base; - - // Declare a new enumeration type in the current scope() - enum_(char const* name); - - // Add a new enumeration value with the given name and value. - inline enum_& value(char const* name, T); - - // Add all of the defined enumeration values to the current scope with the - // same names used here. - inline enum_& export_values(); - private: - static PyObject* to_python(void const* x); - static void* convertible_from_python(PyObject* obj); - static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data); -}; - -template -inline enum_::enum_(char const* name) - : base( - name - , &enum_::to_python - , &enum_::convertible_from_python - , &enum_::construct - , type_id()) -{ -} - -// This is the conversion function that gets registered for converting -// these enums to Python. -template -PyObject* enum_::to_python(void const* x) -{ - return base::to_python( - converter::registered::converters.m_class_object - , static_cast(*(T const*)x)); -} - -// -// The following two static functions serve as the elements of an -// rvalue from_python converter for the enumeration type. -// - -// This checks that a given Python object can be converted to the -// enumeration type. -template -void* enum_::convertible_from_python(PyObject* obj) -{ - return PyObject_IsInstance( - obj - , upcast( - converter::registered::converters.m_class_object)) - - ? obj : 0; -} - -// Constructs an instance of the enumeration type in the from_python -// data. -template -void enum_::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data) -{ - T x = static_cast(PyInt_AS_LONG(obj)); - void* const storage = ((converter::rvalue_from_python_storage*)data)->storage.bytes; - new (storage) T(x); - data->convertible = storage; -} - -template -inline enum_& enum_::value(char const* name, T x) -{ - this->add_value(name, static_cast(x)); - return *this; -} - -template -inline enum_& enum_::export_values() -{ - this->base::export_values(); - return *this; -} - -}} // namespace boost::python - -#endif // ENUM_DWA200298_HPP diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp deleted file mode 100644 index cd0b3586..00000000 --- a/include/boost/python/errors.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef ERRORS_DWA052500_H_ -# define ERRORS_DWA052500_H_ - -# include -# include -# include - -namespace boost { namespace python { - -struct BOOST_PYTHON_DECL error_already_set {}; -struct BOOST_PYTHON_DECL argument_error : error_already_set {}; - -// Handles exceptions caught just before returning to Python code. -// Returns true iff an exception was caught. -BOOST_PYTHON_DECL bool handle_exception_impl(function0); - -template -bool handle_exception(T f) -{ - return handle_exception_impl(function0(boost::ref(f))); -} - -namespace detail { inline void rethrow() { throw; } } - -inline void handle_exception() -{ - handle_exception(detail::rethrow); -} - -BOOST_PYTHON_DECL void throw_argument_error(); -BOOST_PYTHON_DECL void throw_error_already_set(); - -template -inline T* expect_non_null(T* x) -{ - if (x == 0) - throw_error_already_set(); - return x; -} - -// Return source if it is an instance of pytype; throw an appropriate -// exception otherwise. -BOOST_PYTHON_DECL PyObject* pytype_check(PyTypeObject* pytype, PyObject* source); - -}} // namespace boost::python - -#endif // ERRORS_DWA052500_H_ diff --git a/include/boost/python/exception_translator.hpp b/include/boost/python/exception_translator.hpp deleted file mode 100644 index c7581780..00000000 --- a/include/boost/python/exception_translator.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef EXCEPTION_TRANSLATOR_DWA2002810_HPP -# define EXCEPTION_TRANSLATOR_DWA2002810_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -template -void register_exception_translator(Translate const& translate, boost::type* = 0) -{ - detail::register_exception_handler( - bind(detail::translate_exception(), _1, _2, translate) - ); -} - -}} // namespace boost::python - -#endif // EXCEPTION_TRANSLATOR_DWA2002810_HPP diff --git a/include/boost/python/extract.hpp b/include/boost/python/extract.hpp deleted file mode 100644 index 27a0b60d..00000000 --- a/include/boost/python/extract.hpp +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef EXTRACT_DWA200265_HPP -# define EXTRACT_DWA200265_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace converter -{ - template - struct extract_pointer - { - typedef Ptr result_type; - extract_pointer(PyObject*); - - bool check() const; - Ptr operator()() const; - - private: - PyObject* m_source; - void* m_result; - }; - - template - struct extract_reference - { - typedef Ref result_type; - extract_reference(PyObject*); - - bool check() const; - Ref operator()() const; - - private: - PyObject* m_source; - void* m_result; - }; - - template - struct extract_rvalue : private noncopyable - { - typedef typename mpl::if_< - python::detail::copy_ctor_mutates_rhs - , T& - , typename call_traits::param_type - >::type result_type; - - extract_rvalue(PyObject*); - - bool check() const; - result_type operator()() const; - private: - PyObject* m_source; - mutable rvalue_from_python_data m_data; - }; - - template - struct extract_object_manager - { - typedef T result_type; - extract_object_manager(PyObject*); - - bool check() const; - result_type operator()() const; - private: - PyObject* m_source; - }; - - template - struct select_extract - { - BOOST_STATIC_CONSTANT( - bool, obj_mgr = is_object_manager::value); - - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ref = is_reference::value); - - typedef typename mpl::if_c< - obj_mgr - , extract_object_manager - , typename mpl::if_c< - ptr - , extract_pointer - , typename mpl::if_c< - ref - , extract_reference - , extract_rvalue - >::type - >::type - >::type type; - }; -} - -template -struct extract - : converter::select_extract::type -{ - private: - typedef typename converter::select_extract::type base; - public: - typedef typename base::result_type result_type; - - operator result_type() const - { - return (*this)(); - } - - extract(PyObject*); - extract(object const&); -}; - -// -// Implementations -// -template -inline extract::extract(PyObject* o) - : base(o) -{ -} - -template -inline extract::extract(object const& o) - : base(o.ptr()) -{ -} - -namespace converter -{ - template - inline extract_rvalue::extract_rvalue(PyObject* x) - : m_source(x) - , m_data( - (rvalue_from_python_stage1)(x, registered::converters) - ) - { - } - - template - inline bool - extract_rvalue::check() const - { - return m_data.stage1.convertible; - } - - template - inline typename extract_rvalue::result_type - extract_rvalue::operator()() const - { - return *(T*)( - // Only do the stage2 conversion once - m_data.stage1.convertible == m_data.storage.bytes - ? m_data.storage.bytes - : (rvalue_from_python_stage2)(m_source, m_data.stage1, registered::converters) - ); - } - - template - inline extract_reference::extract_reference(PyObject* obj) - : m_source(obj) - , m_result( - (get_lvalue_from_python)(obj, registered::converters) - ) - { - } - - template - inline bool extract_reference::check() const - { - return m_result != 0; - } - - template - inline Ref extract_reference::operator()() const - { - if (m_result == 0) - (throw_no_reference_from_python)(m_source, registered::converters); - - return python::detail::void_ptr_to_reference(m_result, (Ref(*)())0); - } - - template - inline extract_pointer::extract_pointer(PyObject* obj) - : m_source(obj) - , m_result( - obj == Py_None ? 0 : (get_lvalue_from_python)(obj, registered_pointee::converters) - ) - { - } - - template - inline bool extract_pointer::check() const - { - return m_source == Py_None || m_result != 0; - } - - template - inline Ptr extract_pointer::operator()() const - { - if (m_result == 0 && m_source != Py_None) - (throw_no_pointer_from_python)(m_source, registered_pointee::converters); - - return Ptr(m_result); - } - - template - inline extract_object_manager::extract_object_manager(PyObject* obj) - : m_source(obj) - { - } - - template - inline bool extract_object_manager::check() const - { - return object_manager_traits::check(m_source); - } - - template - inline T extract_object_manager::operator()() const - { - return T( - object_manager_traits::adopt(python::incref(m_source)) - ); - } -} - -}} // namespace boost::python::converter - -#endif // EXTRACT_DWA200265_HPP diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp deleted file mode 100755 index 98534944..00000000 --- a/include/boost/python/handle.hpp +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef HANDLE_DWA200269_HPP -# define HANDLE_DWA200269_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template struct null_ok; - -template -inline null_ok* allow_null(T* p) -{ - return (null_ok*)p; -} - -namespace detail -{ - template - inline T* manage_ptr(detail::borrowed >* p, int) - { - return python::xincref((T*)p); - } - - template - inline T* manage_ptr(null_ok >* p, int) - { - return python::xincref((T*)p); - } - - template - inline T* manage_ptr(detail::borrowed* p, long) - { - return python::incref(expect_non_null((T*)p)); - } - - template - inline T* manage_ptr(null_ok* p, long) - { - return (T*)p; - } - - template - inline T* manage_ptr(T* p, ...) - { - return expect_non_null(p); - } -} - -template -class handle -{ - typedef T* (handle::* bool_type )() const; - - public: // types - typedef T element_type; - - public: // member functions - handle(); - ~handle(); - - template - explicit handle(Y* p) - : m_p( - python::upcast( - detail::manage_ptr(p, 0) - ) - ) - { - } - - handle& operator=(handle const& r); - -#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) - - template - handle& operator=(handle const & r) // never throws - { - python::xdecref(m_p); - m_p = python::xincref(python::upcast(r.get())); - return *this; - } - -#endif - - template - handle(handle const& r) - : m_p(python::xincref(python::upcast(r.get()))) - { - } - - handle(handle const& r) - : m_p(python::xincref(r.m_p)) - { - } - - T* operator-> () const; - T& operator* () const; - T* get() const; - T* release(); - void reset(); - - operator bool_type() const // never throws - { - return m_p ? &handle::get : 0; - } - bool operator! () const; // never throws - - public: // implementation details -- do not touch - // Defining this in the class body suppresses a VC7 link failure - inline handle(detail::borrowed_reference x) - : m_p( - python::incref( - downcast((PyObject*)x) - )) - { - } - - private: // data members - T* m_p; -}; - -typedef handle type_handle; - -// -// Compile-time introspection -// -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class is_handle -{ - public: - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -class is_handle > -{ - public: - BOOST_STATIC_CONSTANT(bool, value = true); -}; -# else -namespace detail -{ - typedef char (&yes_handle_t)[1]; - typedef char (&no_handle_t)[2]; - - no_handle_t is_handle_test(...); - - template - yes_handle_t is_handle_test(boost::type< handle >); -} - -template -class is_handle -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_handle_test(boost::type())) - == sizeof(detail::yes_handle_t))); -}; -# endif - -// -// implementations -// -template -inline handle::handle() - : m_p(0) -{ -} - -template -inline handle::~handle() -{ - python::xdecref(m_p); -} - -template -inline handle& handle::operator=(handle const& r) -{ - python::xdecref(m_p); - m_p = python::xincref(r.m_p); - return *this; -} - -template -inline T* handle::operator->() const -{ - return m_p; -} - -template -inline T& handle::operator*() const -{ - return *m_p; -} - -template -inline T* handle::get() const -{ - return m_p; -} - -template -inline bool handle::operator!() const -{ - return m_p == 0; -} - -template -inline T* handle::release() -{ - T* result = m_p; - m_p = 0; - return result; -} - -template -inline void handle::reset() -{ - python::xdecref(m_p); - m_p = 0; -} - -// Because get_managed_object must return a non-null PyObject*, we -// return Py_None if the handle is null. -template -inline PyObject* get_managed_object(handle const& h, tag_t) -{ - return h.get() ? python::upcast(h.get()) : Py_None; -} - -}} // namespace boost::python - - -#endif // HANDLE_DWA200269_HPP diff --git a/include/boost/python/handle_fwd.hpp b/include/boost/python/handle_fwd.hpp deleted file mode 100755 index afcce163..00000000 --- a/include/boost/python/handle_fwd.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef HANDLE_FWD_DWA2002615_HPP -# define HANDLE_FWD_DWA2002615_HPP - -# include - -namespace boost { namespace python { - -template class handle; - -}} // namespace boost::python - -#endif // HANDLE_FWD_DWA2002615_HPP diff --git a/include/boost/python/has_back_reference.hpp b/include/boost/python/has_back_reference.hpp deleted file mode 100644 index 95a3ae9a..00000000 --- a/include/boost/python/has_back_reference.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef HAS_BACK_REFERENCE_DWA2002323_HPP -# define HAS_BACK_REFERENCE_DWA2002323_HPP - -namespace boost { namespace python { - -// traits class which users can specialize to indicate that a class -// contains a back-reference to its owning PyObject* -template -struct has_back_reference -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - - -}} // namespace boost::python - -#endif // HAS_BACK_REFERENCE_DWA2002323_HPP diff --git a/include/boost/python/implicit.hpp b/include/boost/python/implicit.hpp deleted file mode 100644 index a6e73eba..00000000 --- a/include/boost/python/implicit.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef IMPLICIT_DWA2002325_HPP -# define IMPLICIT_DWA2002325_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -template -void implicitly_convertible(boost::type* = 0, boost::type* = 0) -{ - typedef converter::implicit functions; - - converter::registry::push_back( - &functions::convertible - , &functions::construct - , type_id()); -} - -}} // namespace boost::python - -#endif // IMPLICIT_DWA2002325_HPP diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp deleted file mode 100644 index 39bf4ac7..00000000 --- a/include/boost/python/init.hpp +++ /dev/null @@ -1,446 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, -// use, modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided "as is" -// without express or implied warranty, and with no claim as to its -// suitability for any purpose. -// -/////////////////////////////////////////////////////////////////////////////// -#ifndef INIT_JDG20020820_HPP -#define INIT_JDG20020820_HPP - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -# include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -/////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT \ - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ - BOOST_PYTHON_MAX_ARITY, \ - class T, \ - mpl::void_) \ - -#define BOOST_PYTHON_OVERLOAD_TYPES \ - BOOST_PP_ENUM_PARAMS_Z(1, \ - BOOST_PYTHON_MAX_ARITY, \ - class T) \ - -#define BOOST_PYTHON_OVERLOAD_ARGS \ - BOOST_PP_ENUM_PARAMS_Z(1, \ - BOOST_PYTHON_MAX_ARITY, \ - T) \ - -/////////////////////////////////////////////////////////////////////////////// -namespace boost { namespace python { - -template -class init; // forward declaration - - -template -struct optional; // forward declaration - -namespace detail -{ - namespace error - { - template - struct more_keywords_than_init_arguments - { - typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1]; - }; - } - - /////////////////////////////////////////////////////////////////////////// - // - // is_optional::value - // - // This metaprogram checks if T is an optional - // - /////////////////////////////////////////////////////////////////////////// - #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - - template - struct is_optional { - - private: - - template - static boost::type_traits::yes_type f(optional); - static boost::type_traits::no_type f(...); - static T t(); - - public: - - BOOST_STATIC_CONSTANT( - bool, value = - sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); - typedef mpl::bool_ type; - - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) - }; - - /////////////////////////////////////// - #else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - - template - struct is_optional_impl { - - BOOST_STATIC_CONSTANT(bool, value = false); - }; - - template - struct is_optional_impl > { - - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template - struct is_optional : is_optional_impl - { - typedef mpl::bool_::value> type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) - }; - #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -} // namespace detail - -template -struct init_base -{ - init_base(char const* doc_, detail::keyword_range const& keywords_) - : m_doc(doc_), m_keywords(keywords_) - {} - - init_base(char const* doc_) - : m_doc(doc_) - {} - - DerivedT const& derived() const - { - return *static_cast(this); - } - - char const* doc_string() const - { - return m_doc; - } - - detail::keyword_range const& keywords() const - { - return m_keywords; - } - - static default_call_policies call_policies() - { - return default_call_policies(); - } - - private: // data members - char const* m_doc; - detail::keyword_range m_keywords; -}; - -template -class init_with_call_policies - : public init_base > -{ - typedef init_base > base; - public: - BOOST_STATIC_CONSTANT(int, n_arguments = InitT::n_arguments); - BOOST_STATIC_CONSTANT(int, n_defaults = InitT::n_defaults); - - typedef typename InitT::reversed_args reversed_args; - - init_with_call_policies( - CallPoliciesT const& policies_ - , char const* doc_ - , detail::keyword_range const& keywords - ) - : base(doc_, keywords) - , m_policies(policies_) - {} - - CallPoliciesT const& call_policies() const - { - return this->m_policies; - } - - private: // data members - CallPoliciesT m_policies; -}; - -template -class init : public init_base > -{ - typedef init_base > base; - public: - typedef init self_t; - - init(char const* doc_ = 0) - : base(doc_) - { - } - - template - init(char const* doc_, Keywords const& kw) - : base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size)) - { - typedef typename detail::error::more_keywords_than_init_arguments< - Keywords::size, n_arguments - >::too_many_keywords assertion; - } - - template - init(Keywords const& kw, char const* doc_ = 0) - : base(doc_, kw.range()) - { - typedef typename detail::error::more_keywords_than_init_arguments< - Keywords::size, n_arguments - >::too_many_keywords assertion; - } - - template - init_with_call_policies - operator[](CallPoliciesT const& policies) const - { - return init_with_call_policies( - policies, this->doc_string(), this->keywords()); - } - - typedef detail::type_list signature_; - typedef typename mpl::end::type finish; - - // Find the optional<> element, if any - typedef typename mpl::find_if< - signature_, detail::is_optional - >::type opt; - - - // Check to make sure the optional<> element, if any, is the last one - typedef typename mpl::apply_if< - is_same - , mpl::identity - , mpl::next - >::type expected_finish; - BOOST_STATIC_ASSERT((is_same::value)); - - typedef typename mpl::apply_if< - is_same - , mpl::list0<> - , opt - >::type optional_args; - - // Count the number of default args - BOOST_STATIC_CONSTANT(int, n_defaults = mpl::size::value); - - typedef typename mpl::iterator_range< - typename mpl::begin::type - , opt - >::type required_args; - - // Build a reverse image of all the args, including optionals - typedef typename mpl::fold< - required_args - , mpl::list0<> - , mpl::push_front<> - >::type reversed_required; - - typedef typename mpl::fold< - optional_args - , reversed_required - , mpl::push_front<> - >::type reversed_args; - - // Count the maximum number of arguments - BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); -}; - -/////////////////////////////////////////////////////////////////////////////// -// -// optional -// -// optional::type returns a typelist. -// -/////////////////////////////////////////////////////////////////////////////// -template -struct optional - : detail::type_list -{ -}; - -namespace detail -{ - template - void def_init_reversed( - ClassT& cl - , ReversedArgs const& - , CallPoliciesT const& policies - , char const* doc - , detail::keyword_range const& keywords_ - ) - { - typedef typename mpl::fold< - ReversedArgs - , mpl::list0<> - , mpl::push_front<> - >::type args; - - typedef typename ClassT::holder_selector holder_selector_t; -# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - typedef typename holder_selector_t::type selector_t; -# endif - typedef typename ClassT::held_type held_type_t; - - cl.def( - "__init__", - detail::make_keyword_range_constructor( - policies - , keywords_ -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - // Using runtime type selection works around a CWPro7 bug. - , holder_selector_t::execute((held_type_t*)0).get() -# else - , selector_t::get() -# endif - ) - , doc - ); - } - - /////////////////////////////////////////////////////////////////////////////// - // - // define_class_init_helper::apply - // - // General case - // - // Accepts a class_ and an arguments list. Defines a constructor - // for the class given the arguments and recursively calls - // define_class_init_helper::apply with one less arguments (the - // rightmost argument is shaved off) - // - /////////////////////////////////////////////////////////////////////////////// - template - struct define_class_init_helper { - - template - static void apply( - ClassT& cl - , CallPoliciesT const& policies - , ReversedArgs const& args - , char const* doc - , detail::keyword_range keywords) - { - def_init_reversed(cl, args, policies, doc, keywords); - - if (keywords.second > keywords.first) - --keywords.second; - - typename mpl::pop_front::type next; - define_class_init_helper::apply(cl, policies, next, doc, keywords); - } - }; - - /////////////////////////////////////////////////////////////////////////////// - // - // define_class_init_helper<0>::apply - // - // Terminal case - // - // Accepts a class_ and an arguments list. Defines a constructor - // for the class given the arguments. - // - /////////////////////////////////////////////////////////////////////////////// - template <> - struct define_class_init_helper<0> { - - template - static void apply( - ClassT& cl - , CallPoliciesT const& policies - , ReversedArgs const& args - , char const* doc - , detail::keyword_range const& keywords) - { - def_init_reversed(cl, args, policies, doc, keywords); - } - }; -} - -/////////////////////////////////////////////////////////////////////////////// -// -// define_init -// -// Accepts a class_ and an init-list. Defines a set of constructors for -// the class given the arguments. The init list (see init above) has -// n_defaults (number of default arguments and n_arguments (number of -// actual arguments). This function defines n_defaults + 1 constructors -// for the class. Each constructor after the first has one less argument -// to its right. Example: -// -// init -// -// Defines: -// -// __init__(int, char, long, double) -// __init__(int, char, long) -// __init__(int, char) -// __init__(int) -// -/////////////////////////////////////////////////////////////////////////////// -template -void -define_init(ClassT& cl, InitT const& i) -{ - typedef typename InitT::reversed_args reversed_args; - detail::define_class_init_helper::apply( - cl, i.call_policies(), reversed_args(), i.doc_string(), i.keywords()); -} - -}} // namespace boost::python - -#undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT -#undef BOOST_PYTHON_OVERLOAD_TYPES -#undef BOOST_PYTHON_OVERLOAD_ARGS -#undef BOOST_PYTHON_IS_OPTIONAL_VALUE -#undef BOOST_PYTHON_APPEND_TO_INIT - -/////////////////////////////////////////////////////////////////////////////// -#endif // INIT_JDG20020820_HPP - - - - - - - - diff --git a/include/boost/python/instance_holder.hpp b/include/boost/python/instance_holder.hpp deleted file mode 100755 index 28aa02e8..00000000 --- a/include/boost/python/instance_holder.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef INSTANCE_HOLDER_DWA2002517_HPP -# define INSTANCE_HOLDER_DWA2002517_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -// Base class for all holders -struct BOOST_PYTHON_DECL instance_holder : private noncopyable -{ - public: - instance_holder(); - virtual ~instance_holder(); - - // return the next holder in a chain - instance_holder* next() const; - - virtual void* holds(type_info) = 0; - - void install(PyObject* inst) throw(); - - // These functions should probably be located elsewhere. - - // Allocate storage for an object of the given size at the given - // offset in the Python instance<> object if bytes are available - // there. Otherwise allocate size bytes of heap memory. - static void* allocate(PyObject*, std::size_t offset, std::size_t size); - - // Deallocate storage from the heap if it was not carved out of - // the given Python object by allocate(), above. - static void deallocate(PyObject*, void* storage) throw(); - private: - instance_holder* m_next; -}; - -// This macro is needed for implementation of derived holders -# define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward::type)(a##N) - -// -// implementation -// -inline instance_holder* instance_holder::next() const -{ - return m_next; -} - -}} // namespace boost::python - -#endif // INSTANCE_HOLDER_DWA2002517_HPP diff --git a/include/boost/python/iterator.hpp b/include/boost/python/iterator.hpp deleted file mode 100644 index 3f477034..00000000 --- a/include/boost/python/iterator.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ITERATOR_DWA2002512_HPP -# define ITERATOR_DWA2002512_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // Adds an additional layer of binding to - // objects::make_iterator(...), which allows us to pass member - // function and member data pointers. - template - inline object make_iterator( - Accessor1 get_start, Accessor2 get_finish, boost::type* target = 0, NextPolicies* = 0) - { - return objects::make_iterator_function( - boost::protect(boost::bind(get_start, _1)) - , boost::protect(boost::bind(get_finish, _1)) - ); - } - - // Guts of template class iterators<>, below. - template - struct iterators_impl - { - template - struct apply - { - typedef typename T::iterator iterator; - static iterator begin(T& x) { return x.begin(); } - static iterator end(T& x) { return x.end(); } - }; - }; - - template <> - struct iterators_impl - { - template - struct apply - { - typedef typename T::const_iterator iterator; - static iterator begin(T& x) { return x.begin(); } - static iterator end(T& x) { return x.end(); } - }; - }; -} - -// An "ordinary function generator" which contains static begin(x) and -// end(x) functions that invoke T::begin() and T::end(), respectively. -template -struct iterators - : detail::iterators_impl< - boost::is_const::value - >::template apply -{ -}; - -// Create an iterator-building function which uses the given -// accessors. Deduce the Target type from the accessors. The iterator -// returns copies of the inderlying elements. -template -object range(Accessor1 start, Accessor2 finish) -{ - return detail::make_iterator( - start, finish - , detail::target(start)); -} - -// Create an iterator-building function which uses the given accessors -// and next() policies. Deduce the Target type. -template -object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) -{ - return detail::make_iterator(start, finish, detail::target(start)); -} - -// Create an iterator-building function which uses the given accessors -// and next() policies, operating on the given Target type -template -object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) -{ - typedef typename add_reference::type target; - return detail::make_iterator(start, finish); -} - -// A Python callable object which produces an iterator traversing -// [x.begin(), x.end()), where x is an instance of the Container -// type. NextPolicies are used as the CallPolicies for the iterator's -// next() function. -template -struct iterator : object -{ - iterator() - : object( - python::range( - &iterators::begin, &iterators::end - )) - { - } -}; - -}} // namespace boost::python - -#endif // ITERATOR_DWA2002512_HPP diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp deleted file mode 100644 index ce6cfab4..00000000 --- a/include/boost/python/list.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef LIST_DWA2002627_HPP -# define LIST_DWA2002627_HPP - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - struct BOOST_PYTHON_DECL list_base : object - { - void append(object_cref); // append object to end - - long count(object_cref value) const; // return number of occurrences of value - - void extend(object_cref sequence); // extend list by appending sequence elements - - long index(object_cref value) const; // return index of first occurrence of value - - void insert(int index, object_cref); // insert object before index - void insert(object const& index, object_cref); - - object pop(); // remove and return item at index (default last) - object pop(long index); - object pop(object const& index); - - void remove(object_cref value); // remove first occurrence of value - - void reverse(); // reverse *IN PLACE* - - void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 - void sort(object_cref cmpfunc); - - - protected: - list_base(); // new list - explicit list_base(object_cref sequence); // new list initialized from sequence's items - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list_base, object) - private: - static detail::new_non_null_reference call(object const&); - }; -} - -class list : public detail::list_base -{ - typedef detail::list_base base; - public: - list() {} // new list - - template - explicit list(T const& sequence) - : base(object(sequence)) - { - } - - template - void append(T const& x) - { - base::append(object(x)); - } - - template - long count(T const& value) const - { - return base::count(object(value)); - } - - template - void extend(T const& x) - { - base::extend(object(x)); - } - - template - long index(T const& x) const - { - return base::index(object(x)); - } - - template - void insert(int index, T const& x) // insert object before index - { - base::insert(index, object(x)); - } - - template - void insert(object const& index, T const& x) // insert object before index - { - base::insert(index, object(x)); - } - - object pop() { return base::pop(); } - object pop(long index) { return base::pop(index); } - - template - object pop(T const& index) - { - return base::pop(object(index)); - } - - template - void remove(T const& value) - { - base::remove(object(value)); - } - - void sort() { base::sort(); } - - template - void sort(T const& value) - { - base::sort(object(value)); - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyList_Type,list> - { - }; -} - -}} // namespace boost::python - -#endif // LIST_DWA2002627_HPP diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp deleted file mode 100644 index 284296be..00000000 --- a/include/boost/python/long.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef LONG_DWA2002627_HPP -# define LONG_DWA2002627_HPP - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - struct BOOST_PYTHON_DECL long_base : object - { - protected: - long_base(); // new long_ - explicit long_base(object_cref rhs); - explicit long_base(object_cref rhs, object_cref base); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_base, object) - - private: - static detail::new_non_null_reference call(object const&); - static detail::new_non_null_reference call(object const&, object const&); - }; -} - -class long_ : public detail::long_base -{ - typedef detail::long_base base; - public: - long_() {} // new long_ - - template - explicit long_(T const& rhs) - : base(object(rhs)) - { - } - - template - explicit long_(T const& rhs, U const& base) - : base(object(rhs), object(base)) - { - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyLong_Type,long_> - { - }; -} - -}} // namespace boost::python - -#endif // LONG_DWA2002627_HPP diff --git a/include/boost/python/lvalue_from_pytype.hpp b/include/boost/python/lvalue_from_pytype.hpp deleted file mode 100755 index ae01a6bd..00000000 --- a/include/boost/python/lvalue_from_pytype.hpp +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef LVALUE_FROM_PYTYPE_DWA2002130_HPP -# define LVALUE_FROM_PYTYPE_DWA2002130_HPP - -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // Given a pointer-to-function of 1 parameter returning a reference - // type, return the type_id of the function's return type. - template - inline type_info extractor_type_id(T&(*)(U)) - { - return type_id(); - } - - // A function generator whose static execute() function is an lvalue - // from_python converter using the given Extractor. U is expected to - // be the actual type of the PyObject instance from which the result - // is being extracted. - template - struct normalized_extractor - { - static inline void* execute(PyObject* op) - { - typedef typename boost::add_reference::type param; - return &Extractor::execute( - boost::python::detail::void_ptr_to_reference( - op, (param(*)())0 ) - ); - } - }; - - // Given an Extractor type and a pointer to its execute function, - // return a new object whose static execute function does the same - // job but is a conforming lvalue from_python conversion function. - // - // usage: normalize(&Extractor::execute) - template - inline normalized_extractor - normalize(T(*)(U), Extractor* = 0) - { - return normalized_extractor(); - } -} - -// An Extractor which extracts the given member from a Python object -// whose instances are stored as InstanceType. -template -struct extract_member -{ - static MemberType& execute(InstanceType& c) - { - (void)c.ob_type; // static assertion - return c.*member; - } -}; - -// An Extractor which simply extracts the entire python object -// instance of InstanceType. -template -struct extract_identity -{ - static InstanceType& execute(InstanceType& c) - { - (void)c.ob_type; // static assertion - return c; - } -}; - -// Registers a from_python conversion which extracts lvalues using -// Extractor's static execute function from Python objects whose type -// object is python_type. -template -struct lvalue_from_pytype -{ - lvalue_from_pytype() - { - converter::registry::insert( - &extract, detail::extractor_type_id(&Extractor::execute)); - } - private: - static void* extract(PyObject* op) - { - return PyObject_TypeCheck(op, const_cast(python_type)) - ? const_cast( - static_cast( - detail::normalize(&Extractor::execute).execute(op))) - : 0 - ; - } -}; - -}} // namespace boost::python - -#endif // LVALUE_FROM_PYTYPE_DWA2002130_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp deleted file mode 100644 index 9632bbd5..00000000 --- a/include/boost/python/make_function.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MAKE_FUNCTION_DWA20011221_HPP -# define MAKE_FUNCTION_DWA20011221_HPP - -# include -# include -# include - -# include - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // make_function_aux -- - // - // These helper functions for make_function (below) do the raw work - // of constructing a Python object from some invokable entity. See - // for more information about how - // the ConverterGenerators and Sig arguments are used. - template - object make_function_aux( - F f // An object that can be invoked by detail::invoke() - , CallPolicies const& p // CallPolicies to use in the invocation - , ConverterGenerators const& // An MPL iterator over a sequence of arg_from_python generators - , Sig const& // An MPL sequence of argument types expected by F - ) - { - return objects::function_object( - detail::caller(f, p) - , mpl::size::value - 1); - } - - // As above, except that it accepts argument keywords. NumKeywords - // is used only for a compile-time assertion to make sure the user - // doesn't pass more keywords than the function can accept. To - // disable all checking, pass mpl::int_<0> for NumKeywords. - template - object make_function_aux( - F f - , CallPolicies const& p - , ConverterGenerators const& - , Sig const& - , detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names - , NumKeywords // An MPL integral type wrapper: the size of kw - ) - { - enum { arity = mpl::size::value - 1 }; - - typedef typename detail::error::more_keywords_than_function_arguments< - NumKeywords::value, arity - >::too_many_keywords assertion; - - return objects::function_object( - detail::caller(f, p) - , arity - , kw); - } -} - -// make_function -- -// -// These overloaded functions wrap a function or member function -// pointer as a Python object, using optional CallPolicies and -// Keywords. -template -object make_function(F f) -{ - return detail::make_function_aux( - f,default_call_policies(),detail::args_from_python(), detail::get_signature(f)); -} - -template -object make_function(F f, CallPolicies const& policies) -{ - return detail::make_function_aux( - f,policies,detail::args_from_python(), detail::get_signature(f)); -} - -template -object make_function(F f, CallPolicies const& policies, Keywords const& keywords) -{ - return detail::make_function_aux( - f - , policies - , detail::args_from_python() - , detail::get_signature(f) - , keywords.range() - , mpl::int_() - ); -} - -}} - - -#endif // MAKE_FUNCTION_DWA20011221_HPP diff --git a/include/boost/python/manage_new_object.hpp b/include/boost/python/manage_new_object.hpp deleted file mode 100644 index 0acbbec8..00000000 --- a/include/boost/python/manage_new_object.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MANAGE_NEW_OBJECT_DWA200222_HPP -# define MANAGE_NEW_OBJECT_DWA200222_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct manage_new_object_requires_a_pointer_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -struct manage_new_object -{ - template - struct apply - { - typedef typename mpl::if_c< - boost::is_pointer::value - , to_python_indirect - , detail::manage_new_object_requires_a_pointer_return_type - >::type type; - }; -}; - -}} // namespace boost::python - -#endif // MANAGE_NEW_OBJECT_DWA200222_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp deleted file mode 100644 index d259d2da..00000000 --- a/include/boost/python/module.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MODULE_DWA2001128_HPP -# define MODULE_DWA2001128_HPP - -# include -# define BOOST_PYTHON_MODULE BOOST_PYTHON_MODULE_INIT - -#endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/module_init.hpp b/include/boost/python/module_init.hpp deleted file mode 100644 index adc259f3..00000000 --- a/include/boost/python/module_init.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MODULE_INIT_DWA20020722_HPP -# define MODULE_INIT_DWA20020722_HPP - -# include -# include - -# ifndef BOOST_PYTHON_MODULE_INIT - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_DECL void init_module(char const* name, void(*)()); - -}}} - -# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE) - -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" __declspec(dllexport) void init##name() \ -{ \ - boost::python::detail::init_module( \ - #name,&init_module_##name); \ -} \ -void init_module_##name() - -# elif defined(_AIX) && !defined(BOOST_PYTHON_STATIC_MODULE) - -# include -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" \ -{ \ - extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ - void init##name() \ - { \ - boost::python::detail::aix_init_module( \ - _PyImport_LoadDynamicModule, #name, &init_module_##name); \ - } \ -} \ -void init_module_##name() - -# else - -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" void init##name() \ -{ \ - boost::python::detail::init_module(#name, &init_module_##name); \ -} \ -void init_module_##name() - -# endif - -# endif - -#endif // MODULE_INIT_DWA20020722_HPP diff --git a/include/boost/python/numeric.hpp b/include/boost/python/numeric.hpp deleted file mode 100644 index c7563b09..00000000 --- a/include/boost/python/numeric.hpp +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef NUMARRAY_DWA2002922_HPP -# define NUMARRAY_DWA2002922_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace numeric { - -namespace aux -{ - struct BOOST_PYTHON_DECL array_base : object - { -# define BOOST_PP_LOCAL_MACRO(n) \ - array_base(BOOST_PP_ENUM_PARAMS_Z(1, n, object const& x)); -# define BOOST_PP_LOCAL_LIMITS (1, 7) -# include BOOST_PP_LOCAL_ITERATE() - - object argmax(long axis=-1); - object argmin(long axis=-1); - object argsort(long axis=-1); - object astype(object const& type = object()); - void byteswap(); - object copy() const; - object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const; - void info() const; - bool is_c_array() const; - bool isbyteswapped() const; - object new_(object type) const; - void sort(); - object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const; - object type() const; - char typecode() const; - - object factory(object const& buffer=object() - , object const& type=object() - , object const& shape=object() - , bool copy = true - , bool savespace = false - , object typecode = object()); - - object getflat() const; - long getrank() const; - object getshape() const; - bool isaligned() const; - bool iscontiguous() const; - long itemsize() const; - long nelements() const; - object nonzero() const; - - void put(object const& indices, object const& values); - - void ravel(); - - object repeat(object const& repeats, long axis=0); - - void resize(object const& shape); - - void setflat(object const& flat); - void setshape(object const& shape); - - void swapaxes(long axis1, long axis2); - - object take(object const& sequence, long axis = 0) const; - - void tofile(object const& file) const; - - str tostring() const; - - void transpose(object const& axes = object()); - - object view() const; - - public: // implementation detail - do not touch. - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array_base, object); - }; - - struct BOOST_PYTHON_DECL array_object_manager_traits - { - static bool check(PyObject* obj); - static detail::new_non_null_reference adopt(PyObject* obj); - }; -} // namespace aux - -class array : public aux::array_base -{ - typedef aux::array_base base; - public: - - object astype() { return base::astype(); } - - template - object astype(Type const& type_) - { - return base::astype(object(type_)); - } - - template - object new_(Type const& type_) const - { - return base::new_(object(type_)); - } - - template - void resize(Sequence const& x) - { - base::resize(object(x)); - } - -# define BOOST_PP_LOCAL_MACRO(n) \ - void resize(BOOST_PP_ENUM_PARAMS_Z(1, n, long x)) \ - { \ - resize(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x))); \ - } -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) -# include BOOST_PP_LOCAL_ITERATE() - - template - void setshape(Sequence const& x) - { - base::setshape(object(x)); - } - -# define BOOST_PP_LOCAL_MACRO(n) \ - void setshape(BOOST_PP_ENUM_PARAMS_Z(1, n, long x)) \ - { \ - setshape(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x))); \ - } -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) -# include BOOST_PP_LOCAL_ITERATE() - - template - void put(Indices const& indices, Values const& values) - { - base::put(object(indices), object(values)); - } - - template - object take(Sequence const& sequence, long axis = 0) - { - return base::take(object(sequence), axis); - } - - template - void tofile(File const& f) const - { - base::tofile(object(f)); - } - - object factory() - { - return base::factory(); - } - - template - object factory(Buffer const& buffer) - { - return base::factory(object(buffer)); - } - - template - object factory( - Buffer const& buffer - , Type const& type_) - { - return base::factory(object(buffer), object(type_)); - } - - template - object factory( - Buffer const& buffer - , Type const& type_ - , Shape const& shape - , bool copy = true - , bool savespace = false) - { - return base::factory(object(buffer), object(type_), object(shape), copy, savespace); - } - - template - object factory( - Buffer const& buffer - , Type const& type_ - , Shape const& shape - , bool copy - , bool savespace - , char typecode) - { - return base::factory(object(buffer), object(type_), object(shape), copy, savespace, object(typecode)); - } - -# define BOOST_PYTHON_ENUM_AS_OBJECT(z, n, x) object(BOOST_PP_CAT(x,n)) -# define BOOST_PP_LOCAL_MACRO(n) \ - template \ - explicit array(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, n, T, const& x)) \ - : base(BOOST_PP_ENUM_1(n, BOOST_PYTHON_ENUM_AS_OBJECT, x)) \ - {} -# define BOOST_PP_LOCAL_LIMITS (1, 7) -# include BOOST_PP_LOCAL_ITERATE() -# undef BOOST_PYTHON_AS_OBJECT - - static BOOST_PYTHON_DECL void set_module_and_type(char const* package_name = 0, char const* type_attribute_name = 0); - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array, base); -}; - -} // namespace boost::python::numeric - -namespace converter -{ - template <> - struct object_manager_traits< numeric::array > - : numeric::aux::array_object_manager_traits - { - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - }; -} - -}} // namespace boost::python - -#endif // NUMARRAY_DWA2002922_HPP diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp deleted file mode 100755 index dbdb7c0a..00000000 --- a/include/boost/python/object.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_DWA2002612_HPP -# define OBJECT_DWA2002612_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - - class type_; // XXX temporary work-around - class string; - -}} // namespace boost::python - -#endif // OBJECT_DWA2002612_HPP diff --git a/include/boost/python/object/add_to_namespace.hpp b/include/boost/python/object/add_to_namespace.hpp deleted file mode 100644 index e075bafd..00000000 --- a/include/boost/python/object/add_to_namespace.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ADD_TO_NAMESPACE_DWA200286_HPP -# define ADD_TO_NAMESPACE_DWA200286_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -// -// A setattr that's "smart" about function overloading (and docstrings). -// -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute); - -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc); - -}}} // namespace boost::python::objects - -#endif // ADD_TO_NAMESPACE_DWA200286_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp deleted file mode 100644 index 78cf06b5..00000000 --- a/include/boost/python/object/class.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_DWA20011214_HPP -# define CLASS_DWA20011214_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace objects { - -struct BOOST_PYTHON_DECL class_base : python::api::object -{ - // constructor - class_base( - char const* name // The name of the class - - , std::size_t num_types // A list of class_ids. The first is the type - , type_info const*const types // this is wrapping. The rest are the types of - // any bases. - - , char const* doc = 0 // Docstring, if any. - ); - - - // Implementation detail. Hiding this in the private section would - // require use of template friend declarations. - void enable_pickling(bool getstate_manages_dict); - - protected: - // Retrieve the underlying object - void add_property(char const* name, object const& fget); - void add_property(char const* name, object const& fget, object const& fset); - void setattr(char const* name, object const&); - - // Set a special attribute in the class which tells Boost.Python - // to allocate extra bytes for embedded C++ objects in Python - // instances. - void set_instance_size(std::size_t bytes); - - // Set an __init__ function which throws an appropriate exception - // for abstract classes. - void def_no_init(); - - // Effects: - // setattr(self, staticmethod(getattr(self, method_name))) - void make_method_static(const char *method_name); -}; - -}}} // namespace boost::python::objects - -#endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp deleted file mode 100644 index e902a40f..00000000 --- a/include/boost/python/object/class_converters.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_CONVERTERS_DWA2002119_HPP -# define CLASS_CONVERTERS_DWA2002119_HPP - -# include -# include - -# include - -# include - -# include - -# include - -namespace boost { namespace python { namespace objects { - -////////////////////////////////////////////////////////////////////// -// -// register_base_of - -// A BinaryMetaFunction object which registers a single base -// class of T, and the corresponding cast(s) -// - - -// register_downcast/do_nothing - -// Helpers for register_base_of<> which take care of registering -// down-casts -template -struct register_downcast -{ - static void execute() - { - register_conversion(true); - } -}; - -struct do_nothing -{ - static void execute() { } -}; - -// Here's where the real work gets done: -template -struct register_base_of -{ - // Here's the runtime part: - template - void operator()(Base*) const - { - // Register the Base class - register_dynamic_id(); - // Register the up-cast - register_conversion(false); - - // Register the down-cast, if appropriate. - mpl::if_c< - is_polymorphic::value - , register_downcast - , do_nothing - >::type::execute(); - } -}; - -// Brings into existence all converters associated with a class. Bases -// is expected to be an mpl sequence of base types. -template -inline void register_class_from_python(Derived* = 0, Bases* = 0) -{ - python::detail::force_instantiate(converter::shared_ptr_from_python::registration); - - // register all up/downcasts here - register_dynamic_id(); - - // register each base in the sequence - mpl::for_each(register_base_of(), (Bases*)0, (add_pointer*)0); -} - -}}} // namespace boost::python::object - -#endif // CLASS_CONVERTERS_DWA2002119_HPP diff --git a/include/boost/python/object/class_detail.hpp b/include/boost/python/object/class_detail.hpp deleted file mode 100644 index f4d4d51e..00000000 --- a/include/boost/python/object/class_detail.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_DETAIL_DWA200295_HPP -# define CLASS_DETAIL_DWA200295_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL type_handle registered_class_object(type_info id); -BOOST_PYTHON_DECL type_handle class_metatype(); -BOOST_PYTHON_DECL type_handle class_type(); - -}}} // namespace boost::python::object - -#endif // CLASS_DETAIL_DWA200295_HPP diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp deleted file mode 100644 index f0fad309..00000000 --- a/include/boost/python/object/class_wrapper.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_WRAPPER_DWA20011221_HPP -# define CLASS_WRAPPER_DWA20011221_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -// -// These two classes adapt the static execute function of a class -// MakeInstance execute() function returning a new PyObject* -// reference. The first one is used for class copy constructors, and -// the second one is used to handle smart pointers. -// - -template -struct class_cref_wrapper - : to_python_converter > -{ - static PyObject* convert(Src const& x) - { - return MakeInstance::execute(boost::ref(x)); - } -}; - -template -struct class_value_wrapper - : to_python_converter > -{ - static PyObject* convert(Src x) - { - return MakeInstance::execute(x); - } -}; - -}}} // namespace boost::python::objects - -#endif // CLASS_WRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/enum_base.hpp b/include/boost/python/object/enum_base.hpp deleted file mode 100644 index 8e4a7301..00000000 --- a/include/boost/python/object/enum_base.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ENUM_BASE_DWA200298_HPP -# define ENUM_BASE_DWA200298_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -struct BOOST_PYTHON_DECL enum_base : python::api::object -{ - protected: - enum_base( - char const* name - , converter::to_python_function_t - , converter::convertible_function - , converter::constructor_function - , type_info); - - void add_value(char const* name, long value); - void export_values(); - - static PyObject* to_python(PyTypeObject* type, long x); -}; - -}}} // namespace boost::python::object - -#endif // ENUM_BASE_DWA200298_HPP diff --git a/include/boost/python/object/find_instance.hpp b/include/boost/python/object/find_instance.hpp deleted file mode 100644 index 113b622d..00000000 --- a/include/boost/python/object/find_instance.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FIND_INSTANCE_DWA2002312_HPP -# define FIND_INSTANCE_DWA2002312_HPP - -# include - -namespace boost { namespace python { namespace objects { - -// Given a type_id, find the instance data which corresponds to it, or -// return 0 in case no such type is held. -BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, type_info); - -}}} // namespace boost::python::objects - -#endif // FIND_INSTANCE_DWA2002312_HPP diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp deleted file mode 100644 index 789dfd23..00000000 --- a/include/boost/python/object/forward.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FORWARD_DWA20011215_HPP -# define FORWARD_DWA20011215_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -// Very much like boost::reference_wrapper, except that in this -// case T can be a reference already without causing a -// reference-to-reference error. -template -struct reference_to_value -{ - typedef typename add_reference::type>::type reference; - - reference_to_value(reference x) : m_value(x) {} - operator reference() const { return m_value; } - private: - reference m_value; -}; - -// A little metaprogram which selects the type to pass through an -// intermediate forwarding function when the destination argument type -// is T. -template -struct forward - : mpl::if_c< - is_scalar::value - , T - , reference_to_value > -{ -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class unforward -{ - public: - typedef typename unwrap_reference::type& type; -}; - -template -class unforward > -{ - public: - typedef T type; -}; -# else // no partial specialization - -namespace detail -{ - typedef char (&yes_reference_to_value_t)[1]; - typedef char (&no_reference_to_value_t)[2]; - - no_reference_to_value_t is_reference_to_value_test(...); - - template - yes_reference_to_value_t is_reference_to_value_test(boost::type< reference_to_value >); - - template - struct unforwarder - { - template - struct apply - { - typedef typename unwrap_reference::type& type; - }; - }; - - template<> - struct unforwarder - { - template - struct apply - { - typedef typename T::reference type; - }; - }; - - template - class is_reference_to_value - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(is_reference_to_value_test(boost::type())) - == sizeof(yes_reference_to_value_t))); - }; -} - -template -class unforward - : public detail::unforwarder< - detail::is_reference_to_value::value - >::template apply -{}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}}} // namespace boost::python::objects - -#endif // FORWARD_DWA20011215_HPP diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp deleted file mode 100644 index 1a3c3f5f..00000000 --- a/include/boost/python/object/function.hpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FUNCTION_DWA20011214_HPP -# define FUNCTION_DWA20011214_HPP - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -struct BOOST_PYTHON_DECL function : PyObject -{ - function( - py_function const& - , unsigned min_arity - , unsigned max_arity - , python::detail::keyword const* names_and_defaults - , unsigned num_keywords); - - ~function(); - - PyObject* call(PyObject*, PyObject*) const; - - // Add an attribute to the name_space with the given name. If it is - // a function object (this class), and an existing function is - // already there, add it as an overload. - static void add_to_namespace( - object const& name_space, char const* name, object const& attribute); - - static void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc); - - object const& doc() const; - void doc(object const& x); - - object const& name() const; - - private: // helper functions - void argument_error(PyObject* args, PyObject* keywords) const; - void add_overload(handle const&); - - private: // data members - py_function m_fn; - unsigned m_min_arity; - unsigned m_max_arity; - handle m_overloads; - object m_name; - object m_doc; - object m_arg_names; -}; - -// -// implementations -// -inline object const& function::doc() const -{ - return this->m_doc; -} - -inline void function::doc(object const& x) -{ - this->m_doc = x; -} - -inline object const& function::name() const -{ - return this->m_name; -} - -}}} // namespace boost::python::objects - -#endif // FUNCTION_DWA20011214_HPP diff --git a/include/boost/python/object/function_handle.hpp b/include/boost/python/object/function_handle.hpp deleted file mode 100644 index 29efa2be..00000000 --- a/include/boost/python/object/function_handle.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FUNCTION_HANDLE_DWA2002725_HPP -# define FUNCTION_HANDLE_DWA2002725_HPP -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL handle<> function_handle_impl(py_function const& f, unsigned min_args, unsigned max_args = 0); - -// Just like function_object, but returns a handle<> instead. Using -// this for arg_to_python<> allows us to break a circular dependency -// between object and arg_to_python. -template -inline handle<> function_handle(F const& f, Signature) -{ - enum { n_arguments = mpl::size::value - 1 }; - - return objects::function_handle_impl( - python::detail::caller< - F,python::detail::args_from_python,default_call_policies,Signature>( - f, default_call_policies()) - , n_arguments, n_arguments); -} - -// Just like make_function, but returns a handle<> intead. Same -// reasoning as above. -template -handle<> make_function_handle(F f) -{ - return objects::function_handle(f, python::detail::get_signature(f)); -} - -}}} // namespace boost::python::objects - -#endif // FUNCTION_HANDLE_DWA2002725_HPP diff --git a/include/boost/python/object/function_object.hpp b/include/boost/python/object/function_object.hpp deleted file mode 100644 index d3661563..00000000 --- a/include/boost/python/object/function_object.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FUNCTION_OBJECT_DWA2002725_HPP -# define FUNCTION_OBJECT_DWA2002725_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace objects -{ - BOOST_PYTHON_DECL api::object function_object( - py_function const& f - , unsigned min_arity, unsigned max_arity - , python::detail::keyword_range const&); - - BOOST_PYTHON_DECL api::object function_object( - py_function const& f - , unsigned arity - , python::detail::keyword_range const&); - - BOOST_PYTHON_DECL api::object function_object(py_function const& f, unsigned arity); - - // Add an attribute to the name_space with the given name. If it is - // a Boost.Python function object - // (boost/python/object/function.hpp), and an existing function is - // already there, add it as an overload. - BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute); - - BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc); -} - -}} // namespace boost::python::objects - -#endif // FUNCTION_OBJECT_DWA2002725_HPP diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp deleted file mode 100644 index 610f458c..00000000 --- a/include/boost/python/object/inheritance.hpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef INHERITANCE_DWA200216_HPP -# define INHERITANCE_DWA200216_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -typedef type_info class_id; -using python::type_id; - -// Types used to get address and id of most derived type -typedef std::pair dynamic_id_t; -typedef dynamic_id_t (*dynamic_id_function)(void*); - -BOOST_PYTHON_DECL void register_dynamic_id_aux( - class_id static_id, dynamic_id_function get_dynamic_id); - -BOOST_PYTHON_DECL void add_cast( - class_id src_t, class_id dst_t, void* (*cast)(void*), bool polymorphic); - -BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst); - -BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst); - -// -// a generator with an execute() function which, given a source type -// and a pointer to an object of that type, returns its most-derived -// /reachable/ type identifier and object pointer. -// - -// first, the case where T has virtual functions -template -struct polymorphic_id_generator -{ - static dynamic_id_t execute(void* p_) - { - T* p = static_cast(p_); - return std::make_pair(dynamic_cast(p), class_id(typeid(*p))); - } -}; - -// now, the non-polymorphic case. -template -struct non_polymorphic_id_generator -{ - static dynamic_id_t execute(void* p_) - { - return std::make_pair(p_, python::type_id()); - } -}; - -// Now the generalized selector -template -struct dynamic_id_generator -{ - typedef typename mpl::if_c< - is_polymorphic::value - , polymorphic_id_generator - , non_polymorphic_id_generator >::type type; -}; - -// Register the dynamic id function for T with the type-conversion -// system. -template -void register_dynamic_id(T* = 0) -{ - typedef typename dynamic_id_generator::type generator; - register_dynamic_id_aux( - python::type_id(), &generator::execute); -} - -// -// a generator with an execute() function which, given a void* -// pointing to an object of type Source will attempt to convert it to -// an object of type Target. -// - -template -struct dynamic_cast_generator -{ - static void* execute(void* source) - { - return dynamic_cast( - static_cast(source)); - } - -}; - -template -struct implicit_cast_generator -{ - static void* execute(void* source) - { - Target* result = static_cast(source); - return result; - } -}; - -template -struct cast_generator -{ - // It's OK to return false, since we can always cast up with - // dynamic_cast<> if neccessary. -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - BOOST_STATIC_CONSTANT(bool, is_upcast = false); -# else - BOOST_STATIC_CONSTANT( - bool, is_upcast = ( - is_base_and_derived::value - )); -# endif - - typedef typename mpl::if_c< - is_upcast -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - // grab a few more implicit_cast cases for CodeWarrior - || !is_polymorphic::value - || !is_polymorphic::value -# endif - , implicit_cast_generator - , dynamic_cast_generator - >::type type; -}; - -template -inline void register_conversion( - // We need this parameter because CWPro7 can't determine - // which is the base reliably. - bool is_downcast = !cast_generator::is_upcast - - // These parameters shouldn't be used, they're an MSVC bug workaround - , Source* = 0, Target* = 0) -{ - typedef typename cast_generator::type generator; - - add_cast(python::type_id() - , python::type_id() - , &generator::execute - , is_downcast); -} - -}}} // namespace boost::python::object - -#endif // INHERITANCE_DWA200216_HPP diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp deleted file mode 100644 index b258a2a0..00000000 --- a/include/boost/python/object/instance.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef INSTANCE_DWA200295_HPP -# define INSTANCE_DWA200295_HPP - -# include -# include -# include - -namespace boost { namespace python -{ - struct BOOST_PYTHON_DECL instance_holder; -}} // namespace boost::python - -namespace boost { namespace python { namespace objects { - -// Each extension instance will be one of these -template -struct instance -{ - PyObject_VAR_HEAD - PyObject* dict; - PyObject* weakrefs; - instance_holder* objects; - - BOOST_STATIC_CONSTANT(std::size_t, alignment = alignment_of::value); - typedef typename type_with_alignment::type align_t; - - union - { - align_t align; - char bytes[sizeof(Data)]; - } storage; -}; - -template -struct additional_instance_size -{ - typedef instance instance_data; - typedef instance instance_char; - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(instance_data) - - BOOST_PYTHON_OFFSETOF(instance_char,storage)); -}; - -}}} // namespace boost::python::object - -#endif // INSTANCE_DWA200295_HPP diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp deleted file mode 100644 index c97c3994..00000000 --- a/include/boost/python/object/iterator.hpp +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ITERATOR_DWA2002510_HPP -# define ITERATOR_DWA2002510_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -// CallPolicies for the next() method of iterators. We don't want -// users to have to explicitly specify that the references returned by -// iterators are copied, so we just replace the result_converter from -// the default_iterator_call_policies with a permissive one which -// always copies the result. -typedef return_value_policy default_iterator_call_policies; - -// Instantiations of these are wrapped to produce Python iterators. -template -struct iterator_range -{ - iterator_range(object sequence, Iterator start, Iterator finish); - - object m_sequence; // Keeps the sequence alive while iterating. - Iterator m_start; - Iterator m_finish; -}; - -namespace detail -{ - // Guts of the iterator's next() function. We can't just wrap an - // ordinary function because we don't neccessarily know the result - // type of dereferencing the iterator. This also saves us from - // throwing C++ exceptions to indicate end-of-sequence. - template - struct iterator_next - { - static PyObject* execute(PyObject* args_, PyObject* kw, Policies const& policies) - { - typedef iterator_range range_; - - PyObject* py_self = PyTuple_GET_ITEM(args_, 0); - arg_from_python c0(py_self); - range_* self = c0(py_self); - - // Done iterating? - if (self->m_start == self->m_finish) - { - objects::set_stop_iteration_error(); - return 0; - } - - // note: precall happens before we can check for the result - // converter in this case, to ensure it happens before the - // iterator is dereferenced. However, the arity is 1 so - // there's not much risk that this will amount to anything. - if (!policies.precall(args_)) return 0; - - PyObject* result = iterator_next::convert_result(*self->m_start); - ++self->m_start; - - return policies.postcall(args_, result); - } - private: - // Convert the result of dereferencing the iterator. Dispatched - // here because we can't neccessarily get the value_type of the - // iterator without PTS. This way, we deduce the value type by - // dereferencing. - template - static PyObject* convert_result(ValueType& x) - { - typedef typename Policies::result_converter result_converter; - typename mpl::apply1::type cr; - - return cr(x); - } - template - static PyObject* convert_result(ValueType const& x) - { - typedef typename Policies::result_converter result_converter; - typename mpl::apply1::type cr; - - return cr(x); - } - }; - - // Get a Python class which contains the given iterator and - // policies, creating it if neccessary. Requires: NextPolicies is - // default-constructible. - template - object demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies()) - { - typedef iterator_range range_; - - // Check the registry. If one is already registered, return it. - handle<> class_obj( - objects::registered_class_object(python::type_id())); - - if (class_obj.get() != 0) - return object(class_obj); - - // Make a callable object which can be used as the iterator's next() function. - object next_function = - objects::function_object( - bind(&detail::iterator_next::execute, _1, _2, policies) - , 1); - - return class_(name, no_init) - .def("__iter__", identity_function()) - .setattr("next", next_function) - ; - } - - // This class template acts as a generator for an ordinary function - // which builds a Python iterator. - template - struct make_iterator_help - { - // Extract an object x of the Target type from the first Python - // argument, and invoke get_start(x)/get_finish(x) to produce - // iterators, which are used to construct a new iterator_range<> - // object that gets wrapped into a Python iterator. - static PyObject* create( - Accessor1 const& get_start, Accessor2 const& get_finish - , PyObject* args_, PyObject* /*kw*/) - { - // Make sure the Python class is instantiated. - detail::demand_iterator_class("iterator", (Iterator*)0, NextPolicies()); - - to_python_value > cr; - - // Extract x from the first argument - PyObject* arg0 = PyTuple_GET_ITEM(args_, 0); - arg_from_python c0(arg0); - if (!c0.convertible()) return 0; - typename arg_from_python::result_type x = c0(arg0); - - // Build and convert the iterator_range<>. - return cr( - iterator_range( - object((python::detail::borrowed_reference)arg0) - , get_start(x), get_finish(x))); - } - }; - - template - inline object make_iterator_function( - Accessor1 const& get_start, Accessor2 const& get_finish, Iterator const& (*)(), boost::type*, NextPolicies*, int) - { - return - objects::function_object( - boost::bind( - &make_iterator_help< - Target,Iterator,Accessor1,Accessor2,NextPolicies - >::create - , get_start, get_finish, _1, _2) - , 1 ); - } - - template - inline object make_iterator_function( - Accessor1 const& get_start, Accessor2 const& get_finish, Iterator& (*)(), boost::type*, NextPolicies*, ...) - { - return make_iterator_function( - get_start, get_finish, (Iterator const&(*)())0 - , (boost::type*)0, (NextPolicies*)0, 0); - } - -} - -// Create a Python callable object which accepts a single argument -// convertible to the C++ Target type and returns a Python -// iterator. The Python iterator uses get_start(x) and get_finish(x) -// (where x is an instance of Target) to produce begin and end -// iterators for the range, and an instance of NextPolicies is used as -// CallPolicies for the Python iterator's next() function. -template -inline object make_iterator_function( - Accessor1 const& get_start, Accessor2 const& get_finish - , boost::type* = 0, NextPolicies* = 0) -{ - typedef typename Accessor1::result_type iterator; - typedef typename add_const::type iterator_const; - typedef typename add_reference::type iterator_cref; - - return detail::make_iterator_function( - get_start, get_finish - , (iterator_cref(*)())0 - , (boost::type*)0 - , (NextPolicies*)0 - , 0 - ); -} - -// -// implementation -// -template -inline iterator_range::iterator_range( - object sequence, Iterator start, Iterator finish) - : m_sequence(sequence), m_start(start), m_finish(finish) -{ -} - -}}} // namespace boost::python::objects - -#endif // ITERATOR_DWA2002510_HPP diff --git a/include/boost/python/object/iterator_core.hpp b/include/boost/python/object/iterator_core.hpp deleted file mode 100644 index 655fc71e..00000000 --- a/include/boost/python/object/iterator_core.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ITERATOR_CORE_DWA2002512_HPP -# define ITERATOR_CORE_DWA2002512_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL object const& identity_function(); -BOOST_PYTHON_DECL void set_stop_iteration_error(); - -}}} // namespace boost::python::object - -#endif // ITERATOR_CORE_DWA2002512_HPP diff --git a/include/boost/python/object/life_support.hpp b/include/boost/python/object/life_support.hpp deleted file mode 100644 index 5d9587db..00000000 --- a/include/boost/python/object/life_support.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef LIFE_SUPPORT_DWA200222_HPP -# define LIFE_SUPPORT_DWA200222_HPP -# include -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient); - -}}} // namespace boost::python::object - -#endif // LIFE_SUPPORT_DWA200222_HPP diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp deleted file mode 100644 index a2c013c4..00000000 --- a/include/boost/python/object/make_holder.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef MAKE_HOLDER_DWA20011215_HPP -# define MAKE_HOLDER_DWA20011215_HPP - -# include - -# include -# include -# include - -# include -# include -# include - -# include -# include -# include -# include -# include - -# include - -namespace boost { namespace python { namespace objects { - -template struct make_holder; - -# define BOOST_PYTHON_DO_FORWARD_ARG(z, index, _) , f##index(a##index) - -// specializations... -# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# undef BOOST_PYTHON_DO_FORWARD_ARG - -}}} // namespace boost::python::objects - -# endif // MAKE_HOLDER_DWA20011215_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 -# line BOOST_PP_LINE(__LINE__, make_holder.hpp) - -# define N BOOST_PP_ITERATION() - -template <> -struct make_holder -{ - template - struct apply - { -# if N - // Unrolled iteration through each argument type in ArgList, - // choosing the type that will be forwarded on to the holder's - // templated constructor. - typedef typename mpl::begin::type iter0; - -# define BOOST_PP_LOCAL_MACRO(n) \ - typedef typename mpl::apply0::type t##n; \ - typedef typename forward::type f##n; \ - typedef typename mpl::next::type \ - BOOST_PP_CAT(iter,BOOST_PP_INC(n)); // Next iterator type - -# define BOOST_PP_LOCAL_LIMITS (0, N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - - static void execute( - PyObject* p - BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a)) - { - typedef instance instance_t; - - void* memory = Holder::allocate(p, offsetof(instance_t, storage), sizeof(Holder)); - try { - (new (memory) Holder( - p BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p); - } - catch(...) { - Holder::deallocate(p, memory); - throw; - } - } - }; -}; - -# undef N - -#endif diff --git a/include/boost/python/object/make_instance.hpp b/include/boost/python/object/make_instance.hpp deleted file mode 100644 index eb420d2f..00000000 --- a/include/boost/python/object/make_instance.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MAKE_INSTANCE_DWA200296_HPP -# define MAKE_INSTANCE_DWA200296_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct make_instance_impl -{ - typedef objects::instance instance_t; - - template - static inline PyObject* execute(Arg& x) - { - BOOST_STATIC_ASSERT(is_class::value); - - PyTypeObject* type = Derived::get_class_object(x); - - PyObject* raw_result = type->tp_alloc( - type, objects::additional_instance_size::value); - - if (raw_result != 0) - { - python::detail::decref_guard protect(raw_result); - - instance_t* instance = (instance_t*)raw_result; - - // construct the new C++ object and install the pointer - // in the Python object. - Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result); - - // Note the position of the internally-stored Holder, - // for the sake of destruction - instance->ob_size = offsetof(instance_t, storage); - - // Release ownership of the python object - protect.cancel(); - } - return raw_result; - } -}; - - -template -struct make_instance - : make_instance_impl > -{ - template - static inline PyTypeObject* get_class_object(U&) - { - return converter::registered::converters.get_class_object(); - } - - static inline Holder* construct(void* storage, PyObject* instance, reference_wrapper x) - { - return new (storage) Holder(instance, x); - } -}; - - -}}} // namespace boost::python::object - -#endif // MAKE_INSTANCE_DWA200296_HPP diff --git a/include/boost/python/object/make_ptr_instance.hpp b/include/boost/python/object/make_ptr_instance.hpp deleted file mode 100644 index 25dbd77c..00000000 --- a/include/boost/python/object/make_ptr_instance.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MAKE_PTR_INSTANCE_DWA200296_HPP -# define MAKE_PTR_INSTANCE_DWA200296_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct make_ptr_instance - : make_instance_impl > -{ - template - static inline Holder* construct(void* storage, PyObject*, Arg& x) - { - return new (storage) Holder(x); - } - - template - static inline PyTypeObject* get_class_object(Ptr const& x) - { - return get_class_object_impl(get_pointer(x)); - } - - private: - template - static inline PyTypeObject* get_class_object_impl(U const volatile* p) - { - PyTypeObject* derived = get_derived_class_object(is_polymorphic::type(), p); - if (derived) - return derived; - return converter::registered::converters.get_class_object(); - } - - template - static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x) - { - converter::registration const* r = converter::registry::query(type_info(typeid(*x))); - return r ? r->m_class_object : 0; - } - - template - static inline PyTypeObject* get_derived_class_object(mpl::false_, U* x) - { -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - if (typeid(*x) != typeid(U)) - return get_derived_class_object(mpl::true_(), x); -# else - (void)x; -# endif - return 0; - } -}; - - -}}} // namespace boost::python::object - -#endif // MAKE_PTR_INSTANCE_DWA200296_HPP diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp deleted file mode 100644 index e8033196..00000000 --- a/include/boost/python/object/pickle_support.hpp +++ /dev/null @@ -1,125 +0,0 @@ -// (C) Copyright R.W. Grosse-Kunstleve 2002. -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. This -// software is provided "as is" without express or implied warranty, and -// with no claim as to its suitability for any purpose. -#ifndef BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP -# define BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP - -# include - -namespace boost { namespace python { - -namespace api -{ - class object; -} -using api::object; -class tuple; - -BOOST_PYTHON_DECL object const& make_instance_reduce_function(); - -struct pickle_suite; - -namespace error_messages { - - template - struct missing_pickle_suite_function_or_incorrect_signature {}; - - inline void must_be_derived_from_pickle_suite(pickle_suite const&) {} -} - -namespace detail { struct pickle_suite_registration; } - -struct pickle_suite -{ - private: - struct inaccessible {}; - friend struct detail::pickle_suite_registration; - public: - static inaccessible* getinitargs() { return 0; } - static inaccessible* getstate() { return 0; } - static inaccessible* setstate() { return 0; } - static bool getstate_manages_dict() { return false; } -}; - -namespace detail { - - struct pickle_suite_registration - { - typedef pickle_suite::inaccessible inaccessible; - - template - static - void - register_( - Class_& cl, - tuple (*getinitargs_fn)(Tgetinitargs), - inaccessible* (*getstate_fn)(), - inaccessible* (*setstate_fn)(), - bool) - { - cl.enable_pickling(false); - cl.def("__getinitargs__", getinitargs_fn); - } - - template - static - void - register_( - Class_& cl, - inaccessible* (*getinitargs_fn)(), - Rgetstate (*getstate_fn)(Tgetstate), - void (*setstate_fn)(Tsetstate, Ttuple), - bool getstate_manages_dict) - { - cl.enable_pickling(getstate_manages_dict); - cl.def("__getstate__", getstate_fn); - cl.def("__setstate__", setstate_fn); - } - - template - static - void - register_( - Class_& cl, - tuple (*getinitargs_fn)(Tgetinitargs), - Rgetstate (*getstate_fn)(Tgetstate), - void (*setstate_fn)(Tsetstate, Ttuple), - bool getstate_manages_dict) - { - cl.enable_pickling(getstate_manages_dict); - cl.def("__getinitargs__", getinitargs_fn); - cl.def("__getstate__", getstate_fn); - cl.def("__setstate__", setstate_fn); - } - - template - static - void - register_( - Class_&, - ...) - { - typedef typename - error_messages::missing_pickle_suite_function_or_incorrect_signature< - Class_>::error_type error_type; - } - }; - - template - struct pickle_suite_finalize - : PickleSuiteType, - pickle_suite_registration - {}; - -} // namespace detail - -}} // namespace boost::python - -#endif // BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp deleted file mode 100644 index 4400abe6..00000000 --- a/include/boost/python/object/pointer_holder.hpp +++ /dev/null @@ -1,176 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef POINTER_HOLDER_DWA20011215_HPP -# define POINTER_HOLDER_DWA20011215_HPP - -# include - -# include -# include -# include -# include -# include -# include -# include - -# include -# include - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -bool is_null(T const& p, ...) -{ - return p.get() == 0; -} - -template -bool is_null(T* p, int) -{ - return p == 0; -} - -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) - -template -struct pointer_holder : instance_holder -{ - typedef Value value_type; - - pointer_holder(Pointer); - - // Forward construction to the held object - -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) -# include BOOST_PP_ITERATE() - - private: // types - - private: // required holder implementation - void* holds(type_info); - - private: // data members - Pointer m_p; -}; - -template -struct pointer_holder_back_reference : instance_holder -{ - private: - typedef typename python::pointee::type held_type; - public: - typedef Value value_type; - - // Not sure about this one -- can it work? The source object - // undoubtedly does not carry the correct back reference pointer. - pointer_holder_back_reference(Pointer); - - // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) -# include BOOST_PP_ITERATE() - - private: // required holder implementation - void* holds(type_info); - - private: // data members - Pointer m_p; -}; - -# undef BOOST_PYTHON_UNFORWARD_LOCAL - -template -inline pointer_holder::pointer_holder(Pointer p) - : m_p(p) -{ -} - -template -inline pointer_holder_back_reference::pointer_holder_back_reference(Pointer p) - : m_p(p) -{ -} - -template -void* pointer_holder::holds(type_info dst_t) -{ - if (dst_t == python::type_id()) - return &this->m_p; - - if (objects::is_null(this->m_p, 0)) - return 0; - - type_info src_t = python::type_id(); - Value* p = &*this->m_p; - return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); -} - -template -void* pointer_holder_back_reference::holds(type_info dst_t) -{ - if (dst_t == python::type_id()) - return &this->m_p; - - if (objects::is_null(this->m_p, 0)) - return 0; - - if (dst_t == python::type_id()) - return &*this->m_p; - - type_info src_t = python::type_id(); - Value* p = &*this->m_p; - return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); -} - -}}} // namespace boost::python::objects - -# endif // POINTER_HOLDER_DWA20011215_HPP - -/* --------------- pointer_holder --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 -# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template< BOOST_PP_ENUM_PARAMS_Z(1, N, class A) > -# endif - pointer_holder(PyObject* BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_p(new Value( - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - )) - {} - -# undef N - -/* --------------- pointer_holder_back_reference --------------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 -# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp(pointer_holder_back_reference)) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template < BOOST_PP_ENUM_PARAMS_Z(1, N, class A) > -# endif - pointer_holder_back_reference( - PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_p(new held_type( - p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - )) - {} - -# undef N - -#endif diff --git a/include/boost/python/object/py_function.hpp b/include/boost/python/object/py_function.hpp deleted file mode 100644 index 0682d692..00000000 --- a/include/boost/python/object/py_function.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PY_FUNCTION_DWA200286_HPP -# define PY_FUNCTION_DWA200286_HPP -# include - -namespace boost { namespace python { namespace objects { - -// This type is used as a "generalized Python callback", wrapping the -// function signature: -// -// PyObject* (PyObject* args, PyObject* keywords) -// -// We use boost::function to avoid generating lots of virtual tables -typedef boost::function2 py_function; - -}}} // namespace boost::python::objects - -#endif // PY_FUNCTION_DWA200286_HPP diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp deleted file mode 100644 index 87bc06da..00000000 --- a/include/boost/python/object/select_holder.hpp +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SELECT_HOLDER_DWA2002322_HPP -# define SELECT_HOLDER_DWA2002322_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include - -# include -# include -# include - -# include -# include -# include - -# include - -namespace boost { namespace python { namespace objects { - -namespace detail -{ - - // check_default_constructible -- - // - // Used to give a clean error message when the user doesn't specify - // any __init__ functions, but when the class being wrapped doesn't - // have an appropriate default constructor (or if - // has_back_reference is true, a constructor taking PyObject*). - - // A helpful compile-time assertion which gives a reasonable error - // message if T can't be default-constructed. - template - static int specify_init_arguments_or_no_init_for_class_(T const&); - - // U is expected to take an initial hidden PyObject* in its - // constructor. Normally this means U is a virtual function - // dispatcher subclass for T. - template - void check_default_constructible(T*, U*, mpl::bool_) - { - python::detail::force_instantiate( - sizeof(specify_init_arguments_or_no_init_for_class_(U((::PyObject*)0))) - ); - } - - // Handles the "normal" case where T is held directly and - // has_back_reference is not specialized. - template - void check_default_constructible(T*, T*, mpl::bool_) - { - python::detail::force_instantiate( - sizeof(specify_init_arguments_or_no_init_for_class_(T())) - ); - } - - // - // select_value_holder/select_pointer_holder -- - // - // An instantiation of one of these data-free class templates is - // returned by select_holder::execute(), below. Each provides the - // following public interface: - // - // static void assert_default_constructible() -- called when no - // init<...> arguments are specified in class_'s - // constructor; causes a compile-time error when T has no - // corresponding default constructor. - // - // typedef ... type -- the class derived from instance_holder - // which will manage a Held object in Python class instances - // - // static type* get() { return 0; } -- just a way to access the - // computed type at runtime. - // - // static void register_() -- forces registration of any - // to_python converters corresponding to Held. - - template - struct select_value_holder - { - BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same::value) | has_back_reference::value); - - static void assert_default_constructible() - { - detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_()); - } - - typedef typename mpl::if_c< - back_ref - , value_holder_back_reference - , value_holder - >::type type; - - static inline void register_() {} - - static type* get() { return 0; } - }; - - template - struct select_pointer_holder - { - typedef typename python::pointee::type pointee; - BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same::value) | has_back_reference::value); - - static void assert_default_constructible() - { - detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_()); - } - - typedef typename mpl::if_c< - back_ref - , pointer_holder_back_reference - , pointer_holder - >::type type; - - static inline void register_() - { - select_pointer_holder::register_(mpl::bool_()); - } - - static type* get() { return 0; } - - private: - static inline void register_(mpl::true_) - { - } - - struct construct_from_pointer - { - static type* execute(PyObject*, Ptr x) - { - return new type(x); - } - }; - - static inline void register_(mpl::false_) - { - python::detail::force_instantiate( - objects::class_value_wrapper >()); - } - }; -} - -// select_holder::execute((Held*)0) -// -// implements a compile-time returns an instantiation of -// detail::select_value_holder or detail::select_pointer_holder, as -// appropriate for class_ -template -struct select_holder -{ - // Return the additional size to allocate in Python class - // instances to hold the C++ instance data. - static inline std::size_t additional_size() - { - return additional_size_helper( -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - execute((Held*)0) -# else - type() -# endif - ); - } - - # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - // These overloads are an elaborate workaround for deficient - // compilers: - // - // They are meant to be called with a null pointer to the class_'s - // Held template argument. The selected overload will create an - // appropriate instantiation of select_value_holder or - // select_pointer_holder, which is itself an empty class that is - // ultimately used to create the class_'s instance_holder subclass - // object. - - // No Held was specified; T is held directly by-value - static inline detail::select_value_holder - execute(python::detail::not_specified*) - { - return detail::select_value_holder(); - } - - // A type derived from T was specified; it is assumed to be a - // virtual function dispatcher class, and T is held as Held. - static inline detail::select_value_holder - execute(T*) - { - return detail::select_value_holder(); - } - - // Some other type was specified; Held is assumed to be a (smart) - // pointer to T or a class derived from T. - static inline detail::select_pointer_holder - execute(void*) - { - return detail::select_pointer_holder(); - } -# else - typedef typename mpl::if_< - is_same - , detail::select_value_holder - , typename mpl::if_< - mpl::or_< - is_same - , is_base_and_derived - > - , detail::select_value_holder - , detail::select_pointer_holder - >::type - >::type type; -# endif - - private: - template - static inline std::size_t additional_size_helper(Selector const&) - { - typedef typename Selector::type holder; - return additional_instance_size::value; - } -}; - -}}} // namespace boost::python::objects - -#endif // SELECT_HOLDER_DWA2002322_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp deleted file mode 100644 index 6ae3ae75..00000000 --- a/include/boost/python/object/value_holder.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# ifndef VALUE_HOLDER_DWA20011215_HPP -# define VALUE_HOLDER_DWA20011215_HPP - -# include - -# include -# include - -# include -# include - -# include -# include - -# include -# include -# include -# include -# include - -# include -# include - -namespace boost { namespace python { namespace objects { - -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) - -template -struct value_holder : instance_holder -{ - typedef Held value_type; - - // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) -# include BOOST_PP_ITERATE() - - private: // required holder implementation - void* holds(type_info); - - private: // data members - Held m_held; -}; - -template -struct value_holder_back_reference : instance_holder -{ - typedef Held value_type; - - // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) -# include BOOST_PP_ITERATE() - -private: // required holder implementation - void* holds(type_info); - - private: // data members - BackReferenceType m_held; -}; - -# undef BOOST_PYTHON_UNFORWARD_LOCAL - -template -void* value_holder::holds(type_info dst_t) -{ - type_info src_t = python::type_id(); - return src_t == dst_t ? &m_held - : find_static_type(&m_held, src_t, dst_t); -} - -template -void* value_holder_back_reference::holds( - type_info dst_t) -{ - type_info src_t = python::type_id(); - Held* x = &m_held; - - if (dst_t == src_t) - return x; - else if (dst_t == python::type_id()) - return &m_held; - else - return find_static_type(x, src_t, dst_t); -} - -}}} // namespace boost::python::objects - -# endif // VALUE_HOLDER_DWA20011215_HPP - -// --------------- value_holder --------------- - -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 -# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder)) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template -# endif - value_holder( - PyObject* BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_held( - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - ) - {} - -# undef N - -// --------------- value_holder_back_reference --------------- - -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 -# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder_back_reference)) - -# define N BOOST_PP_ITERATION() - -# if (N != 0) - template -# endif - value_holder_back_reference( - PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) - : m_held( - p BOOST_PP_COMMA_IF(N) - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - ) - { - } - -# undef N - -#endif diff --git a/include/boost/python/object/value_holder_fwd.hpp b/include/boost/python/object/value_holder_fwd.hpp deleted file mode 100644 index 6cb2a0f5..00000000 --- a/include/boost/python/object/value_holder_fwd.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_HOLDER_FWD_DWA2002311_HPP -# define VALUE_HOLDER_FWD_DWA2002311_HPP - -namespace boost { namespace python { namespace objects { - -struct no_back_reference; - -template struct value_holder_generator; - -}}} // namespace boost::python::object - -#endif // VALUE_HOLDER_FWD_DWA2002311_HPP diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp deleted file mode 100755 index 4d3c2a7d..00000000 --- a/include/boost/python/object_attributes.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_ATTRIBUTES_DWA2002615_HPP -# define OBJECT_ATTRIBUTES_DWA2002615_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace api { - -struct const_attribute_policies -{ - typedef char const* key_type; - static object get(object const& target, char const* key); -}; - -struct attribute_policies : const_attribute_policies -{ - static object const& set(object const& target, char const* key, object const& value); - static void del(object const&target, char const* key); -}; - -// -// implementation -// -template -inline object_attribute object_operators::attr(char const* name) -{ - object_cref2 x = *static_cast(this); - return object_attribute(x, name); -} - -template -inline const_object_attribute object_operators::attr(char const* name) const -{ - object_cref2 x = *static_cast(this); - return const_object_attribute(x, name); -} - -inline object const_attribute_policies::get(object const& target, char const* key) -{ - return python::getattr(target, key); -} - -inline object const& attribute_policies::set( - object const& target - , char const* key - , object const& value) -{ - python::setattr(target, key, value); - return value; -} - -inline void attribute_policies::del( - object const& target - , char const* key) -{ - python::delattr(target, key); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_ATTRIBUTES_DWA2002615_HPP diff --git a/include/boost/python/object_call.hpp b/include/boost/python/object_call.hpp deleted file mode 100644 index dd0c0dc0..00000000 --- a/include/boost/python/object_call.hpp +++ /dev/null @@ -1,24 +0,0 @@ -# if !defined(BOOST_PYTHON_SYNOPSIS) -# // Copyright David Abrahams 2002. Permission to copy, use, -# // modify, sell and distribute this software is granted provided this -# // copyright notice appears in all copies. This software is provided -# // "as is" without express or implied warranty, and with no claim as -# // to its suitability for any purpose. - -# if !defined(BOOST_PP_IS_ITERATING) -# error Boost.Python - do not include this file! -# endif - -# define N BOOST_PP_ITERATION() - - template - typename detail::dependent::type - operator()(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)) const - { - typedef typename detail::dependent::type obj; - U const& self = *static_cast(this); - return call(get_managed_object(self, tag), BOOST_PP_ENUM_PARAMS_Z(1, N, a)); - } - -# undef N -# endif // BOOST_PYTHON_SYNOPSIS diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp deleted file mode 100755 index 4727edba..00000000 --- a/include/boost/python/object_core.hpp +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_CORE_DWA2002615_HPP -# define OBJECT_CORE_DWA2002615_HPP - -# include - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include -# include - -namespace boost { namespace python { - -namespace converter -{ - template struct arg_to_python; -} - -// Put this in an inner namespace so that the generalized operators won't take over -namespace api -{ - -// This file contains the definition of the object class and enough to -// construct/copy it, but not enough to do operations like -// attribute/item access or addition. - - template class proxy; - - struct const_attribute_policies; - struct attribute_policies; - struct const_item_policies; - struct item_policies; - struct const_slice_policies; - struct slice_policies; - - typedef proxy const_object_attribute; - typedef proxy object_attribute; - typedef proxy const_object_item; - typedef proxy object_item; - typedef proxy const_object_slice; - typedef proxy object_slice; - - // - // is_proxy -- proxy type detection - // -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct is_proxy - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; - template - struct is_proxy > - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; -# else - typedef char yes_proxy; - typedef char (&no_proxy)[2]; - template - yes_proxy is_proxy_helper(boost::type >*); - no_proxy is_proxy_helper(...); - template - struct is_proxy - { - BOOST_STATIC_CONSTANT( - bool, value = (sizeof(is_proxy_helper((boost::type*)0)) - == sizeof(yes_proxy))); - }; -# endif - - template struct object_initializer; - - class object; - typedef PyObject* (object::*bool_type)() const; - - template - class object_operators - { - protected: -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef object const& object_cref; -# else - typedef object object_cref; -# endif - public: - // function call - // - object operator()() const; - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - - // truth value testing - // - operator bool_type() const; - bool operator!() const; // needed for vc6 - - // Attribute access - // - const_object_attribute attr(char const*) const; - object_attribute attr(char const*); - - // item access - // - const_object_item operator[](object_cref) const; - object_item operator[](object_cref); - - template - const_object_item - operator[](T const& key) const -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return (*this)[object(key)]; - } -# endif - - template - object_item - operator[](T const& key) -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return (*this)[object(key)]; - } -# endif - - // slicing - // - const_object_slice slice(object_cref, object_cref) const; - object_slice slice(object_cref, object_cref); - - const_object_slice slice(slice_nil, object_cref) const; - object_slice slice(slice_nil, object_cref); - - const_object_slice slice(object_cref, slice_nil) const; - object_slice slice(object_cref, slice_nil); - - template - const_object_slice - slice(T const& start, V const& end) const -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return this->slice( - slice_bound::type(start) - , slice_bound::type(end)); - } -# endif - - template - object_slice - slice(T const& start, V const& end) -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return this->slice( - slice_bound::type(start) - , slice_bound::type(end)); - } -# endif - private: - // there is a confirmed CWPro8 codegen bug here. We prevent the - // early destruction of a temporary by binding a named object - // instead. -# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3003 - typedef object const& object_cref2; -# else - typedef object const object_cref2; -# endif - }; - - // VC6 and VC7 require this base class in order to generate the - // correct copy constructor for object. We can't define it there - // explicitly or it will complain of ambiguity. - struct object_base : object_operators - { - // copy constructor without NULL checking, for efficiency. - inline object_base(object_base const&); - inline object_base(PyObject* ptr); - - object_base& operator=(object_base const& rhs); - ~object_base(); - - // Underlying object access -- returns a borrowed reference - PyObject* ptr() const; - - private: - PyObject* m_ptr; - }; - - class object : public object_base - { - public: - // default constructor creates a None object - object(); - // explicit conversion from any C++ object to Python - template - explicit object(T const& x) - : object_base( - object_initializer< - is_proxy::value - , converter::is_object_manager::value - >::get(&x, detail::convertible::check(&x))) - { - } - - // Throw error_already_set() if the handle is null. - BOOST_PYTHON_DECL explicit object(handle<> const&); - - public: // implementation detail -- for internal use only - explicit object(detail::borrowed_reference); - explicit object(detail::new_reference); - explicit object(detail::new_non_null_reference); - }; - - // Macros for forwarding constructors in classes derived from - // object. Derived classes will usually want these as an - // implementation detail -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \ - inline explicit derived(python::detail::borrowed_reference p) \ - : base(p) {} \ - inline explicit derived(python::detail::new_reference p) \ - : base(p) {} \ - inline explicit derived(python::detail::new_non_null_reference p) \ - : base(p) {} - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_ -# else - // MSVC6 has a bug which causes an explicit template constructor to - // be preferred over an appropriate implicit conversion operator - // declared on the argument type. Normally, that would cause a - // runtime failure when using extract to extract a type with a - // templated constructor. This additional constructor will turn that - // runtime failure into an ambiguity error at compile-time due to - // the lack of partial ordering, or at least a link-time error if no - // generalized template constructor is declared. -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \ - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \ - template \ - explicit derived(extract const&); -# endif - - // - // object_initializer -- get the handle to construct the object with, - // based on whether T is a proxy or derived from object - // - template - struct object_initializer - { - static PyObject* - get(object const* x, detail::yes_convertible) - { - return python::incref(x->ptr()); - } - - template - static PyObject* - get(T const* x, detail::no_convertible) - { - return python::incref(converter::arg_to_python(*x).get()); - } - }; - - template <> - struct object_initializer - { - template - static PyObject* - get(proxy const* x, detail::no_convertible) - { - return python::incref(x->operator object().ptr()); - } - }; - - template <> - struct object_initializer - { - template - static PyObject* - get(T const* x, ...) - { - return python::incref(get_managed_object(*x, tag)); - } - }; - - template <> - struct object_initializer - {}; // empty implementation should cause an error -} -using api::object; -template struct extract; - -// -// implementation -// - -inline object::object() - : object_base(python::incref(Py_None)) -{} - -// copy constructor without NULL checking, for efficiency -inline api::object_base::object_base(object_base const& rhs) - : m_ptr(python::incref(rhs.m_ptr)) -{} - -inline api::object_base::object_base(PyObject* p) - : m_ptr(p) -{} - -inline api::object_base& api::object_base::operator=(api::object_base const& rhs) -{ - Py_INCREF(rhs.m_ptr); - Py_DECREF(this->m_ptr); - this->m_ptr = rhs.m_ptr; - return *this; -} - -inline api::object_base::~object_base() -{ - Py_DECREF(m_ptr); -} - -inline object::object(detail::borrowed_reference p) - : object_base(python::incref((PyObject*)p)) -{} - -inline object::object(detail::new_reference p) - : object_base(expect_non_null((PyObject*)p)) -{} - -inline object::object(detail::new_non_null_reference p) - : object_base((PyObject*)p) -{} - -inline PyObject* api::object_base::ptr() const -{ - return m_ptr; -} - -// -// Converter specialization implementations -// -namespace converter -{ - template struct object_manager_traits; - - template <> - struct object_manager_traits - { - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - static bool check(PyObject*) { return true; } - - static python::detail::new_non_null_reference adopt(PyObject* x) - { - return python::detail::new_non_null_reference(x); - } - }; -} - -inline PyObject* get_managed_object(object const& x, tag_t) -{ - return x.ptr(); -} - -}} // namespace boost::python - -#endif // OBJECT_CORE_DWA2002615_HPP diff --git a/include/boost/python/object_fwd.hpp b/include/boost/python/object_fwd.hpp deleted file mode 100644 index 8b0c093e..00000000 --- a/include/boost/python/object_fwd.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_FWD_DWA2002724_HPP -# define OBJECT_FWD_DWA2002724_HPP - -namespace boost { namespace python { -namespace api -{ - class object; -} -using api::object; -}} // namespace boost::python - -#endif // OBJECT_FWD_DWA2002724_HPP diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp deleted file mode 100755 index 436a671f..00000000 --- a/include/boost/python/object_items.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_ITEMS_DWA2002615_HPP -# define OBJECT_ITEMS_DWA2002615_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace api { - -struct const_item_policies -{ - typedef object key_type; - static object get(object const& target, object const& key); -}; - -struct item_policies : const_item_policies -{ - static object const& set(object const& target, object const& key, object const& value); - static void del(object const& target, object const& key); -}; - -// -// implementation -// -template -inline object_item -object_operators::operator[](object_cref key) -{ - object_cref2 x = *static_cast(this); - return object_item(x, key); -} - -template -inline const_object_item -object_operators::operator[](object_cref key) const -{ - object_cref2 x = *static_cast(this); - return const_object_item(x, key); -} - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 -template -template -inline const_object_item -object_operators::operator[](T const& key) const -{ - return (*this)[object(key)]; -} - -template -template -inline object_item -object_operators::operator[](T const& key) -{ - return (*this)[object(key)]; -} -# endif - - -inline object const_item_policies::get(object const& target, object const& key) -{ - return getitem(target, key); -} - -inline object const& item_policies::set( - object const& target - , object const& key - , object const& value) -{ - setitem(target, key, value); - return value; -} - -inline void item_policies::del( - object const& target - , object const& key) -{ - delitem(target, key); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_ITEMS_DWA2002615_HPP diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp deleted file mode 100644 index fb14d484..00000000 --- a/include/boost/python/object_operators.hpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_OPERATORS_DWA2002617_HPP -# define OBJECT_OPERATORS_DWA2002617_HPP - -# include -# include - -namespace boost { namespace python { namespace api { - -template -object object_operators::operator()() const -{ - object_cref2 f = *static_cast(this); - return call(f.ptr()); -} - - -template -inline -object_operators::operator bool_type() const -{ - object_cref2 x = *static_cast(this); - return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0; -} - -template -inline bool -object_operators::operator!() const -{ - object_cref2 x = *static_cast(this); - return !PyObject_IsTrue(x.ptr()); -} - -# define BOOST_PYTHON_COMPARE_OP(op, opid) \ -template \ -bool operator op(L const& l, R const& r) \ -{ \ - return PyObject_RichCompareBool( \ - object(l).ptr(), object(r).ptr(), opid); \ -} -BOOST_PYTHON_COMPARE_OP(>, Py_GT) -BOOST_PYTHON_COMPARE_OP(>=, Py_GE) -BOOST_PYTHON_COMPARE_OP(<, Py_LT) -BOOST_PYTHON_COMPARE_OP(<=, Py_LE) -BOOST_PYTHON_COMPARE_OP(==, Py_EQ) -BOOST_PYTHON_COMPARE_OP(!=, Py_NE) -# undef BOOST_PYTHON_COMPARE_OP - -# define BOOST_PYTHON_BINARY_OPERATOR(op) \ -BOOST_PYTHON_DECL object operator op(object const& l, object const& r); \ -template \ -object operator op(L const& l, R const& r) \ -{ \ - return object(l) op object(r); \ -} -BOOST_PYTHON_BINARY_OPERATOR(+) -BOOST_PYTHON_BINARY_OPERATOR(-) -BOOST_PYTHON_BINARY_OPERATOR(*) -BOOST_PYTHON_BINARY_OPERATOR(/) -BOOST_PYTHON_BINARY_OPERATOR(%) -BOOST_PYTHON_BINARY_OPERATOR(<<) -BOOST_PYTHON_BINARY_OPERATOR(>>) -BOOST_PYTHON_BINARY_OPERATOR(&) -BOOST_PYTHON_BINARY_OPERATOR(^) -BOOST_PYTHON_BINARY_OPERATOR(|) -# undef BOOST_PYTHON_BINARY_OPERATOR - - -# define BOOST_PYTHON_INPLACE_OPERATOR(op) \ -BOOST_PYTHON_DECL object& operator op(object& l, object const& r); \ -template \ -object& operator op(object& l, R const& r) \ -{ \ - return l op object(r); \ -} -BOOST_PYTHON_INPLACE_OPERATOR(+=) -BOOST_PYTHON_INPLACE_OPERATOR(-=) -BOOST_PYTHON_INPLACE_OPERATOR(*=) -BOOST_PYTHON_INPLACE_OPERATOR(/=) -BOOST_PYTHON_INPLACE_OPERATOR(%=) -BOOST_PYTHON_INPLACE_OPERATOR(<<=) -BOOST_PYTHON_INPLACE_OPERATOR(>>=) -BOOST_PYTHON_INPLACE_OPERATOR(&=) -BOOST_PYTHON_INPLACE_OPERATOR(^=) -BOOST_PYTHON_INPLACE_OPERATOR(|=) -# undef BOOST_PYTHON_INPLACE_OPERATOR - -}}} // namespace boost::python - -#endif // OBJECT_OPERATORS_DWA2002617_HPP diff --git a/include/boost/python/object_protocol.hpp b/include/boost/python/object_protocol.hpp deleted file mode 100755 index 8698dd9f..00000000 --- a/include/boost/python/object_protocol.hpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_PROTOCOL_DWA2002615_HPP -# define OBJECT_PROTOCOL_DWA2002615_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace api { - -template -object getattr(Target const& target, Key const& key) -{ - return getattr(object(target), object(key)); -} - -template -object getattr(Target const& target, Key const& key, Default const& default_) -{ - return getattr(object(target), object(key), object(default_)); -} - - -template -void setattr(object const& target, Key const& key, Value const& value) -{ - setattr(target, object(key), object(value)); -} - -template -void delattr(object const& target, Key const& key) -{ - delattr(target, object(key)); -} - -template -object getitem(Target const& target, Key const& key) -{ - return getitem(object(target), object(key)); -} - - -template -void setitem(object const& target, Key const& key, Value const& value) -{ - return setitem(target, object(key), object(value)); -} - -template -void delitem(object const& target, Key const& key) -{ - delitem(target, object(key)); -} - -template -object getslice(Target const& target, Begin const& begin, End const& end) -{ - return getslice(object(target), object(begin), object(end)); -} - -template -void setslice(object const& target, Begin const& begin, End const& end, Value const& value) -{ - setslice(target, object(begin), object(end), object(value)); -} - -template -void delslice(object const& target, Begin const& begin, End const& end) -{ - delslice(target, object(begin), object(end)); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_PROTOCOL_DWA2002615_HPP diff --git a/include/boost/python/object_protocol_core.hpp b/include/boost/python/object_protocol_core.hpp deleted file mode 100755 index 50d2f454..00000000 --- a/include/boost/python/object_protocol_core.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_PROTOCOL_CORE_DWA2002615_HPP -# define OBJECT_PROTOCOL_CORE_DWA2002615_HPP - -# include -# include - -namespace boost { namespace python { - -namespace api -{ - class object; - - BOOST_PYTHON_DECL object getattr(object const& target, object const& key); - BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_); - BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value); - BOOST_PYTHON_DECL void delattr(object const& target, object const& key); - - // These are defined for efficiency, since attributes are commonly - // accessed through literal strings. - BOOST_PYTHON_DECL object getattr(object const& target, char const* key); - BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_); - BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value); - BOOST_PYTHON_DECL void delattr(object const& target, char const* key); - - BOOST_PYTHON_DECL object getitem(object const& target, object const& key); - BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value); - BOOST_PYTHON_DECL void delitem(object const& target, object const& key); - - BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end); - BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value); - BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end); -} - -using api::getattr; -using api::setattr; -using api::delattr; - -using api::getitem; -using api::setitem; -using api::delitem; - -using api::getslice; -using api::setslice; -using api::delslice; - -}} // namespace boost::python - -#endif // OBJECT_PROTOCOL_CORE_DWA2002615_HPP diff --git a/include/boost/python/object_slices.hpp b/include/boost/python/object_slices.hpp deleted file mode 100644 index eb8dcb0b..00000000 --- a/include/boost/python/object_slices.hpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_SLICES_DWA2002615_HPP -# define OBJECT_SLICES_DWA2002615_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace api { - -struct const_slice_policies -{ - typedef std::pair, handle<> > key_type; - static object get(object const& target, key_type const& key); -}; - -struct slice_policies : const_slice_policies -{ - static object const& set(object const& target, key_type const& key, object const& value); - static void del(object const& target, key_type const& key); -}; - -// -// implementation -// -template -object_slice -object_operators::slice(object_cref start, object_cref finish) -{ - object_cref2 x = *static_cast(this); - return object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr()))); -} - -template -const_object_slice -object_operators::slice(object_cref start, object_cref finish) const -{ - object_cref2 x = *static_cast(this); - return const_object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr()))); -} - -template -object_slice -object_operators::slice(slice_nil, object_cref finish) -{ - object_cref2 x = *static_cast(this); - return object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr()))); -} - -template -const_object_slice -object_operators::slice(slice_nil, object_cref finish) const -{ - object_cref2 x = *static_cast(this); - return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr()))); -} - -template -object_slice -object_operators::slice(object_cref start, slice_nil) -{ - object_cref2 x = *static_cast(this); - return object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0))); -} - -template -const_object_slice -object_operators::slice(object_cref start, slice_nil) const -{ - object_cref2 x = *static_cast(this); - return const_object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0))); -} -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 -template -template -inline const_object_slice -object_operators::slice(T const& start, V const& end) const -{ - return this->slice( - typename slice_bound::type(start) - , typename slice_bound::type(end)); -} - -template -template -inline object_slice -object_operators::slice(T const& start, V const& end) -{ - return this->slice( - typename slice_bound::type(start) - , typename slice_bound::type(end)); -} -# endif - - -inline object const_slice_policies::get(object const& target, key_type const& key) -{ - return getslice(target, key.first, key.second); -} - -inline object const& slice_policies::set( - object const& target - , key_type const& key - , object const& value) -{ - setslice(target, key.first, key.second, value); - return value; -} - -inline void slice_policies::del( - object const& target - , key_type const& key) -{ - delslice(target, key.first, key.second); -} - -}}} // namespace boost::python::api - -#endif // OBJECT_SLICES_DWA2002615_HPP diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp deleted file mode 100644 index 3292efa7..00000000 --- a/include/boost/python/operators.hpp +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OPERATORS_DWA2002530_HPP -# define OPERATORS_DWA2002530_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // This is essentially the old v1 to_python(). It will be eliminated - // once the public interface for to_python is settled on. - template - PyObject* convert_result(T const& x) - { - return converter::arg_to_python(x).release(); - } - - // Operator implementation template declarations. The nested apply - // declaration here keeps MSVC6 happy. - template struct operator_l - { - template struct apply; - }; - - template struct operator_r - { - template struct apply; - }; - - template struct operator_1 - { - template struct apply; - }; - - // MSVC6 doesn't want us to do this sort of inheritance on a nested - // class template, so we use this layer of indirection to avoid - // ::template<...> on the nested apply functions below - template - struct operator_l_inner - : operator_l::template apply - {}; - - template - struct operator_r_inner - : operator_r::template apply - {}; - - template - struct operator_1_inner - : operator_1::template apply - {}; - - // Define three different binary_op templates which take care of - // these cases: - // self op self - // self op R - // L op self - // - // The inner apply metafunction is used to adjust the operator to - // the class type being defined. Inheritance of the outer class is - // simply used to provide convenient access to the operation's - // name(). - - // self op self - template - struct binary_op : operator_l - { - template - struct apply : operator_l_inner - { - }; - }; - - // self op R - template - struct binary_op_l : operator_l - { - template - struct apply : operator_l_inner - { - }; - }; - - // L op self - template - struct binary_op_r : operator_r - { - template - struct apply : operator_r_inner - { - }; - }; - - template - struct unary_op : operator_1 - { - template - struct apply : operator_1_inner - { - }; - }; - - // This type is what actually gets returned from operators used on - // self_t - template - struct operator_ - : mpl::if_< - is_same - , typename mpl::if_< - is_same - , binary_op - , binary_op_l::type> - >::type - , typename mpl::if_< - is_same - , unary_op - , binary_op_r::type> - >::type - >::type - { - }; -} - -# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \ -namespace detail \ -{ \ - template <> \ - struct operator_l \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* execute(L const& l, R const& r) \ - { \ - return detail::convert_result(expr); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ - \ - template <> \ - struct operator_r \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* execute(R const& r, L const& l) \ - { \ - return detail::convert_result(expr); \ - } \ - }; \ - static char const* name() { return "__" #rid "__"; } \ - }; \ -} - -# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ -BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ -namespace self_ns \ -{ \ - template \ - inline detail::operator_ \ - operator op(L const&, R const&) \ - { \ - return detail::operator_(); \ - } \ -} - -BOOST_PYTHON_BINARY_OPERATOR(add, radd, +) -BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -) -BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *) -BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /) -BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %) -BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<) -BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>) -BOOST_PYTHON_BINARY_OPERATOR(and, rand, &) -BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^) -BOOST_PYTHON_BINARY_OPERATOR(or, ror, |) -BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >) -BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=) -BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <) -BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) -BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) -BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) -# undef BOOST_PYTHON_BINARY_OPERATOR - -// pow isn't an operator in C++; handle it specially. -BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r)) -# undef BOOST_PYTHON_BINARY_OPERATION - -namespace self_ns -{ -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP - template - inline detail::operator_ - pow(L const&, R const&) - { - return detail::operator_(); - } -# else - // When there's no argument-dependent lookup, we need these - // overloads to handle the case when everything is imported into the - // global namespace. Note that the plain overload below does /not/ - // take const& arguments. This is needed by MSVC6 at least, or it - // complains of ambiguities, since there's no partial ordering. - inline detail::operator_ - pow(self_t, self_t) - { - return detail::operator_(); - } - template - inline detail::operator_ - pow(self_t const&, R const&) - { - return detail::operator_(); - } - template - inline detail::operator_ - pow(L const&, self_t const&) - { - return detail::operator_(); - } -# endif -} - - -# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \ -namespace detail \ -{ \ - template <> \ - struct operator_l \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* \ - execute(back_reference l, R const& r) \ - { \ - l.get() op r; \ - return python::incref(l.source().ptr()); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ -} \ -namespace self_ns \ -{ \ - template \ - inline detail::operator_ \ - operator op(self_t const&, R const&) \ - { \ - return detail::operator_(); \ - } \ -} - -BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=) -BOOST_PYTHON_INPLACE_OPERATOR(isub,-=) -BOOST_PYTHON_INPLACE_OPERATOR(imul,*=) -BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=) -BOOST_PYTHON_INPLACE_OPERATOR(imod,%=) -BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=) -BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=) -BOOST_PYTHON_INPLACE_OPERATOR(iand,&=) -BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=) -BOOST_PYTHON_INPLACE_OPERATOR(ior,|=) - -# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \ -namespace detail \ -{ \ - template <> \ - struct operator_1 \ - { \ - template \ - struct apply \ - { \ - static PyObject* execute(T const& x) \ - { \ - return detail::convert_result(op(x)); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ -} \ -namespace self_ns \ -{ \ - inline detail::operator_ \ - func_name(self_t const&) \ - { \ - return detail::operator_(); \ - } \ -} -# undef BOOST_PYTHON_INPLACE_OPERATOR - -BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-) -BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+) -BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs) -BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~) -BOOST_PYTHON_UNARY_OPERATOR(int, long, int_) -BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) -BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) -BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_) -BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str) -# undef BOOST_PYTHON_UNARY_OPERATOR - -}} // namespace boost::python - -# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -using boost::python::self_ns::abs; -using boost::python::self_ns::int_; -using boost::python::self_ns::long_; -using boost::python::self_ns::float_; -using boost::python::self_ns::complex_; -using boost::python::self_ns::str; -using boost::python::self_ns::pow; -# endif - -#endif // OPERATORS_DWA2002530_HPP diff --git a/include/boost/python/other.hpp b/include/boost/python/other.hpp deleted file mode 100755 index 0142da34..00000000 --- a/include/boost/python/other.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef OTHER_DWA20020601_HPP -# define OTHER_DWA20020601_HPP -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -# if _MSC_VER+0 >= 1020 -# pragma once -# endif - -# include - -namespace boost { namespace python { - -template struct other -{ - typedef T type; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace detail -{ - template - class is_other - { - public: - BOOST_STATIC_CONSTANT(bool, value = false); - }; - - template - class is_other > - { - public: - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template - class unwrap_other - { - public: - typedef T type; - }; - - template - class unwrap_other > - { - public: - typedef T type; - }; -} -# else // no partial specialization - -}} // namespace boost::python - -#include - -namespace boost { namespace python { - -namespace detail -{ - typedef char (&yes_other_t)[1]; - typedef char (&no_other_t)[2]; - - no_other_t is_other_test(...); - - template - yes_other_t is_other_test(type< other >); - - template - struct other_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct other_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; - - template - class is_other - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_other_test(type())) - == sizeof(detail::yes_other_t))); - }; - - template - class unwrap_other - : public detail::other_unwrapper< - is_other::value - >::template apply - {}; -} - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}} // namespace boost::python - -#endif // #ifndef OTHER_DWA20020601_HPP diff --git a/include/boost/python/overloads.hpp b/include/boost/python/overloads.hpp deleted file mode 100644 index 50fc2497..00000000 --- a/include/boost/python/overloads.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OVERLOADS_DWA2002101_HPP -# define OVERLOADS_DWA2002101_HPP - -# include -# include - -#endif // OVERLOADS_DWA2002101_HPP diff --git a/include/boost/python/pointee.hpp b/include/boost/python/pointee.hpp deleted file mode 100644 index d62bab54..00000000 --- a/include/boost/python/pointee.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef POINTEE_DWA2002323_HPP -# define POINTEE_DWA2002323_HPP - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct pointee_impl - { - template struct apply : remove_pointer {}; - }; - - template <> - struct pointee_impl - { - template struct apply - { - typedef typename T::element_type type; - }; - }; -} - -template -struct pointee - : detail::pointee_impl::value>::template apply -{ -}; - -}} // namespace boost::python::detail - -#endif // POINTEE_DWA2002323_HPP diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp deleted file mode 100755 index 1818fa27..00000000 --- a/include/boost/python/proxy.hpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PROXY_DWA2002615_HPP -# define PROXY_DWA2002615_HPP -# include -# include - -namespace boost { namespace python { namespace api { - -template -class proxy : public object_operators > -{ - typedef typename Policies::key_type key_type; - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef proxy const& assignment_self; -# else - typedef proxy assignment_self; -# endif - public: - proxy(object const& target, key_type const& key); - operator object() const; - - // to support a[b] = c[d] - proxy const& operator=(assignment_self) const; - - template - inline proxy const& operator=(T const& rhs) const - { - Policies::set(m_target, m_key, object(rhs)); - return *this; - } - - public: // implementation detail - void del() const; - - private: - object m_target; - key_type m_key; -}; - - -template -inline void del(proxy const& x) -{ - x.del(); -} - -// -// implementation -// - -template -inline proxy::proxy(object const& target, key_type const& key) - : m_target(target), m_key(key) -{} - -template -inline proxy::operator object() const -{ - return Policies::get(m_target, m_key); -} - -// to support a[b] = c[d] -template -inline proxy const& proxy::operator=(typename proxy::assignment_self rhs) const -{ - return *this = python::object(rhs); -} - -# define BOOST_PYTHON_PROXY_INPLACE(op) \ -template \ -proxy const& operator op(proxy const& lhs, R const& rhs) \ -{ \ - object old(lhs); \ - return lhs = (old op rhs); \ -} -BOOST_PYTHON_PROXY_INPLACE(+=) -BOOST_PYTHON_PROXY_INPLACE(-=) -BOOST_PYTHON_PROXY_INPLACE(*=) -BOOST_PYTHON_PROXY_INPLACE(/=) -BOOST_PYTHON_PROXY_INPLACE(%=) -BOOST_PYTHON_PROXY_INPLACE(<<=) -BOOST_PYTHON_PROXY_INPLACE(>>=) -BOOST_PYTHON_PROXY_INPLACE(&=) -BOOST_PYTHON_PROXY_INPLACE(^=) -BOOST_PYTHON_PROXY_INPLACE(|=) -# undef BOOST_PYTHON_PROXY_INPLACE - -template -inline void proxy::del() const -{ - Policies::del(m_target, m_key); -} - -}}} // namespace boost::python::api - -#endif // PROXY_DWA2002615_HPP diff --git a/include/boost/python/ptr.hpp b/include/boost/python/ptr.hpp deleted file mode 100644 index dd37f58b..00000000 --- a/include/boost/python/ptr.hpp +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef PTR_DWA20020601_HPP -# define PTR_DWA20020601_HPP -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -// -// Based on boost/ref.hpp, thus: -// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) -// Copyright (C) 2001 Peter Dimov - -# if _MSC_VER+0 >= 1020 -# pragma once -# endif - -# include -# include - -namespace boost { namespace python { - -template class pointer_wrapper -{ - public: - typedef Ptr type; - - explicit pointer_wrapper(Ptr x): p_(x) {} - operator Ptr() const { return p_; } - Ptr get() const { return p_; } - private: - Ptr p_; -}; - -template -inline pointer_wrapper ptr(T t) -{ - return pointer_wrapper(t); -} - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -class is_pointer_wrapper - : public mpl::false_ -{ -}; - -template -class is_pointer_wrapper > - : public mpl::true_ -{ -}; - -template -class unwrap_pointer -{ - public: - typedef T type; -}; - -template -class unwrap_pointer > -{ - public: - typedef T type; -}; -# else // no partial specialization - -}} // namespace boost::python - -#include - -namespace boost { namespace python { - -namespace detail -{ - typedef char (&yes_pointer_wrapper_t)[1]; - typedef char (&no_pointer_wrapper_t)[2]; - - no_pointer_wrapper_t is_pointer_wrapper_test(...); - - template - yes_pointer_wrapper_t is_pointer_wrapper_test(boost::type< pointer_wrapper >); - - template - struct pointer_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct pointer_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; -} - -template -class is_pointer_wrapper -{ - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_pointer_wrapper_test(boost::type())) - == sizeof(detail::yes_pointer_wrapper_t))); - typedef mpl::bool_ type; -}; - -template -class unwrap_pointer - : public detail::pointer_unwrapper< - is_pointer_wrapper::value - >::template apply -{}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}} // namespace boost::python - -#endif // #ifndef PTR_DWA20020601_HPP diff --git a/include/boost/python/raw_function.hpp b/include/boost/python/raw_function.hpp deleted file mode 100755 index 3a28d127..00000000 --- a/include/boost/python/raw_function.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef RAW_FUNCTION_DWA200336_HPP -# define RAW_FUNCTION_DWA200336_HPP - -# include -# include -# include - -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct raw_dispatcher - { - raw_dispatcher(F f) : f(f) {} - - PyObject* operator()(PyObject* args, PyObject* keywords) - { - return incref( - object( - f(tuple(borrowed_reference(args)), dict(borrowed_reference(keywords))) - ).ptr() - ); - } - private: - F f; - }; - - object BOOST_PYTHON_DECL make_raw_function(objects::py_function, std::size_t min_args); -} - -template -object raw_function(F f, std::size_t min_args = 0) -{ - return detail::make_raw_function(detail::raw_dispatcher(f), min_args); -} - -}} // namespace boost::python - -#endif // RAW_FUNCTION_DWA200336_HPP diff --git a/include/boost/python/refcount.hpp b/include/boost/python/refcount.hpp deleted file mode 100755 index dce6b266..00000000 --- a/include/boost/python/refcount.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REFCOUNT_DWA2002615_HPP -# define REFCOUNT_DWA2002615_HPP - -# include -# include - -namespace boost { namespace python { - -template -inline T* incref(T* p) -{ - Py_INCREF(python::upcast(p)); - return p; -} - -template -inline T* xincref(T* p) -{ - Py_XINCREF(python::upcast(p)); - return p; -} - -template -inline void decref(T* p) -{ - Py_DECREF(python::upcast(p)); -} - -template -inline void xdecref(T* p) -{ - Py_XDECREF(python::upcast(p)); -} - -}} // namespace boost::python - -#endif // REFCOUNT_DWA2002615_HPP diff --git a/include/boost/python/reference_existing_object.hpp b/include/boost/python/reference_existing_object.hpp deleted file mode 100644 index e16dcf18..00000000 --- a/include/boost/python/reference_existing_object.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REFERENCE_EXISTING_OBJECT_DWA200222_HPP -# define REFERENCE_EXISTING_OBJECT_DWA200222_HPP -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct reference_existing_object_requires_a_pointer_or_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template struct to_python_value; - -struct reference_existing_object -{ - template - struct apply - { - BOOST_STATIC_CONSTANT( - bool, ok = is_pointer::value || is_reference::value); - - typedef typename mpl::if_c< - ok - , to_python_indirect - , detail::reference_existing_object_requires_a_pointer_or_reference_return_type - >::type type; - }; -}; - -}} // namespace boost::python - -#endif // REFERENCE_EXISTING_OBJECT_DWA200222_HPP diff --git a/include/boost/python/return_by_value.hpp b/include/boost/python/return_by_value.hpp deleted file mode 100644 index 97f9f245..00000000 --- a/include/boost/python/return_by_value.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BY_VALUE_DWA20021015_HPP -# define BY_VALUE_DWA20021015_HPP - -# include -# include -# include - -namespace boost { namespace python { - -struct return_by_value -{ - template - struct apply - { - typedef to_python_value< - typename add_reference< - typename add_const::type - >::type - > type; - }; -}; - -}} // namespace boost::python - -#endif // BY_VALUE_DWA20021015_HPP diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp deleted file mode 100644 index 7e350d77..00000000 --- a/include/boost/python/return_internal_reference.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef RETURN_INTERNAL_REFERENCE_DWA2002131_HPP -# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct return_internal_reference_owner_arg_must_be_greater_than_zero -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template -struct return_internal_reference - : with_custodian_and_ward_postcall<0, owner_arg, BasePolicy_> -{ - private: - BOOST_STATIC_CONSTANT(bool, legal = owner_arg > 0); - public: - typedef typename mpl::if_c< - legal - , reference_existing_object - , detail::return_internal_reference_owner_arg_must_be_greater_than_zero - >::type result_converter; -}; - -}} // namespace boost::python - -#endif // RETURN_INTERNAL_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/return_value_policy.hpp b/include/boost/python/return_value_policy.hpp deleted file mode 100644 index 0f3c00fe..00000000 --- a/include/boost/python/return_value_policy.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef RETURN_VALUE_POLICY_DWA2002131_HPP -# define RETURN_VALUE_POLICY_DWA2002131_HPP -# include - -namespace boost { namespace python { - -template -struct return_value_policy : BasePolicy_ -{ - typedef ResultConverterGenerator result_converter; -}; - -}} // namespace boost::python - -#endif // RETURN_VALUE_POLICY_DWA2002131_HPP diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp deleted file mode 100644 index 2e208bfc..00000000 --- a/include/boost/python/scope.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SCOPE_DWA2002724_HPP -# define SCOPE_DWA2002724_HPP - -# include -# include -# include - -namespace boost { namespace python { - -class BOOST_PYTHON_DECL scope - : public object -{ - public: - inline scope(scope const&); - inline scope(object const&); - inline scope(); - inline ~scope(); - - private: // data members - PyObject* m_previous_scope; - - private: // unimplemented functions - void operator=(scope const&); - - private: // static members - - // Use a PyObject* to avoid problems with static destruction after Py_Finalize - static PyObject* current_scope; -}; - -inline scope::scope(object const& new_scope) - : object(new_scope) - , m_previous_scope(current_scope) -{ - current_scope = python::incref(new_scope.ptr()); -} - -inline scope::scope() - : object(detail::borrowed_reference( - current_scope ? current_scope : Py_None - )) - , m_previous_scope(python::xincref(current_scope)) -{ -} - -inline scope::~scope() -{ - python::xdecref(current_scope); - current_scope = m_previous_scope; -} - -namespace converter -{ - template <> - struct object_manager_traits - : object_manager_traits - { - }; -} - -// Placing this after the specialization above suppresses a CWPro8.3 bug -inline scope::scope(scope const& new_scope) - : object(new_scope) - , m_previous_scope(current_scope) -{ - current_scope = python::incref(new_scope.ptr()); -} - -}} // namespace boost::python - -#endif // SCOPE_DWA2002724_HPP diff --git a/include/boost/python/self.hpp b/include/boost/python/self.hpp deleted file mode 100755 index c7d3f670..00000000 --- a/include/boost/python/self.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SELF_DWA2002531_HPP -# define SELF_DWA2002531_HPP - -# include - -namespace boost { namespace python { - -//# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 -# define BOOST_PYTHON_SELF_IS_CLASS -//# endif - -// Sink self_t into its own namespace so that we have a safe place to -// put the completely general operator templates which operate on -// it. It is possible to avoid this, but it turns out to be much more -// complicated and finally GCC 2.95.2 chokes on it. -namespace self_ns -{ -# ifndef BOOST_PYTHON_SELF_IS_CLASS - enum self_t { self }; -# else - struct self_t {}; - extern BOOST_PYTHON_DECL self_t self; -# endif -} - -using self_ns::self_t; -using self_ns::self; - -}} // namespace boost::python - -#endif // SELF_DWA2002531_HPP diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp deleted file mode 100644 index 5b0f6026..00000000 --- a/include/boost/python/signature.hpp +++ /dev/null @@ -1,119 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, -// use, modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided "as is" -// without express or implied warranty, and with no claim as to its -// suitability for any purpose. -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(BOOST_PP_IS_ITERATING) - -# ifndef SIGNATURE_JDG20020813_HPP -# define SIGNATURE_JDG20020813_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -# include -# include -# include -# include - -# define BOOST_PYTHON_LIST_INC(n) \ - BOOST_PP_CAT(mpl::list, BOOST_PP_INC(n)) - -/////////////////////////////////////////////////////////////////////////////// -namespace boost { namespace python { namespace detail { - -/////////////////////////////////////////////////////////////////////////////// -// -// The following macros generate expansions for: -// -// template -// inline mpl::list -// get_signature(RT(*)(T0...TN)) -// { -// return mpl::list(); -// } -// -// And, for an appropriate assortment of cv-qualifications -// -// template -// inline mpl::list -// get_signature(RT(ClassT::*)(T0...TN) cv)) -// { -// return mpl::list(); -// } -// -// These functions extract the return type, class (for member -// functions) and arguments of the input signature and stuffs them in -// an mpl::list. Note that cv-qualification is dropped from the -// target class; that is a necessary sacrifice to ensure that an -// lvalue from_python converter is used. -// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) - -# include BOOST_PP_ITERATE() - -} - -}} // namespace boost::python - - -# undef BOOST_PYTHON_LIST_INC - -/////////////////////////////////////////////////////////////////////////////// -# endif // SIGNATURE_JDG20020813_HPP - -#elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING) - -# define N BOOST_PP_ITERATION() - -template < - class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> -inline BOOST_PYTHON_LIST_INC(N)< - RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T))) -{ - return BOOST_PYTHON_LIST_INC(N)< - RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) - >(); -} - -# undef N - -# define BOOST_PP_ITERATION_PARAMS_2 \ - (3, (0, 3, )) -# include BOOST_PP_ITERATE() - -#else - -# define N BOOST_PP_RELATIVE_ITERATION(1) -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_ITERATION()) - -template < - class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> -inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< - RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) -{ - return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< - RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) - >(); -} - -# undef Q -# undef N - -#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/slice_nil.hpp b/include/boost/python/slice_nil.hpp deleted file mode 100644 index cb169116..00000000 --- a/include/boost/python/slice_nil.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SLICE_NIL_DWA2002620_HPP -# define SLICE_NIL_DWA2002620_HPP - -namespace boost { namespace python { namespace api { - -class object; - -enum slice_nil -{ -# ifndef _ // Watch out for GNU gettext users, who #define _(x) - _ -# endif -}; - -template -struct slice_bound -{ - typedef object type; -}; - -template <> -struct slice_bound -{ - typedef slice_nil type; -}; - -} - -using api::slice_nil; -# ifndef _ // Watch out for GNU gettext users, who #define _(x) -using api::_; -# endif - -}} // namespace boost::python - -#endif // SLICE_NIL_DWA2002620_HPP diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp deleted file mode 100644 index 2ebae5e7..00000000 --- a/include/boost/python/str.hpp +++ /dev/null @@ -1,400 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef STR_20020703_HPP -#define STR_20020703_HPP - -#include -#include -#include - -// disable defines in provided by some system libraries -#undef isspace -#undef islower -#undef isalpha -#undef isdigit -#undef isalnum -#undef isupper - -namespace boost { namespace python { - -class str; - -namespace detail -{ - struct BOOST_PYTHON_DECL str_base : object - { - str capitalize() const; - - str center(object_cref width) const; - - long count(object_cref sub) const; - - long count(object_cref sub, object_cref start) const; - - long count(object_cref sub, object_cref start, object_cref end) const; - - object decode() const; - object decode(object_cref encoding) const; - - object decode(object_cref encoding, object_cref errors) const; - - object encode() const; - object encode(object_cref encoding) const; - object encode(object_cref encoding, object_cref errors) const; - - bool endswith(object_cref suffix) const; - - bool endswith(object_cref suffix, object_cref start) const; - bool endswith(object_cref suffix, object_cref start, object_cref end) const; - - str expandtabs() const; - str expandtabs(object_cref tabsize) const; - - long find(object_cref sub) const; - long find(object_cref sub, object_cref start) const; - - long find(object_cref sub, object_cref start, object_cref end) const; - - long index(object_cref sub) const; - - long index(object_cref sub, object_cref start) const; - long index(object_cref sub, object_cref start, object_cref end) const; - - bool isalnum() const; - bool isalpha() const; - bool isdigit() const; - bool islower() const; - bool isspace() const; - bool istitle() const; - bool isupper() const; - - str join(object_cref sequence) const; - - str ljust(object_cref width) const; - str lower() const; - str lstrip() const; - - str replace(object_cref old, object_cref new_) const; - str replace(object_cref old, object_cref new_, object_cref maxsplit) const; - long rfind(object_cref sub) const; - - long rfind(object_cref sub, object_cref start) const; - - long rfind(object_cref sub, object_cref start, object_cref end) const; - long rindex(object_cref sub) const; - long rindex(object_cref sub, object_cref start) const; - - - long rindex(object_cref sub, object_cref start, object_cref end) const; - - str rjust(object_cref width) const; - - str rstrip() const; - - list split() const; - list split(object_cref sep) const; - - list split(object_cref sep, object_cref maxsplit) const; - - - list splitlines() const; - list splitlines(object_cref keepends) const; - - bool startswith(object_cref prefix) const; - - - bool startswith(object_cref prefix, object_cref start) const; - bool startswith(object_cref prefix, object_cref start, object_cref end) const; - - str strip() const; - str swapcase() const; - str title() const; - - str translate(object_cref table) const; - - str translate(object_cref table, object_cref deletechars) const; - - - str upper() const; - - protected: - str_base(); // new str - - str_base(const char* s); // new str - explicit str_base(object_cref other); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str_base, object) - private: - static new_reference call(object const&); - }; -} - - -class str : public detail::str_base -{ - typedef detail::str_base base; - public: - str() {} // new str - - str(const char* s) : base(s) {} // new str - - template - explicit str(T const& other) - : base(object(other)) - { - } - - template - str center(T const& width) const - { - return base::center(object(width)); - } - - template - long count(T const& sub) const - { - return base::count(object(sub)); - } - - template - long count(T1 const& sub,T2 const& start) const - { - return base::count(object(sub), object(start)); - } - - template - long count(T1 const& sub,T2 const& start, T3 const& end) const - { - return base::count(object(sub), object(start)); - } - - object decode() const { return base::decode(); } - - template - object decode(T const& encoding) const - { - return base::decode(object(encoding)); - } - - template - object decode(T1 const& encoding, T2 const& errors) const - { - return base::decode(object(encoding),object(errors)); - } - - object encode() const { return base::encode(); } - - template - object encode(T const& encoding) const - { - return base::encode(object(encoding)); - } - - template - object encode(T1 const& encoding, T2 const& errors) const - { - return base::encode(object(encoding),object(errors)); - } - - template - bool endswith(T const& suffix) const - { - return base::endswith(object(suffix)); - } - - template - bool endswith(T1 const& suffix, T2 const& start) const - { - return base::endswith(object(suffix), object(start)); - } - - template - bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const - { - return base::endswith(object(suffix), object(start), object(end)); - } - - str expandtabs() const { return base::expandtabs(); } - - template - str expandtabs(T const& tabsize) const - { - return base::expandtabs(object(tabsize)); - } - - template - long find(T const& sub) const - { - return base::find(object(sub)); - } - - template - long find(T1 const& sub, T2 const& start) const - { - return base::find(object(sub), object(start)); - } - - template - long find(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::find(object(sub), object(start), object(end)); - } - - template - long index(T const& sub) const - { - return base::index(object(sub)); - } - - template - long index(T1 const& sub, T2 const& start) const - { - return base::index(object(sub), object(start)); - } - - template - long index(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::index(object(sub), object(start), object(end)); - } - - template - str join(T const& sequence) const - { - return base::join(object(sequence)); - } - - template - str ljust(T const& width) const - { - return base::ljust(object(width)); - } - - template - str replace(T1 const& old, T2 const& new_) const - { - return base::replace(object(old),object(new_)); - } - - template - str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const - { - return base::replace(object(old),object(new_), object(maxsplit)); - } - - template - long rfind(T const& sub) const - { - return base::rfind(object(sub)); - } - - template - long rfind(T1 const& sub, T2 const& start) const - { - return base::rfind(object(sub), object(start)); - } - - template - long rfind(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::rfind(object(sub), object(start), object(end)); - } - - template - long rindex(T const& sub) const - { - return base::rindex(object(sub)); - } - - template - long rindex(T1 const& sub, T2 const& start) const - { - return base::rindex(object(sub), object(start)); - } - - template - long rindex(T1 const& sub, T2 const& start, T3 const& end) const - { - return base::rindex(object(sub), object(start), object(end)); - } - - template - str rjust(T const& width) const - { - return base::rjust(object(width)); - } - - list split() const { return base::split(); } - - template - list split(T const& sep) const - { - return base::split(object(sep)); - } - - template - list split(T1 const& sep, T2 const& maxsplit) const - { - return base::split(object(sep), object(maxsplit)); - } - - list splitlines() const { return base::splitlines(); } - - template - list splitlines(T const& keepends) const - { - return base::splitlines(object(keepends)); - } - - template - bool startswith(T const& prefix) const - { - return base::startswith(object(prefix)); - } - - template - bool startswith(T1 const& prefix, T2 const& start) const - { - return base::startswith(object(prefix), object(start)); - } - - template - bool startswith(T1 const& prefix, T2 const& start, T3 const& end) const - { - return base::startswith(object(prefix), object(start), object(end)); - } - - template - str translate(T const& table) const - { - return base::translate(object(table)); - } - - template - str translate(T1 const& table, T2 const& deletechars) const - { - return base::translate(object(table), object(deletechars)); - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str, base) -}; - -// -// Converter Specializations -// -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyString_Type,str> - { - }; -} - -}} // namespace boost::python - -#endif // STR_20020703_HPP diff --git a/include/boost/python/tag.hpp b/include/boost/python/tag.hpp deleted file mode 100644 index c8ce6878..00000000 --- a/include/boost/python/tag.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TAG_DWA2002720_HPP -# define TAG_DWA2002720_HPP - -namespace boost { namespace python { - -// used only to prevent argument-dependent lookup from finding the -// wrong function in some cases. Cheaper than qualification. -enum tag_t { tag }; - -}} // namespace boost::python - -#endif // TAG_DWA2002720_HPP diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp deleted file mode 100644 index 86bf95a3..00000000 --- a/include/boost/python/to_python_converter.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_CONVERTER_DWA200221_HPP -# define TO_PYTHON_CONVERTER_DWA200221_HPP - -# include -# include -# include - -namespace boost { namespace python { - -template -struct to_python_converter -{ - to_python_converter(); -}; - -// -// implementation -// - -template -to_python_converter::to_python_converter() -{ - typedef converter::as_to_python_function< - T, Conversion - > normalized; - - converter::registry::insert( - &normalized::convert - , type_id()); -} - -}} // namespace boost::python - -#endif // TO_PYTHON_CONVERTER_DWA200221_HPP diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp deleted file mode 100644 index 215cb198..00000000 --- a/include/boost/python/to_python_indirect.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_INDIRECT_DWA200221_HPP -# define TO_PYTHON_INDIRECT_DWA200221_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template -struct to_python_indirect -{ - PyObject* operator()(T ptr) const; - private: - static PyTypeObject* type(); -}; - -// -// implementations -// -namespace detail -{ - struct make_owning_holder - { - typedef PyObject* result_type; - template - static result_type execute(T* p) - { - // can't use auto_ptr with Intel 5 and VC6 Dinkum library - // for some reason. We get link errors against the auto_ptr - // copy constructor. -# if defined(__ICL) && __ICL < 600 - typedef boost::shared_ptr smart_pointer; -# else - typedef std::auto_ptr smart_pointer; -# endif - typedef objects::pointer_holder holder_t; - - smart_pointer ptr(p); - return objects::make_ptr_instance::execute(ptr); - } - }; - - struct make_reference_holder - { - typedef PyObject* result_type; - template - static result_type execute(T* p) - { - typedef objects::pointer_holder holder_t; - return objects::make_ptr_instance::execute(p); - } - }; - - struct get_pointer_class - { - typedef PyTypeObject* result_type; - template - static result_type execute(T* p) - { - BOOST_STATIC_ASSERT(is_class::value); - return converter::registered::converters.class_object; - } - }; - - // null_pointer_to_none -- return none() for null pointers and 0 for all other types/values - // - // Uses simulated partial ordering - template - inline PyObject* null_pointer_to_none(T&, int) - { - return 0; - } - - // overload for pointers - template - inline PyObject* null_pointer_to_none(T* x, long) - { - return x == 0 ? python::detail::none() : 0; - } -} - -template -inline PyObject* to_python_indirect::operator()(T x) const -{ - BOOST_STATIC_ASSERT(is_pointer::value || is_reference::value); - - PyObject* const null_result = detail::null_pointer_to_none(x, 1L); - if (null_result != 0) - return null_result; - - return detail::unwind_type(x); -} - -template -inline PyTypeObject* to_python_indirect::type() -{ - return detail::unwind_type(); -} - -}} // namespace boost::python - -#endif // TO_PYTHON_INDIRECT_DWA200221_HPP diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp deleted file mode 100644 index 4af5c6f8..00000000 --- a/include/boost/python/to_python_value.hpp +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_VALUE_DWA200221_HPP -# define TO_PYTHON_VALUE_DWA200221_HPP - -# include -# include - -# include -# include -# include -# include -# include -# include - -# include - -# include - -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct object_manager_to_python_value - { - typedef typename add_reference< - typename add_const::type - >::type argument_type; - - PyObject* operator()(argument_type) const; - - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = false); - }; - - - template - struct registry_to_python_value - { - typedef typename add_reference< - typename add_const::type - >::type argument_type; - - PyObject* operator()(argument_type) const; - - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = true); - }; - - template - struct shared_ptr_to_python_value - { - typedef typename add_reference< - typename add_const::type - >::type argument_type; - - PyObject* operator()(argument_type) const; - - // This information helps make_getter() decide whether to try to - // return an internal reference or not. I don't like it much, - // but it will have to serve for now. - BOOST_STATIC_CONSTANT(bool, uses_registry = false); - }; -} - -template -struct to_python_value - : mpl::if_< - detail::value_is_shared_ptr - , detail::shared_ptr_to_python_value - , typename mpl::if_< - mpl::or_< - converter::is_object_manager - , converter::is_reference_to_object_manager - > - , detail::object_manager_to_python_value - , detail::registry_to_python_value - >::type - >::type -{ -}; - -// -// implementation -// -namespace detail -{ - template - inline PyObject* registry_to_python_value::operator()(argument_type x) const - { - return converter::registered::converters.to_python(&x); - } - - template - inline PyObject* object_manager_to_python_value::operator()(argument_type x) const - { - return python::upcast( - python::xincref( - get_managed_object(x, tag)) - ); - } - - template - inline PyObject* shared_ptr_to_python_value::operator()(argument_type x) const - { - return converter::shared_ptr_to_python(x); - } -} - -}} // namespace boost::python - -#endif // TO_PYTHON_VALUE_DWA200221_HPP diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp deleted file mode 100644 index 8e3cb210..00000000 --- a/include/boost/python/tuple.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TUPLE_20020706_HPP -#define TUPLE_20020706_HPP - -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace detail -{ - struct BOOST_PYTHON_DECL tuple_base : object - { - protected: - tuple_base(); - tuple_base(object_cref sequence); - - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple_base, object) - - private: - static detail::new_reference call(object const&); - }; -} - -class tuple : public detail::tuple_base -{ - typedef detail::tuple_base base; - public: - tuple() {} - - template - explicit tuple(T const& sequence) - : base(object(sequence)) - { - } - - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple, base) -}; - -// -// Converter Specializations // $$$ JDG $$$ moved here to prevent -// // G++ bug complaining specialization - // provided after instantiation -namespace converter -{ - template <> - struct object_manager_traits - : pytype_object_manager_traits<&PyTuple_Type,tuple> - { - }; -} - -// for completeness -inline tuple make_tuple() { return tuple(); } - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace boost::python - -#endif - diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp deleted file mode 100755 index d44ce26a..00000000 --- a/include/boost/python/type_id.hpp +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TYPE_ID_DWA2002517_HPP -# define TYPE_ID_DWA2002517_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// for this compiler at least, cross-shared-library type_info -// comparisons don't work, so use typeid(x).name() instead. It's not -// yet clear what the best default strategy is. -# if (defined(__GNUC__) && __GNUC__ >= 3) \ - || defined(_AIX) \ - || ( defined(__sgi) && defined(__host_mips)) -# define BOOST_PYTHON_TYPE_ID_NAME -# endif - -// type ids which represent the same information as std::type_info -// (i.e. the top-level reference and cv-qualifiers are stripped), but -// which works across shared libraries. -struct type_info : private totally_ordered -{ - inline type_info(std::type_info const& = typeid(void)); - - inline bool operator<(type_info const& rhs) const; - inline bool operator==(type_info const& rhs) const; - - char const* name() const; - friend BOOST_PYTHON_DECL std::ostream& operator<<( - std::ostream&, type_info const&); - - private: // data members -# ifdef BOOST_PYTHON_TYPE_ID_NAME - typedef char const* base_id_t; -# else - typedef std::type_info const* base_id_t; -# endif - - base_id_t m_base_type; -}; - -template -inline type_info type_id(boost::type* = 0) -{ - return type_info( -# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 700) - typeid(T) -# else // strip the decoration which msvc and Intel mistakenly leave in - python::detail::msvc_typeid() -# endif - ); -} - -# if defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -// Older EDG-based compilers seems to mistakenly distinguish "int" from -// "signed int", etc., but only in typeid() expressions. However -// though int == signed int, the "signed" decoration is propagated -// down into template instantiations. Explicit specialization stops -// that from taking hold. - -# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \ -template <> \ -inline type_info type_id(boost::type*) \ -{ \ - return type_info(typeid(T)); \ -} - -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short) -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int) -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long) -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG -BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long) -# endif -# undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID -# endif - - -inline type_info::type_info(std::type_info const& id) - : m_base_type( -# ifdef BOOST_PYTHON_TYPE_ID_NAME - id.name() -# else - &id -# endif - ) -{ -} - -inline bool type_info::operator<(type_info const& rhs) const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return std::strcmp(m_base_type, rhs.m_base_type) < 0; -# else - return m_base_type->before(*rhs.m_base_type); -# endif -} - -inline bool type_info::operator==(type_info const& rhs) const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return !std::strcmp(m_base_type, rhs.m_base_type); -# else - return *m_base_type == *rhs.m_base_type; -# endif -} - -inline char const* type_info::name() const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return m_base_type; -# else - return m_base_type->name(); -# endif -} - - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&); - -}} // namespace boost::python - -#endif // TYPE_ID_DWA2002517_HPP diff --git a/include/boost/python/with_custodian_and_ward.hpp b/include/boost/python/with_custodian_and_ward.hpp deleted file mode 100644 index 4d022448..00000000 --- a/include/boost/python/with_custodian_and_ward.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP -# define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP - -# include -# include - -namespace boost { namespace python { - -template -struct with_custodian_and_ward : BasePolicy_ -{ - static bool precall(PyObject* args); -}; - -template -struct with_custodian_and_ward_postcall : BasePolicy_ -{ - static PyObject* postcall(PyObject* args, PyObject* result); -}; - -// -// implementations -// -template -bool with_custodian_and_ward::precall(PyObject* args_) -{ - BOOST_STATIC_ASSERT(custodian != ward); - BOOST_STATIC_ASSERT(custodian > 0); - BOOST_STATIC_ASSERT(ward > 0); - - PyObject* patient = PyTuple_GetItem(args_, ward - 1); - if (patient == 0) return false; - PyObject* nurse = PyTuple_GetItem(args_, custodian - 1); - if (nurse == 0) return false; - - PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient); - if (life_support == 0) - return false; - - bool result = BasePolicy_::precall(args_); - - if (!result) - Py_XDECREF(life_support); - - return result; -} - -template -PyObject* with_custodian_and_ward_postcall::postcall(PyObject* args_, PyObject* result) -{ - BOOST_STATIC_ASSERT(custodian != ward); - - PyObject* patient = ward > 0 ? PyTuple_GetItem(args_, ward - 1) : result; - if (patient == 0) return 0; - - PyObject* nurse = custodian > 0 ? PyTuple_GetItem(args_, custodian - 1) : result; - if (nurse == 0) return 0; - - result = BasePolicy_::postcall(args_, result); - if (result == 0) - return 0; - - if (python::objects::make_nurse_and_patient(nurse, patient) == 0) - { - Py_XDECREF(result); - return 0; - } - return result; -} - -}} // namespace boost::python - -#endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP diff --git a/index.html b/index.html deleted file mode 100644 index dff3b20f..00000000 --- a/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - -Automatic redirection failed, please go to -doc/index.html. - - \ No newline at end of file diff --git a/pyste/README b/pyste/README deleted file mode 100644 index b0cc7d36..00000000 --- a/pyste/README +++ /dev/null @@ -1,31 +0,0 @@ -Pyste - Python Semi-Automatic Exporter -====================================== - -Pyste is a Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple interface file, which following the -Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code. - -The documentation can be found in the file index.html accompaning this README. - -Enjoy! -Bruno da Silva de Oliveira (nicodemus@globalite.com.br) - -Thanks -====== - -- David Abrahams, creator of Boost.Python, for tips on the syntax of the interface - file and support. -- Marcelo Camelo, for design tips, support and inspiration for this project. - Also, the name was his idea. 8) -- Brad King, creator of the excellent GCCXML (http://www.gccxml.org) -- Fredrik Lundh, creator of the elementtree library (http://effbot.org) - -Bugs -==== - -Pyste is a young tool, so please help it to get better! Send bug reports to -nicodemus@globalite.com.br, accompaining the stack trace in case of exceptions. -If possible, run pyste with --debug, and send the resulting xmls too (pyste -will output a xml file with the same of each header it parsed). diff --git a/pyste/doc/exporting_all_declarations_from_a_header.html b/pyste/doc/exporting_all_declarations_from_a_header.html deleted file mode 100644 index 4f2418f5..00000000 --- a/pyste/doc/exporting_all_declarations_from_a_header.html +++ /dev/null @@ -1,76 +0,0 @@ - - - -Exporting All Declarations from a Header - - - - - - - - - -
- - Exporting All Declarations from a Header -
-
- - - - - - -
-

-Pyste also supports a mechanism to export all declarations found in a header -file. Suppose again our file, hello.h:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} 
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-    enum choice { red, blue };
-    
-    void show(choice c) { std::cout << "value: " << (int)c << std::endl; } 
-
-

-You can just use the AllFromHeader construct:

-
-    hello = AllFromHeader("hello.h")
-
-

-this will export all the declarations found in hello.h, which is equivalent -to write:

-
-    Class("World", "hello.h")
-    Enum("choice", "hello.h")
-    Function("show", "hello.h")
-
-

-Note that you can still use the functions rename, set_policy, exclude, etc. Just access -the members of the header object like this:

-
-    rename(hello.World.greet, "Greet")
-    exclude(hello.World.set, "Set")
-
- - - - - - -
-
-
- - diff --git a/pyste/doc/introduction.html b/pyste/doc/introduction.html deleted file mode 100644 index ffb50e7e..00000000 --- a/pyste/doc/introduction.html +++ /dev/null @@ -1,74 +0,0 @@ - - - -Introduction - - - - - - - - - -
- - Introduction -
-
- - - - - - -
-

What is Pyste?

-Pyste is a -Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple interface file, which following the - -Boost.Python's philosophy, is simple Python code. Pyste then uses -GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code.

-

Example

-Let's borrow the class World from the -tutorial:

-
-    struct World
-    {
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-

-Here's the interface file for it, named world.pyste:

-
-    Class("World", "world.h")
-
-

-and that's it!

-

-The next step is invoke pyste in the command-line:

-
python pyste.py --module=hello world.pyste

-this will create a file "hello.cpp" in the directory where the command was -run.

-

-Pyste supports the following features:

-
  • Functions
  • Classes
  • Class Templates
  • Virtual Methods
  • Overloading
  • Attributes
  • Enums (both "free" enums and class enums)
  • Nested Classes
- - - - - -
-
-
- - diff --git a/pyste/doc/policies.html b/pyste/doc/policies.html deleted file mode 100644 index 2869889f..00000000 --- a/pyste/doc/policies.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Policies - - - - - - - - - - -
- - Policies -
-
- - - - - - -
-

-Even thought Pyste can identify various elements in the C++ code, like virtual -methods, attributes, and so on, one thing that it can't do is to guess the -semantics of functions that return pointers or references. In this case, the -user must manually specify the policy. Policies are explained in the - -tutorial.

-

-The policies in Pyste are named exactly as in -Boost.Python, only the syntax is -slightly different. For instance, this policy:

-
-    return_internal_reference<1, with_custodian_and_ward<1, 2> >()
-
-

-becomes in Pyste:

-
-    return_internal_reference(1, with_custodian_and_ward(1, 2))
-
-

-The user can specify policies for functions and methods with the set_policy -function:

-
-    set_policy(f, return_internal_reference())
-    set_policy(C.foo, return_value_policy(manage_new_object))
-
- - - - -
- - What if a function or method needs a policy and the user -doesn't set one?

-If a function/method needs a policy and one was not set, Pyste will issue a error. -The user should then go in the interface file and set the policy for it, -otherwise the generated cpp won't compile. -
- - - - - - -
-
-
- - diff --git a/pyste/doc/pyste.txt b/pyste/doc/pyste.txt deleted file mode 100644 index b6fbb281..00000000 --- a/pyste/doc/pyste.txt +++ /dev/null @@ -1,370 +0,0 @@ -[doc Pyste Documentation] - -[def GCCXML [@http://www.gccxml.org GCCXML]] -[def Boost.Python [@../../index.html Boost.Python]] - -[page Introduction] - -[h2 What is Pyste?] - -Pyste is a Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple ['interface file], which following the -Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code. - -[h2 Example] - -Let's borrow the class [^World] from the [@../../doc/tutorial/doc/exposing_classes.html tutorial]: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -Here's the interface file for it, named [^world.pyste]: - - Class("World", "world.h") - -and that's it! - -The next step is invoke pyste in the command-line: - -[pre python pyste.py --module=hello world.pyste] - -this will create a file "[^hello.cpp]" in the directory where the command was -run. - -Pyste supports the following features: - -* Functions -* Classes -* Class Templates -* Virtual Methods -* Overloading -* Attributes -* Enums (both "free" enums and class enums) -* Nested Classes - -[page Running Pyste] - -To run pyste, you will need: - -* Python 2.2, avaiable at [@http://www.python.org python's website]. -* The great [@http://effbot.org elementtree] library, from Fredrik Lundh. -* The excellent GCCXML, from Brad King. - -Installation for the tools is avaiable in their respective webpages. - -[blurb -[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so -that pyste can call it. How to do this varies from platform to platform. -] - -[h2 Ok, now what?] - -Well, now let's fire it up: - -[pre -''' ->python pyste.py - -Usage: - pyste [options] --module= interface-files - -where options are: - -I add an include path - -D define symbol - --no-using do not declare "using namespace boost"; - use explicit declarations instead - --pyste-ns= set the namespace where new types will be declared; - default is "pyste" -''' -] - -Options explained: - -The [^-I] and [^-D] are preprocessor flags, which are needed by gccxml to parse the header files correctly and by pyste to find the header files declared in the -interface files. - -[^--no-using] tells pyste to don't declare "[^using namespace boost;]" in the -generated cpp, using the namespace boost::python explicitly in all declarations. -Use only if you're having a name conflict in one of the files. - -Use [^--pyste-ns] to change the namespace where new types are declared (for -instance, the virtual wrappers). Use only if one of your header files declare a -namespace named "pyste" and this is causing conflicts. - -So, the usage is simple enough: - -[pre >python pyste.py --module=mymodule file.pyste file2.pyste ...] - -will generate a file [^mymodule.cpp] in the same dir where the command was -executed. Now you can compile the file using the same instructions of the -[@../../doc/tutorial/doc/building_hello_world.html tutorial]. - -[h2 Wait... how do I set those I and D flags?] - -Don't worry: normally GCCXML is already configured correctly for your plataform, -so the search path to the standard libraries and the standard defines should -already be set. You only have to set the paths to other libraries that your code -needs, like Boost, for example. - -Plus, Pyste automatically uses the contents of the environment variable -[^INCLUDE] if it exists. Visual C++ users should run the [^Vcvars32.bat] file, -which for Visual C++ 6 is normally located at: - - C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat - -with that, you should have little trouble setting up the flags. - -[page The Interface Files] - -The interface files are the heart of Pyste. The user creates one or more -interface files declaring the classes and functions he wants to export, and then -invokes pyste passing the interface files to it. Pyste then generates a single -cpp file with Boost.Python code, with all the classes and functions exported. - -Besides declaring the classes and functions, the user has a number of other -options, like renaming classes and methods, excluding methods and attributes, -and so on. - -[h2 Basics] - -Suppose we have a class and some functions that we want to expose to Python -declared in the header [^hello.h]: - - struct World - { - World(std::string msg): msg(msg) {} - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - - enum choice { red, blue }; - - namespace test { - - void show(choice c) { std::cout << "value: " << (int)c << std::endl; } - - } - -We create a file named [^hello.pyste] and create instances of the classes -[^Function], [^Class] and [^Enum]: - - Function("test::show", "hello.h") - Class("World", "hello.h") - Enum("choice", "hello.h") - -That will expose the class, the free function and the enum found in [^hello.h]. - -[page:1 Renaming and Excluding] - -You can easily rename functions, classes, methods, attributes, etc. Just use the -function [^rename], like this: - - World = Class("World", "hello.h") - rename(World, "IWorld") - show = Function("choice", "hello.h") - rename(show, "Show") - -You can rename methods and attributes using this syntax: - - rename(World.greet, "Greet") - rename(World.set, "Set") - choice = Enum("choice", "hello.h") - rename(choice.red, "Red") - rename(choice.blue, "Blue") - -You can exclude functions, classes, methods, attributes, etc, in the same way, -with the function [^exclude]: - - exclude(World.greet) - exclude(World.msg) - -Easy, huh? [$theme/smiley.gif] - -[page:1 Policies] - -Even thought Pyste can identify various elements in the C++ code, like virtual -methods, attributes, and so on, one thing that it can't do is to guess the -semantics of functions that return pointers or references. In this case, the -user must manually specify the policy. Policies are explained in the -[@../../doc/tutorial/doc/call_policies.html tutorial]. - -The policies in Pyste are named exactly as in Boost.Python, only the syntax is -slightly different. For instance, this policy: - - return_internal_reference<1, with_custodian_and_ward<1, 2> >() - -becomes in Pyste: - - return_internal_reference(1, with_custodian_and_ward(1, 2)) - -The user can specify policies for functions and methods with the [^set_policy] -function: - - set_policy(f, return_internal_reference()) - set_policy(C.foo, return_value_policy(manage_new_object)) - -[blurb -[$theme/note.gif] [*What if a function or method needs a policy and the user -doesn't set one?][br][br] -If a function/method needs a policy and one was not set, Pyste will issue a error. -The user should then go in the interface file and set the policy for it, -otherwise the generated cpp won't compile. -] - -[page:1 Templates] - -Template Classes can easily exported too, but you can't export the "Template" -itself... you have to export instantiations of it! So, if you want to export a -[^std::vector], you will have to export vectors of int, doubles, etc. - -Suppose we have this code: - - template - struct Point - { - T x; - T y; - }; - -And we want to export [^Point]s of int and double: - - Point = Template("Point", "point.h") - Point("int") - Point("double") - -Pyste will assign default names for each instantiation. In this example, those -would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to -rename the instantiations: - - Point("int", "IPoint") // renames the instantiation - double_inst = Point("double") // another way to do the same - rename(double_inst, "DPoint") - -Note that you can rename, exclude, set policies, etc, in the [^Template] class -like you would do with a [^Function] or a [^Class]. This changes affect all -[*future] instantiations: - - Point = Template("Point", "point.h") - Point("float", "FPoint") // will have x and y as data members - rename(Point.x, "X") - rename(Point.y, "Y") - Point("int", "IPoint") // will have X and Y as data members - Point("double", "DPoint") // also will have X and Y as data member - -If you want to change a option of a particular instantiation, you can do so: - - Point = Template("Point", "point.h") - Point("int", "IPoint") - d_inst = Point("double", "DPoint") - rename(d_inst.x, "X") // only DPoint is affect by this renames, - rename(d_inst.y, "Y") // IPoint stays intact - -[blurb [$theme/note.gif] [*What if my template accepts more than one type?] -[br][br] -When you want to instantiate a Template with more than one type, you can pass -either a string with the types separated by whitespace, or a list of strings -'''("int double" or ["int", "double"]''' would both work). -] - -[page:1 Wrappers] - -Suppose you have this function: - - std::vector names(); - -But you don't want to export a vector, you want this function to return -a python list of strings. Boost.Python has an excellent support for that: - - list names_wrapper() - { - list result; - vector v = names(); - // put each string in the vector in the list - return result; - } - - BOOST_PYTHON_MODULE(test) - { - def("names", &names_wrapper); - } - -Nice heh? -Pyste supports this mechanism too. You declare the [^names_wrapper] function in a -header, like "[^test_wrappers.h]", and in the interface file: - - Include("test_wrappers.h") - names = Function("names", "test.h") - set_wrapper(names, "names_wrapper") - -You can optionally declare the function in the interface file itself: - - names_wrapper = Wrapper("names_wrapper", - """ - list names_wrapper() - { - // call name() and convert the vector to a list... - } - """) - names = Function("names", "test.h") - set_wrapper(names, names_wrapper) - -The same mechanism can be done with methods too. Just remember that the first -parameter of wrappers for methods is a pointer to the class, like in -Boost.Python: - - struct C - { - std::vector names(); - } - - list names_wrapper(C* c) - { - // same as before, calling c->names() and converting result to a list - } - -And then in the interface file: - - C = Class("C", "test.h") - set_wrapper(C.names, "names_wrapper") - -[page:1 Exporting All Declarations from a Header] - -Pyste also supports a mechanism to export all declarations found in a header -file. Suppose again our file, [^hello.h]: - - struct World - { - World(std::string msg): msg(msg) {} - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - - enum choice { red, blue }; - - void show(choice c) { std::cout << "value: " << (int)c << std::endl; } - -You can just use the [^AllFromHeader] construct: - - hello = AllFromHeader("hello.h") - -this will export all the declarations found in [^hello.h], which is equivalent -to write: - - Class("World", "hello.h") - Enum("choice", "hello.h") - Function("show", "hello.h") - -Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access -the members of the header object like this: - - rename(hello.World.greet, "Greet") - exclude(hello.World.set, "Set") - diff --git a/pyste/doc/renaming_and_excluding.html b/pyste/doc/renaming_and_excluding.html deleted file mode 100644 index 29a8001b..00000000 --- a/pyste/doc/renaming_and_excluding.html +++ /dev/null @@ -1,68 +0,0 @@ - - - -Renaming and Excluding - - - - - - - - - - -
- - Renaming and Excluding -
-
- - - - - - -
-

-You can easily rename functions, classes, methods, attributes, etc. Just use the -function rename, like this:

-
-    World = Class("World", "hello.h")
-    rename(World, "IWorld")
-    show = Function("choice", "hello.h")
-    rename(show, "Show")
-
-

-You can rename methods and attributes using this syntax:

-
-    rename(World.greet, "Greet")
-    rename(World.set, "Set")
-    choice = Enum("choice", "hello.h")
-    rename(choice.red, "Red")
-    rename(choice.blue, "Blue")
-
-

-You can exclude functions, classes, methods, attributes, etc, in the same way, -with the function exclude:

-
-    exclude(World.greet)
-    exclude(World.msg)
-
-

-Easy, huh?

- - - - - - -
-
-
- - diff --git a/pyste/doc/running_pyste.html b/pyste/doc/running_pyste.html deleted file mode 100644 index 42834000..00000000 --- a/pyste/doc/running_pyste.html +++ /dev/null @@ -1,110 +0,0 @@ - - - -Running Pyste - - - - - - - - - - -
- - Running Pyste -
-
- - - - - - -
-

-To run pyste, you will need:

-

-Installation for the tools is avaiable in their respective webpages.

- - - - -
- - -GCCXML must be accessible in the PATH environment variable, so -that pyste can call it. How to do this varies from platform to platform. -
-

Ok, now what?

-Well, now let's fire it up:

-
-
->python pyste.py
-
-Usage:
-    pyste [options] --module=<name> interface-files
-
-where options are:
-    -I <path>           add an include path
-    -D <symbol>         define symbol
-    --no-using          do not declare "using namespace boost";
-                        use explicit declarations instead
-    --pyste-ns=<name>   set the namespace where new types will be declared;
-                        default is "pyste"
-                        
-

-Options explained:

-

-The -I and -D are preprocessor flags, which are needed by gccxml to parse the header files correctly and by pyste to find the header files declared in the -interface files.

-

---no-using tells pyste to don't declare "using namespace boost;" in the -generated cpp, using the namespace boost::python explicitly in all declarations. -Use only if you're having a name conflict in one of the files.

-

-Use --pyste-ns to change the namespace where new types are declared (for -instance, the virtual wrappers). Use only if one of your header files declare a -namespace named "pyste" and this is causing conflicts.

-

-So, the usage is simple enough:

-
>python pyste.py --module=mymodule file.pyste file2.pyste ...

-will generate a file mymodule.cpp in the same dir where the command was -executed. Now you can compile the file using the same instructions of the - -tutorial.

-

Wait... how do I set those I and D flags?

-Don't worry: normally -GCCXML is already configured correctly for your plataform, -so the search path to the standard libraries and the standard defines should -already be set. You only have to set the paths to other libraries that your code -needs, like Boost, for example.

-

-Plus, Pyste automatically uses the contents of the environment variable -INCLUDE if it exists. Visual C++ users should run the Vcvars32.bat file, -which for Visual C++ 6 is normally located at:

-
-    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
-
-

-with that, you should have little trouble setting up the flags.

- - - - - - -
-
-
- - diff --git a/pyste/doc/templates.html b/pyste/doc/templates.html deleted file mode 100644 index 58548c72..00000000 --- a/pyste/doc/templates.html +++ /dev/null @@ -1,103 +0,0 @@ - - - -Templates - - - - - - - - - - -
- - Templates -
-
- - - - - - -
-

-Template Classes can easily exported too, but you can't export the "Template" -itself... you have to export instantiations of it! So, if you want to export a -std::vector, you will have to export vectors of int, doubles, etc.

-

-Suppose we have this code:

-
-    template <class T>
-    struct Point
-    {
-        T x;
-        T y;
-    };
-
-

-And we want to export Points of int and double:

-
-    Point = Template("Point", "point.h")
-    Point("int")
-    Point("double")
-
-

-Pyste will assign default names for each instantiation. In this example, those -would be "Point_int" and "Point_double", but most of the time users will want to -rename the instantiations:

-
-    Point("int", "IPoint")         // renames the instantiation
-    double_inst = Point("double")  // another way to do the same
-    rename(double_inst, "DPoint")
-
-

-Note that you can rename, exclude, set policies, etc, in the Template class -like you would do with a Function or a Class. This changes affect all -future instantiations:

-
-    Point = Template("Point", "point.h")
-    Point("float", "FPoint")        // will have x and y as data members
-    rename(Point.x, "X")
-    rename(Point.y, "Y")
-    Point("int", "IPoint")          // will have X and Y as data members
-    Point("double", "DPoint")       // also will have X and Y as data member
-
-

-If you want to change a option of a particular instantiation, you can do so:

-
-    Point = Template("Point", "point.h")
-    Point("int", "IPoint")          
-    d_inst = Point("double", "DPoint")       
-    rename(d_inst.x, "X")           // only DPoint is affect by this renames,
-    rename(d_inst.y, "Y")           // IPoint stays intact
-
- - - - -
- What if my template accepts more than one type? -

-When you want to instantiate a Template with more than one type, you can pass -either a string with the types separated by whitespace, or a list of strings -("int double" or ["int", "double"] would both work). -
- - - - - - -
-
-
- - diff --git a/pyste/doc/the_interface_files.html b/pyste/doc/the_interface_files.html deleted file mode 100644 index 77246af7..00000000 --- a/pyste/doc/the_interface_files.html +++ /dev/null @@ -1,81 +0,0 @@ - - - -The Interface Files - - - - - - - - - - -
- - The Interface Files -
-
- - - - - - -
-

-The interface files are the heart of Pyste. The user creates one or more -interface files declaring the classes and functions he wants to export, and then -invokes pyste passing the interface files to it. Pyste then generates a single -cpp file with -Boost.Python code, with all the classes and functions exported.

-

-Besides declaring the classes and functions, the user has a number of other -options, like renaming classes and methods, excluding methods and attributes, -and so on.

-

Basics

-Suppose we have a class and some functions that we want to expose to Python -declared in the header hello.h:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} 
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-    enum choice { red, blue };
-    
-    namespace test {
-    
-    void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
-    
-    }
-
-

-We create a file named hello.pyste and create instances of the classes -Function, Class and Enum:

-
-    Function("test::show", "hello.h")
-    Class("World", "hello.h")
-    Enum("choice", "hello.h")
-
-

-That will expose the class, the free function and the enum found in hello.h.

- - - - - - -
-
-
- - diff --git a/pyste/doc/theme/alert.gif b/pyste/doc/theme/alert.gif deleted file mode 100644 index 270764cc58716d36f8545c07ffbccb76a3dbc7f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 577 zcmZ?wbhEHb6krfwc*el+^5x4HFJ3%)^yuNkhj;GW`TvCB_N{CGA2IyD%W(C|x&OBr z{@-G_a_Q{m__~8F~vDYEl>qqZpDSjq@WJa>5z1Lm6Vd z86rG+L!23`^cb|27{rAb*jO1D7#RNl{|}<5jTL{gu!=AwGw6T}2E_>j`@DwarsiZ7 zvzCqy8~4s$Mnes@-VRGi5tqr$%yz7-+I%yUbrd6_%=Konm?$SD`KoeGb{17nO!DDy z>t(PKkWWZ*<cQAmnAE=fsD%$UE$ROUW+NUZ1+QQKJ-!ms2) z!wk-f=<_sLpE#kg){9r_k3+JcmI}v|3yP=3Bn5<=JQ5$B644M)RP)^A(&gG6!^Fs7 F4FJH#(p~@n diff --git a/pyste/doc/theme/arrow.gif b/pyste/doc/theme/arrow.gif deleted file mode 100644 index e33db0fb4dd85e0fe527343d95a3f28a0ebb74f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70 zcmZ?wbhEHb6lLIGn8?8J9}E~6W->4^DE?&OC-XFJFH7^5yH-udiOcdjJ0Y=g*&CzkdDw`}cS6-hKG+ zVdct|pFVy1_U+rhfB)XRdGq$|+aEuEeEj(F|NsB1R;~K`_wVY}tN;A@vu4ej6)RT! z{{8#cuU~7|u3fio-TL+GfByWrapT4f8#Zj(v}yC^&D*wZ+q!k@mMvR$@7{gjz=7@C zx9{A!bMM~0yLRo`vuDr#{rh+9*s*WlzC(u&9X)#V)TvV^Po6w- zyLay%Jb3Wz*|X1|Kfizf{+Tmpu3fwK^y$-^H*a3Qe*M|AXXnnHJAeNCg$oysA3uKe z>eWk^E+4<0lBLU*@T^?5dd(`K^&2*BTFEI`2zd3>o;z)v)s9R@BSUeM~|O8Wn_5q^405CHt*hl`1r~B%hzw;zdQW;{pasr zF9v2V8Hs|fgUuYmej5*MSa`TSY=y@hkBv&AY7)j-cRDt)dE zU9$D{^$pSTGkte&%f01a^!nae>+L=F4>WVj`|WA_`1r(RZF9M$J3l|aF#GrnzrDM@ zzP^$C;>NkXyT8BJIMglgzi&_FC%sFnlY$n!TsEid z)yw4z+N54FEt!_}YUPS$t6r^IvuM`A)fY$|rssS*xogRqPp5XWJpOdrfW7(58I$WZ zJ;oN#*L*&AD&X$RBj zw_mR(wCjGmkup8^+s%ySYroyf+5Yz1?SkXF-|v)M&;5S4;`!R|_iFabaxho}0O~&E Au>b%7 diff --git a/pyste/doc/theme/bkd2.gif b/pyste/doc/theme/bkd2.gif deleted file mode 100644 index b03d9ba97ca7a4c4de297b5413fd3d3df8e0fb49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2543 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 diff --git a/pyste/doc/theme/bulb.gif b/pyste/doc/theme/bulb.gif deleted file mode 100644 index 74f3baac42f12ac0551040a00f78cb573360a0ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 944 zcmZ?wbhEHbU2JX=yWO8qb`WHgo38Gifu=q@6jF_W#UGhBGsb&&*6a zGjrydnP<+-{D0;Q!i=IrIPje+GvC495Q% z(*85d1W7Xd|8LCj-`M!SaoT_5nIN^s|No~k{7*CfpO*GNZ6-)-+W-GE8UD{S{y#JA z|IC>nlV<+^e}>`z8RP$8cYq8A8~y)3Nb~>yAnE^L0P?^n9t{C$ zm!W3VRz=HX0SO5P1_s5SEQ|~c3=BFT0%V2*i>ts1&-4h1-QU}6JQPJ#9Az#qP{_IL z>m8xcQ#>ccK&B>uvC-M7@I$1?63NFG4AfGLn>kr6)<~>7uC&oZb>E%VNA7Gc3=Gx) DZ>u*X diff --git a/pyste/doc/theme/c++boost.gif b/pyste/doc/theme/c++boost.gif deleted file mode 100644 index 58be431a3fafbd5adfa01e829ce8d80a03a83ed0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8819 zcmZ?wbhEHb6lDx!_|CwzZQFbH(K6ngWKJ ziiVnsJ(`+|nwo~1nogRU#hRMcnwmYDhC!N^Q#37?YC7%JbULQ#bxbqrnr8BQL(ODE zLoY+8V}?P;41=y2MlCgrx@H*l+%Wl?Ve)gs?C+L}mX?N=mWDx=hSipqQ!JgPSURn> z^vbpjT56g6-Lm?-WzTmf!(=DJY9}WzC#NVUr)(#u7ALR0PC?a9L35m__ikjmUwbv`^m{;;Wuj=n!J>P?zs)M|u zg1oYWg0h2x<^%<;4T`!KlsqLUd1+Ac+Mw)XLD|=WvhM|DKM$(D7F7K{sO5W5&-0+3 z??H3EM|mYj1#OK2ftIN3wNcggqSpRT4$4lBTAG}kot#{qoIE8tyC*q&PIC6vOS7xD zW>??KZaJ6Tb1u8*UUtv(>?z-~m%h(F_CNdD|Kj4M#l`1}=X@_-`@MMU_u_NktBZT8 zpp&i(JHp3~FQ z(gOl>dV03@^c?G%^1f%zxt=-KdX`@6S^B(Z>-#A^bEeFhGiA=&DRcHtS^9j+()UxA zexI`S-juEHr|f+`W$$+oI`@ChoO5&5URye6?b11Wmo7cFbm_UJOYbdRyLai)y3n&#m2hZSB_QYmePqd+hz%bMM!l`@Z(t_qETz@7;S2jPC8- z`+V=-_j~t#-+S!X-gEc%o_oLd-1lQ!uN`~-{oJ{G=gz%9ckkZ0d+*QP`+n{H_iNw3 z-@Etx-o5Y7LE!uQ=ilFd2LZ*OEQ|~c{~2^ZSpk$M7&!hh{O6SM*s$PWGl#HN%!v&P z54Q^_d(H9KxaerNgmKoL6B`#F?^kf{lJVTM)Z?TNcv$a| zX8p~bZNB0Df&T~6_*U;Ue!k)Nx4)0STN=lnoy=Uk&wHlPgHtoufA^>{GB7Z*NC+qx zEcpIN;8}uG+nxy)Z*Fk5pN`YwZ+XkW@@A=`LV`o-eI~Cj)^QWQ-oG;S@4wD($Mp*; zKP`6s{@DHBpR&r|f1Y;l*S~LH`{mvB-SzM1@2UKMVR3)O&lAhfXRyDTtWf>OAmU!t zs=u54Gam$&%`7~<@(I8EdENsIoYf18T1uH!F5G5d%-B3PRcBIqc*K(2v|IK+EpEtF zvVWTFZ*Tf*@q*YTCzbu}KZ#iM+uB`wtUT%073U>3|4u$WZ{ub)vwzYj1 zuldQd;&D~NvF-O#<}b8Nu8>@&;-9;Xcf)NZMy&}m=Ir4$;7VZmncQc2tKjgwqRO9N zm2B@69PXQ`ze#LXi_kW+n@esNs@-bIFpJ8}njN-lZftLp)yfr%lw4wFt350_kh}L| z+bR2hhkXvb%G=Y~cylrH%;s)`%pM)00cDHCB8v?zgnNb(GKA z#VV6;>)Rcd&s%@~^7x$1zd6b0?C$^iIo0ykHf4VM&pV8lZu@Lu*+1oT!|Hxpf4|Hp zebJ9zByaeB$KplThPhp@+}w7ws^{-I@aj&~7QP3E9IP%KooDK%P!P@VoTuVR?H94` zCpNd97&Ruj`*iYECj5P=JLyHiW`FayIluYr-`yzgH@o}hbD!0}CB}K?FTZT=v;Hk} z*Wb!~J9CMZ>G{tyuKeBLtiR*imCgMV{z~j#(jUWiC!yMCQ>B4B)0tJb8Fs#D?q0)q z;wM8smqL1^eT~I-iGN!rN2$G9{?}&G>8NXw2Oq>Pd~2*xz3{8?!x??n>n!ZQoBUAi z{}dgt z+CLsYPp}lKr}0kz_UE(Cjeixn=arWW*d5?Mdt3Fq+0Tf_yms$*G@rM4{ATfKgFi9M z=WOo^IQyI4zjJt>-Hn*T{Dw!KeD?kQBBq$%>gJQnz2<*jxcxrVXp+6cL-y^1<5sr{ z`AbdC%KXfjzPTZlzxu=CroTTf_WNC*B_^p;##iY5_F7rj>MP4aUq9$&K4+pK&+5n2 z!p(61TN3}pH%Ikq4zMyjF=2>~Y^(eCN8^~qA4a>{2K|ohC)^DWE#y!Acv#~4jpK$J zCh})UD9aza;A&SA$Xgq+QGWk|V|EKZcGtx$mio(a-29VaPu`tm*#{5Wr7lO9EI*qg z_x*>M{f@2fH8&SWOYE86f26Jd%#L$;3OOAdnOkRvpM0FMR_TBQhXG^Do5zBR5#60P z3bl5BIiCOT1+(6&VC{gj>ONC~C-i-q$Y1rM!|PW<>cn?T7pPrjwogoYI#uL~SMtlp zaz72i*j_HQ;AZM7j}w0CS{L;d zE~=m2vY1ct#=_Edu3C*3-sHVm(ags>fq^Mvq3pkZi{15F7V;NbD9dljIA%L#VNZ?D zV~H;}T(zDsa>iYGEV_O}yH-sgfBYUL`Bfc9ZFVf`kKOQS;hGc2^^z94q+D?pUozvk ze$T@GEC*-#>lH7}HwE_RS2WAr?r^g^wz03K#aZ@e#Bu9)AN$IGtZA#CBQ$x2iWPrW zvErQ=2W3_xMpmB(tM~#K=CTy=7u!5q-M^w)P^e6{jAyY(LaKY+pCi4wHck9VM_a$F zDG1wO*Cc%*fz5u(MV@MfWU1bpDlCu?UGugvkfU^sbp!| zxOzv6ZNkE?@*_%%jzze-_CD;3w@H>;ccIm0Rb%h%u*ci(Z)i6^RM?-tM_K;8hr-oY zM{UCTjyY-SaTHfRKD#%8%}iBUm67MdoiIZO^B$E338V5&x1MTFTCr?uCx;-H%JxUH z3mjamCnU1wGCUG~f1;7^%*8gxEy=u@8SPS66#7l>D9UDfd=vCC=+|Ac@aFuEb=*%9 zIm~Y?=AByMuBv0$e{@&!#tE^l)*+1Cl?xt;e2G};70%6*af4afD0ja3m4*E!OAgE5 z`6Sq&=A-;I!Rqqtvb-Xeq}~{nV=n90@#$AEa?1%Um{(T8W~i0E{Pl+oR>vIJbpBNZ zobUd>K=y9M@!IZReAOL?r4CPUtG%1ZS6F#C^R0us^@4AG_H!T0-2HKF{+)|`WhL+Z zZ%%Trf8MB5S+Ke~X!Z1l=NA(c6<5oCom90~-l(`LsX7Qzz_eLm>(Kl$h$PuI8) zit=SQw(GCB@s7b^!d0#lnQ}Hi99fkXH0=A|X!GNRb(OV21Bb-|^Vbg=IkYA;?BjP} zOgpjFT3{ka%=JgI3K@>(c7c@^42{wjKbowTENIR1P~?44&?L2MBdhL`IPPZ}i~{!< z+Y{eA@V@tOmcDn9&1OfkKwE~pVpBh-&z5GP=@$RAE(CH0Z%GyrOl{S9c91Li%wtKN zSU2-m{{$~rH$0ZEebc_^SL1`3yjeZ_&hE!-krc^Hi0k5 zfc3=%wjhC)tOtBYukkfIaO_D>ou0ti^_A=G0rm+O_>O;wIPih%^Ma^P2|W7^_&-kO zzgl4DdNuUz0vm=;hF=5Z3^ytHx0Z2z=dYb$c3#lD=7MLLBbWLX2BrgiiA?hPpEP5G zEWbE#EiaH(GGO=@e68ro2V>W*eBBi$uP*R1ec`>ff%j-a@Vy4UD+_pUU*LT(f$#PK zW2Ps(4=(V|?cn?WneTQ(*8>5*mkWwtEr?#9!S{;6l#j*KD!hcFh3`cI--#r?oipP9 zhVuVNjTaR0`N1T1ghgyVla}7KHUVM7tmpiy3DVmO)rBwk{X0;0c(ETx0&kfj-%108 z9|!oEGWvc981y%A2^ceQ8}KhI$nJ1xENb9*#K6Aj0-yH<#`_BFodfceGS$i1-_sS zY^S!dEi>nMaDc73fv>{hALm;Kj)@6;(>8FtNZ^{Tz`yzf=Vyn=Pan8DTX|Pc<$ZX- z?e+%#^)L7zFz9_vM z_8@^H^8w!!2aY!h98(MUY7$asU*%iL(7N#e_m>CUt3~-P9B@k#;VW!$xR<2=jmhS@ z#s|b=djli_8U=dYS(jurVFrU0lR}V3OrC3*TQKIBGXIrx@5i+%WI^ zVz&nkyr&I;v z0VMg!CJfaUiT*z>p;lt1tWCotY|UaQU=v)x6(_*H-(kYT3#=KhSe-8LIu$TqH(*gaz{@&;fvuD2 zUIU|s0AHa2>IQysDU<(UdLJJt z2^quLYa;mVo<-}ljZjS%Wn$&^PTy>D40HT z;OY6mp0=Qj=b`T230#{#aNiK%`x?n}@dMA52HyJ&yeAoWuNf@3Zm|7+K-V<~o{I&% z_Y&scci_G9p_Yw{PvVz-lefvPQu`MZ_~v);y;@KlaG9^3Nn_8B1+z3dUoh}LGf4b= zK{fG{Wg3&%xfea@&8wLe8FLiXc@)&c0=VuZ^s*GN**VDW6p(A(()&iRVTbh^rW0jP z7&u-8#JpX=Y}vrq&cJoSfLq`rU)}@O6Aer68?ZPF@H#(WJ*L1C_pgALCxGFC1Czl7 z9Tp>J@FH2$OfJ&0kVI$Zj~v;J(l!^Q`3hK^x}|>^FtIo=1_|wA?%17iQtqjN!s#eJ!6{sy8<;~s z@GTVJ+F!sU_>s@4fF~=8=T#JsvjF=A1s10U-dG04{R|9jA9&jv*lsH@NEECvy}%oI zfa!VxvmXO5ivjcX35=2#cqJDw-8En~e88*C!KZX`X7mSMKLytJ46KkTg##f!d za)BWsTq*JA1Kz0tk$W$2|6^LoPB zpPmbjZs5K0V8NXa_In+8I1CrO{E%SE%~R!v|B0im`Z;U?7n0ZldCCnqCqL!>b%A^T2L8k?_E#S8 zKWtE$V6D2aI8*17$dYV<35|TJA5QKP%;t1pteL=fw_%H}$eQOndS#cgzkR?laRJ|s zKYUgREUzYTF8si^R)Kwg!yfjD{3j>auqU!zSiRo)1J`A3mrq~$*sC}uF)#>z;FfY= zy;8s&yMa6K!>tny@!uTypCxbwC2&bCU^*YbEZM;KX*c&Ob%*|IdUrN(MK9o5tIivB zfMs`sz{&-zo&VNyi9h8&e}MmL0PnlW*QTiHrB%rD2`Sz&l=w4&yZ!;w-o!O(MJ(P2 zcq&VX9M=R3;3EB@aT!N zy>(#8{J^(Jpz-q$?zIg9KN>g!8U&tNv1~SAneXtJO_5(FflESxWxoLH>staF6S(vR zn0E; zD8*U$_%5SYW?)|9z`E&!z`7U>Ej)&uzoT&Iue(4Eo<2{8*p&xln+EBa!p*E-sEjR`CXb%?}vs9C+CS zc>)uTuzlq7ci>=8Thc|+W?27z4P~9K@Lgrrf@$`#({Ab*|TdmIDGqG%b)WqLkGG!L|KXgd_70Q?5T2mRp`*D&_ z@>F)I_nJZone%$HqnzpI921zQ4MoZiUy&->kjyTeJV| zTl#tWxx4!-KmWUW`n$jU{`$WX)^m1*d`dYr$u(`s^!H0nPWcyB_3s;xZv39q4|2Yn zzIRTtt=oO3^XI2^qAMyp9ril6WW+9t+TWzR^|)5woQR@53of5f?mJer=v>B$EM~_)l-R_Xznf6oeWzx^n@>{b0t*hncskrx`GWF}r z-|h43q`F^hI>qN=;Mgm6>y1iBT+#~J;wKZA&pmWUafK}B!N}*b1@|J^Wr_|7w$I7; zt5KV}^pB%DuT#X%Ba`w>PAPHs?y^)Ccrj^$o3iz~1@6k_#~hL;IaoQWPL1ul_;lu{ zd7ka_DnIRXpI@`?j=RHgxvCG2C$tuwa9};IQtaBT_j&o;vmXvFpI;sK>Wy4gRpURF zx#205?9-~>M5gqWe4B7|UVww7`icU(lge|7P6fL1pPHrU!e_baA_te>nnx^adgfI& zUFu2t;4IO%i<70n&+o%San%|HedVl@6;AWKk6m2OZ}%zks6=&KWt)7)yp89V<}rA? z%N=?ZsAE_s(VU@Vc)DeqPn#Fh=Y?f+?)J=|a&OOb@#2z)uJgQ7UK-5HJ1}Fhbfk-? zx?toX&Zoi!4wf!~hH8aNHihh&z`V2P-HKLA*LkNoW{EF3<-zG*_Tq$mkkrS6?RfzK zi)L)yccO7#VcNpweXhSMTc_5Ay!<*n>&MRZ^Y{M=JbvTQzmx0^+S0ev7cnkAYI%$4 ze2dSLdDs87w98g~n;5K6|7u~oT;-0<%jK%?RsMQewIFZ#Y*o`q%h}b9U#az)Y&)jG ztzi=NtjBP{?j)(+u9hXCeLp;pPS0B4c=VC){E6*ywHj~S?z!k$Bxs?Ch6K*n1cHi^2SLRI6N2b>kxI`y4o zyWWeBTnRUvB^xKXGX6{a$XVU+PByH-#VCbwxAUDuqyj`)%|(fb0UMCF;o@~$nC z4L=wc)LnVw{jOQbFz{ZQmDd6De@%cIkli+R?R2an})b{&`e_^_|6 zhFMB#rMr~Q3PC3yrgDjov)uMA?DEKHkxt&w<`xpzn_8nRxoQT>CkrF~*d>SZBo?w+ z?Fu|n7o#a3d8^%N%MyVOlO^eaEKg@}Jz1*eH&N-wg5$s5IPz3^D9ii_U^98v*mIiE zS@N5rtL=>~-sj(J>X{(W>-OiLW1oQ0av7aH9ty{%P0aRKC}b|x_}PG|CH_kT`~C+9 z`P3Ra+|!P*r!d@h-KEH8@F7`r^#gVlzk~em{xU@zUEyzjL2zHmpT(*FBce7jg=|i1 zy)<9)rq6VbLlX>2k11Z*;AXc+u&=u2vBZlV$DWog>^5mSEI0S{QvHvD{jvX;L=WY- z8ya6SNr^fl^rS)7*hR}Pf=5l+@4;2$GmgFaC5t5%XS5_532_J?xS(`-gOmKW<6X6H z4vGEKXfu4~%v&GQyzf&m*TY){h!&qb{Ur2BZ`q(`y zc8OfiiEy_r#m+-sDN^@09JiIawAI;rj^bTUw$0(J=ZP#j)z%h&day9b}a6P@?2ydR3y8pG#d0= zVV2oj5oW$XaLI&*$KpLZIqan_HqDN0>Ak7Tro88b+P@1|ZWs$6JnnKue8F*D?b=?) zjkV6wYB_JG7cyo|*fwR4d8Nn_h0HhaqUXA~?P_}5C;rksq}8)0KIJ=4+JzJPlRk34 z=(@}kzV1Xqec{?8jE8tS4{{_P&J@fPVV2ELnm^%d%*=L=C0k;IUJJfF$p7xk_T8;{ z?5&qR^3`zcxcKNoj_s?1x25)r%G59Av2~epH+{kOBh%FiAJtt<>Yj1<)UmG3mJF|W z3j&;#e=T4$eDYCEM!4@p^|7z+Wnn4pZ=B`+bDIhs zp272;Y;n*2 z{OG1NpCiA|f7$s7FOOf4TN2r3^2Gk%3L)nw3;WMV&Aw5swezu!b8fc&Qdu$ATh=W1 z9_H;>oVn&L+Z^jlyk{;Yue#b^`%opU3=oSpr%~ki<~5JQji;JxWPB4V%(6NB`TUQo#$ArQu`m89 zeQ3(G-2NtTYo5ba*_RpZDk}wZJ=J^VoEE!V?K14W$R8;8a>8Ggw;PMvJUr#@EjVVf zB9ZR_^M2{uAKa|JCcG~{Wm5rX_ww!QeeOTV*8nj z4)0si4<@UW7_dKEJVDoK50hrcAq^$2os;Tr?Rc+z@O$F?qcc0Sx_ah2>Rxu*Io-p) zEuv>r&_T99&dIwc{lCDIa9F6NfT!+&%9=$2-<^5Z-fDko&GE;oLv@Ra&c`)+H`o99 zwWdt_pq5I$u!s(4S++p>L(}xgX;slO(kd%dpQv=KP-;D)!WihRZ0-D~NT9xB{@Dz3 zlb3edTMm~OJKH@LGJJA)O}3$!%7hiW4?C(HaWXmL>~h2<Q%P5$_{Me6AeveR9N4XL17rgEatT*T~8M diff --git a/pyste/doc/theme/l_arr.gif b/pyste/doc/theme/l_arr.gif deleted file mode 100644 index 5b3cb1cbf07e316c3655ac84c9ba72dfbe2e25a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#U2JX=yW!8D`F$dFITS|7mIeXEOYsnf8C?%>QSM|DT!p z|3Ab3|7ZS#f#OdVMg|6c1|5)2kQodtE+0;Mrh1v)&NktlbFtDU2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#&gTE>G6muSe93zS-%fd>Q)&EUbx3v}%NcRk;>%V0Cvz}Z0{|MoM2G+Y diff --git a/pyste/doc/theme/r_arr_disabled.gif b/pyste/doc/theme/r_arr_disabled.gif deleted file mode 100644 index 2100f78bf35a47e09ca76ffcc6e80c5a2b11e359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91 zcmZ?wbhEHb6k!l%n8?5|bLPzZ_wWDz|DS<@LGdRGs|W)VgAM}&0|Q8&fk|gd|H|rv v@(cz3o}Svfg4O3$GVLgQHgm3)*?|1&XIvGFi0itr1TiFoeP&p1C|3gi5M|Dy8)Dq>pVFYM_y+=U^T ztHBMdj+tQ(A2Y*wF$RYE_4D-@jtU##9xMTW{_9v6c`wK7#J8B1sE6<80-`n z7><}aTg5mA1O&%;g!uX}*f26MGK54pa~u~3ne&L_xcGT71qKC%`|QWX?G$<#K=P%G z=f$!jvLf=G=8H2hFfyd8*(n?_D`m7(uv4gs=yaGbo~{-bxlJUa@tDY4zP5<9g6(Q8 z@$VV#2iy??g*_vVXy`OS*Qv? diff --git a/pyste/doc/theme/style.css b/pyste/doc/theme/style.css deleted file mode 100644 index 53a6205e..00000000 --- a/pyste/doc/theme/style.css +++ /dev/null @@ -1,170 +0,0 @@ -body -{ - background-image: url(bkd.gif); - background-color: #FFFFFF; - margin: 1em 2em 1em 2em; -} - -h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; } -h2 { font: 140% sans-serif; font-weight: bold; text-align: left; } -h3 { font: 120% sans-serif; font-weight: bold; text-align: left; } -h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; } -h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; } -h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; } - -pre -{ - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-top: 2pt; - padding-right: 2pt; - padding-left: 2pt; - padding-bottom: 2pt; - - display: block; - font-family: "courier new", courier, mono; - background-color: #eeeeee; font-size: small -} - -code -{ - font-family: "Courier New", Courier, mono; - font-size: small -} - -tt -{ - display: inline; - font-family: "Courier New", Courier, mono; - color: #000099; - font-size: small -} - -p -{ - text-align: justify; - font-family: Georgia, "Times New Roman", Times, serif -} - -ul -{ - list-style-image: url(bullet.gif); - font-family: Georgia, "Times New Roman", Times, serif -} - -ol -{ - font-family: Georgia, "Times New Roman", Times, serif -} - -a -{ - font-weight: bold; - color: #003366; - text-decoration: none; -} - -a:hover { color: #8080FF; } - -.literal { color: #666666; font-style: italic} -.keyword { color: #000099} -.identifier {} -.comment { font-style: italic; color: #990000} -.special { color: #800040} -.preprocessor { color: #FF0000} -.string { font-style: italic; color: #666666} -.copyright { color: #666666; font-size: small} -.white_bkd { background-color: #FFFFFF} -.dk_grey_bkd { background-color: #999999} -.quotes { color: #666666; font-style: italic; font-weight: bold} - -.note_box -{ - display: block; - - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-right: 12pt; - padding-left: 12pt; - padding-bottom: 12pt; - padding-top: 12pt; - - font-family: Arial, Helvetica, sans-serif; - background-color: #E2E9EF; - font-size: small; text-align: justify -} - -.table_title -{ - background-color: #648CCA; - - font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; - font-weight: bold -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.table_cells -{ - background-color: #E2E9EF; - - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.toc -{ - DISPLAY: block; - background-color: #E2E9EF - font-family: Arial, Helvetica, sans-serif; - - border-top: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - border-right: gray 1pt solid; - - padding-top: 24pt; - padding-right: 24pt; - padding-left: 24pt; - padding-bottom: 24pt; -} - -.toc_title -{ - background-color: #648CCA; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - color: #FFFFFF; - font-weight: bold -} - -.toc_cells -{ - background-color: #E2E9EF; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -} - -div.logo -{ - float: right; -} - -.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } diff --git a/pyste/doc/theme/u_arr.gif b/pyste/doc/theme/u_arr.gif deleted file mode 100644 index ada3d6e043d2e4314a20d6783f2800f2f21d89c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#pCE@bTiY5O-A{7vV42g%c7%l^E8u0x - - -Wrappers - - - - - - - - - - -
- - Wrappers -
-
- - - - - - -
-

-Suppose you have this function:

-
-    std::vector<std::string> names();
-
-

-But you don't want to export a vector<string>, you want this function to return -a python list of strings. -Boost.Python has an excellent support for that:

-
-    list names_wrapper()
-    {
-        list result;
-        vector<string> v = names();
-        // put each string in the vector in the list
-        return result;
-    }
-    
-    BOOST_PYTHON_MODULE(test)
-    {
-        def("names", &names_wrapper);
-    }
-
-

-Nice heh? -Pyste supports this mechanism too. You declare the names_wrapper function in a -header, like "test_wrappers.h", and in the interface file:

-
-    Include("test_wrappers.h")
-    names = Function("names", "test.h")
-    set_wrapper(names, "names_wrapper")
-
-

-You can optionally declare the function in the interface file itself:

-
-    names_wrapper = Wrapper("names_wrapper",
-    """
-    list names_wrapper()
-    {
-        // call name() and convert the vector to a list...
-    }
-    """)
-    names = Function("names", "test.h")
-    set_wrapper(names, names_wrapper)
-
-

-The same mechanism can be done with methods too. Just remember that the first -parameter of wrappers for methods is a pointer to the class, like in - -Boost.Python:

-
-    struct C
-    {
-        std::vector<std::string> names();
-    }
-
-    list names_wrapper(C* c)
-    {
-        // same as before, calling c->names() and converting result to a list
-    }
-
-

-And then in the interface file:

-
-    C = Class("C", "test.h")
-    set_wrapper(C.names, "names_wrapper")
-
- - - - - - -
-
-
- - diff --git a/pyste/example/README b/pyste/example/README deleted file mode 100644 index 868345b0..00000000 --- a/pyste/example/README +++ /dev/null @@ -1,5 +0,0 @@ -To use this examples, just execute the command-line: - -pyste --module= .pyste - -For more information, please refer to the documentation. diff --git a/pyste/example/basic.h b/pyste/example/basic.h deleted file mode 100644 index 5a619e72..00000000 --- a/pyste/example/basic.h +++ /dev/null @@ -1,21 +0,0 @@ -struct C -{ - virtual int f(int x = 10) - { - return x*2; - } - - int foo(int x=1){ - return x+1; - } -}; - -int call_f(C& c) -{ - return c.f(); -} - -int call_f(C& c, int x) -{ - return c.f(x); -} diff --git a/pyste/example/basic.pyste b/pyste/example/basic.pyste deleted file mode 100644 index a6b4e17b..00000000 --- a/pyste/example/basic.pyste +++ /dev/null @@ -1,2 +0,0 @@ -Class('C', 'basic.h') -Function('call_f', 'basic.h') diff --git a/pyste/example/enums.h b/pyste/example/enums.h deleted file mode 100644 index 440cefd2..00000000 --- a/pyste/example/enums.h +++ /dev/null @@ -1,18 +0,0 @@ -namespace test { -enum color { red, blue }; - -struct X -{ - enum choices - { - good = 1, - bad = 2 - }; - - int set(choices c) - { - return (int)c; - } -}; - -} diff --git a/pyste/example/enums.pyste b/pyste/example/enums.pyste deleted file mode 100644 index dd9d7fbc..00000000 --- a/pyste/example/enums.pyste +++ /dev/null @@ -1,8 +0,0 @@ -color = Enum('test::color', 'enums.h') -rename(color.red, 'Red') -rename(color.blue, 'Blue') -X = Class('test::X', 'enums.h') -rename(X.choices.bad, 'Bad') -rename(X.choices.good, 'Good') -rename(X.choices, 'Choices') - diff --git a/pyste/example/header_test.h b/pyste/example/header_test.h deleted file mode 100644 index d3d60fcc..00000000 --- a/pyste/example/header_test.h +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include - -enum choice { red, blue }; - -void print_choice(choice c) -{ - std::map choice_map; - choice_map[red] = "red"; - choice_map[blue] = "blue"; - std::cout << "You chose: " << choice_map[c] << std::endl; -} - -struct C -{ - choice c; - - void print_() - { - print_choice(c); - } -}; diff --git a/pyste/example/header_test.pyste b/pyste/example/header_test.pyste deleted file mode 100644 index b0e752ff..00000000 --- a/pyste/example/header_test.pyste +++ /dev/null @@ -1 +0,0 @@ -AllFromHeader('header_test.h') diff --git a/pyste/example/nested.h b/pyste/example/nested.h deleted file mode 100644 index 35804fbb..00000000 --- a/pyste/example/nested.h +++ /dev/null @@ -1,21 +0,0 @@ - -struct X -{ - struct Y - { - int valueY; - static int staticYValue; - struct Z - { - int valueZ; - }; - }; - - static int staticXValue; - int valueX; -}; - -int X::staticXValue = 10; -int X::Y::staticYValue = 20; - -typedef X Root; diff --git a/pyste/example/nested.pyste b/pyste/example/nested.pyste deleted file mode 100644 index b6291385..00000000 --- a/pyste/example/nested.pyste +++ /dev/null @@ -1 +0,0 @@ -Class('Root', 'nested.h') diff --git a/pyste/example/operator.h b/pyste/example/operator.h deleted file mode 100644 index 5c07549b..00000000 --- a/pyste/example/operator.h +++ /dev/null @@ -1,47 +0,0 @@ -#include - - -struct C -{ - static double x; - double value; - - const C operator+(const C other) const - { - C c; - c.value = value + other.value; - return c; - } - operator int() const - { - return value; - } - double operator()() - { - return x; - } - - double operator()(double other) - { - return x + other; - } - - -}; - -double C::x = 10; - -const C operator*(const C& lhs, const C& rhs) -{ - C c; - c.value = lhs.value * rhs.value; - return c; -} - -std::ostream& operator <<( std::ostream& s, const C& c) -{ - std::cout << "here"; - s << "C instance: "; - return s; -} - diff --git a/pyste/example/operator.pyste b/pyste/example/operator.pyste deleted file mode 100644 index ffa5725c..00000000 --- a/pyste/example/operator.pyste +++ /dev/null @@ -1,12 +0,0 @@ -Include('iostream') -test = Wrapper('sum', -''' -const C sum(const C&, const C&) -{ - std::cout << "sum!" << std::endl; - return C(); -} -''' -) -C = Class('C', 'operator.h') -set_wrapper(C.operator['+'], test) diff --git a/pyste/example/templates.h b/pyste/example/templates.h deleted file mode 100644 index de2afe44..00000000 --- a/pyste/example/templates.h +++ /dev/null @@ -1,8 +0,0 @@ - -template -struct Point -{ - X x; - Y y; -}; - diff --git a/pyste/example/templates.pyste b/pyste/example/templates.pyste deleted file mode 100644 index 30bef79e..00000000 --- a/pyste/example/templates.pyste +++ /dev/null @@ -1,8 +0,0 @@ -Point = Template('Point', 'templates.h') -rename(Point.x, 'i') -rename(Point.y, 'j') -IPoint = Point('int double') -FPoint = Point('double int') -rename(IPoint, 'IPoint') -rename(IPoint.x, '_x_') - diff --git a/pyste/example/wrappertest.h b/pyste/example/wrappertest.h deleted file mode 100644 index a75cddcc..00000000 --- a/pyste/example/wrappertest.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef WRAPPER_TEST -#define WRAPPER_TEST - - -#include - -std::vector Range(int count) -{ - std::vector v; - v.reserve(count); - for (int i = 0; i < count; ++i){ - v.push_back(i); - } - return v; -} - - -struct C -{ - C() {} - - std::vector Mul(int value) - { - std::vector res; - res.reserve(value); - std::vector::const_iterator it; - std::vector v(Range(value)); - for (it = v.begin(); it != v.end(); ++it){ - res.push_back(*it * value); - } - return res; - } -}; - -#endif diff --git a/pyste/example/wrappertest.pyste b/pyste/example/wrappertest.pyste deleted file mode 100644 index 80c76cda..00000000 --- a/pyste/example/wrappertest.pyste +++ /dev/null @@ -1,15 +0,0 @@ -Include('wrappertest_wrappers.h') - -f = Function('Range', 'wrappertest.h') -set_wrapper(f, 'RangeWrapper') - -mul = Wrapper('MulWrapper', -''' -list MulWrapper(C& c, int value){ - return VectorToList(c.Mul(value)); -} -''' -) - -C = Class('C', 'wrappertest.h') -set_wrapper(C.Mul, mul) diff --git a/pyste/example/wrappertest_wrappers.h b/pyste/example/wrappertest_wrappers.h deleted file mode 100644 index a45c3671..00000000 --- a/pyste/example/wrappertest_wrappers.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef WRAPPER_TEST_WRAPPERS -#define WRAPPER_TEST_WRAPPERS - -#include -#include -#include "wrappertest.h" - -using namespace boost::python; - -template -list VectorToList(const std::vector & v) -{ - list res; - std::vector::const_iterator it; - for(it = v.begin(); it != v.end(); ++it){ - res.append(*it); - } - Py_XINCREF(res.ptr()); - return res; -} - -list RangeWrapper(int count){ - return VectorToList(Range(count)); -} - -#endif diff --git a/pyste/index.html b/pyste/index.html deleted file mode 100644 index ff153b50..00000000 --- a/pyste/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - -Pyste Documentation - - - - - - - - - -
- - Pyste Documentation -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table of contents
- Introduction -
- Running Pyste -
- The Interface Files -
- Renaming and Excluding -
- Policies -
- Templates -
- Wrappers -
- Exporting All Declarations from a Header -
-
-
- - diff --git a/pyste/src/.cvsignore b/pyste/src/.cvsignore deleted file mode 100644 index 0d20b648..00000000 --- a/pyste/src/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/pyste/src/ClassExporter.py b/pyste/src/ClassExporter.py deleted file mode 100644 index 64bf3834..00000000 --- a/pyste/src/ClassExporter.py +++ /dev/null @@ -1,726 +0,0 @@ -import exporters -from Exporter import Exporter -from declarations import * -from enumerate import enumerate -from settings import * -from CodeUnit import CodeUnit -from EnumExporter import EnumExporter - - -#============================================================================== -# ClassExporter -#============================================================================== -class ClassExporter(Exporter): - 'Generates boost.python code to export a class declaration' - - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - # sections of code - self.sections = {} - # template: each item in the list is an item into the class_<...> - # section. - self.sections['template'] = [] - # constructor: each item in the list is a parameter to the class_ - # constructor, like class_(...) - self.sections['constructor'] = [] - # inside: everything within the class_<> statement - self.sections['inside'] = [] - # scope: items outside the class statement but within its scope. - # scope* s = new scope(class<>()); - # ... - # delete s; - self.sections['scope'] = [] - # declarations: outside the BOOST_PYTHON_MODULE macro - self.sections['declaration'] = [] - self.sections['include'] = [] - # a list of Constructor instances - self.constructors = [] - self.wrapper_generator = None - # a list of code units, generated by nested declarations - self.nested_codeunits = [] - - - def ScopeName(self): - return _ID(self.class_.FullName()) + '_scope' - - - def Name(self): - return self.class_.FullName() - - - def SetDeclarations(self, declarations): - Exporter.SetDeclarations(self, declarations) - decl = self.GetDeclaration(self.info.name) - if isinstance(decl, Typedef): - self.class_ = decl.type - if not self.info.rename: - self.info.rename = decl.name - else: - self.class_ = decl - self.public_members = \ - [x for x in self.class_.members if x.visibility == Scope.public] - - - def Order(self): - '''Return the TOTAL number of bases that this class has, including the - bases' bases. Do this because base classes must be instantialized - before the derived classes in the module definition. - ''' - - def BasesCount(classname): - decl = self.GetDeclaration(classname) - bases = [x.name for x in decl.bases] - total = 0 - for base in bases: - total += BasesCount(base) - return len(bases) + total - - return BasesCount(self.class_.FullName()) - - - def Export(self, codeunit, exported_names): - self.ExportBasics() - self.ExportBases(exported_names) - self.ExportConstructors() - self.ExportVariables() - self.ExportMethods() - self.ExportVirtualMethods() - self.ExportOperators() - self.ExportNestedClasses(exported_names) - self.ExportNestedEnums() - self.Write(codeunit) - - - def Write(self, codeunit): - indent = self.INDENT - boost_ns = namespaces.python - pyste_ns = namespaces.pyste - code = '' - # begin a scope for this class if needed - nested_codeunits = self.nested_codeunits - needs_scope = self.sections['scope'] or nested_codeunits - if needs_scope: - scope_name = self.ScopeName() - code += indent + boost_ns + 'scope* %s = new %sscope(\n' %\ - (scope_name, boost_ns) - # export the template section - template_params = ', '.join(self.sections['template']) - code += indent + boost_ns + 'class_< %s >' % template_params - # export the constructor section - constructor_params = ', '.join(self.sections['constructor']) - code += '(%s)\n' % constructor_params - # export the inside section - in_indent = indent*2 - for line in self.sections['inside']: - code += in_indent + line + '\n' - # write the scope section and end it - if not needs_scope: - code += indent + ';\n' - else: - code += indent + ');\n' - for line in self.sections['scope']: - code += indent + line + '\n' - # write the contents of the nested classes - for nested_unit in nested_codeunits: - code += '\n' + nested_unit.Section('module') - # close the scope - code += indent + 'delete %s;\n' % scope_name - - # write the code to the module section in the codeunit - codeunit.Write('module', code + '\n') - - # write the declarations to the codeunit - declarations = '\n'.join(self.sections['declaration']) - for nested_unit in nested_codeunits: - declarations += nested_unit.Section('declaration') - if declarations: - codeunit.Write('declaration', declarations + '\n') - - # write the includes to the codeunit - includes = '\n'.join(self.sections['include']) - for nested_unit in nested_codeunits: - includes += nested_unit.Section('include') - if includes: - codeunit.Write('include', includes) - - - def Add(self, section, item): - 'Add the item into the corresponding section' - self.sections[section].append(item) - - - def ExportBasics(self): - 'Export the name of the class and its class_ statement' - self.Add('template', self.class_.FullName()) - name = self.info.rename or self.class_.name - self.Add('constructor', '"%s"' % name) - - - def ExportBases(self, exported_names): - 'Expose the bases of the class into the template section' - bases = self.class_.bases - bases_list = [] - for base in bases: - if base.visibility == Scope.public and base.name in exported_names: - bases_list.append(base.name) - if bases_list: - code = namespaces.python + 'bases< %s > ' % \ - (', '.join(bases_list)) - self.Add('template', code) - - - def ExportConstructors(self): - '''Exports all the public contructors of the class, plus indicates if the - class is noncopyable. - ''' - py_ns = namespaces.python - indent = self.INDENT - - def init_code(cons): - 'return the init<>() code for the given contructor' - param_list = [p.FullName() for p in cons.parameters] - min_params_list = param_list[:cons.minArgs] - max_params_list = param_list[cons.minArgs:] - min_params = ', '.join(min_params_list) - max_params = ', '.join(max_params_list) - init = py_ns + 'init< ' - init += min_params - if max_params: - if min_params: - init += ', ' - init += py_ns + ('optional< %s >' % max_params) - init += ' >()' - return init - - constructors = [x for x in self.public_members if isinstance(x, Constructor)] - self.constructors = constructors[:] - if not constructors: - # declare no_init - self.Add('constructor', py_ns + 'no_init') - else: - # write the constructor with less parameters to the constructor section - smaller = None - for cons in constructors: - if smaller is None or len(cons.parameters) < len(smaller.parameters): - smaller = cons - assert smaller is not None - self.Add('constructor', init_code(smaller)) - constructors.remove(smaller) - # write the rest to the inside section, using def() - for cons in constructors: - code = '.def(%s)' % init_code(cons) - self.Add('inside', code) - # check if the class is copyable - if not self.class_.HasCopyConstructor() or self.class_.abstract: - self.Add('template', namespaces.boost + 'noncopyable') - - - def ExportVariables(self): - 'Export the variables of the class, both static and simple variables' - vars = [x for x in self.public_members if isinstance(x, Variable)] - for var in vars: - if self.info[var.name].exclude: - continue - name = self.info[var.name].rename or var.name - fullname = var.FullName() - if var.static: - code = '%s->attr("%s") = %s;' % (self.ScopeName(), name, fullname) - self.Add('scope', code) - else: - if var.type.const: - def_ = '.def_readonly' - else: - def_ = '.def_readwrite' - code = '%s("%s", &%s)' % (def_, name, fullname) - self.Add('inside', code) - - - printed_policy_warnings = {} - - def CheckPolicy(self, m): - 'Warns the user if this method needs a policy' - def IsString(type): - return type.const and type.name == 'char' and isinstance(type, PointerType) - needs_policy = isinstance(m.result, (ReferenceType, PointerType)) - if IsString(m.result): - needs_policy = False - has_policy = self.info[m.name].policy is not None - if needs_policy and not has_policy: - warning = '---> Error: Method "%s" needs a policy.' % m.FullName() - if warning not in self.printed_policy_warnings: - print warning - print - self.printed_policy_warnings[warning] = 1 - - - def ExportMethods(self): - 'Export all the non-virtual methods of this class' - - def OverloadName(m): - 'Returns the name of the overloads struct for the given method' - return _ID(m.FullName()) + ('_overloads_%i_%i' % (m.minArgs, m.maxArgs)) - - declared = {} - def DeclareOverloads(m): - 'Declares the macro for the generation of the overloads' - if not m.virtual: - func = m.name - code = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(%s, %s, %i, %i)\n' - code = code % (OverloadName(m), func, m.minArgs, m.maxArgs) - if code not in declared: - declared[code] = True - self.Add('declaration', code) - - - def Pointer(m): - 'returns the correct pointer declaration for the method m' - # check if this method has a wrapper set for him - wrapper = self.info[method.name].wrapper - if wrapper: - return '&' + wrapper.FullName() - # return normal pointers to the methods of the class - is_unique = self.class_.IsUnique(m.name) - if is_unique: - return '&' + method.FullName() - else: - return method.PointerDeclaration() - - def IsExportable(m): - 'Returns true if the given method is exportable by this routine' - ignore = (Constructor, ClassOperator, Destructor) - return isinstance(m, Method) and not isinstance(m, ignore) and not m.virtual - - methods = [x for x in self.public_members if IsExportable(x)] - - for method in methods: - if self.info[method.name].exclude: - continue # skip this method - - name = self.info[method.name].rename or method.name - - # warn the user if this method needs a policy and doesn't have one - self.CheckPolicy(method) - - # check for policies - policy = self.info[method.name].policy or '' - if policy: - policy = ', %s%s()' % (namespaces.python, policy.Code()) - # check for overloads - overload = '' - if method.minArgs != method.maxArgs: - # add the overloads for this method - overload_name = OverloadName(method) - DeclareOverloads(method) - overload = ', %s%s()' % (namespaces.pyste, overload_name) - - # build the .def string to export the method - pointer = Pointer(method) - code = '.def("%s", %s' % (name, pointer) - code += policy - code += overload - code += ')' - self.Add('inside', code) - # static method - if method.static: - code = '.staticmethod("%s")' % name - self.Add('inside', code) - # add wrapper code if this method has one - wrapper = self.info[method.name].wrapper - if wrapper and wrapper.code: - self.Add('declaration', wrapper.code) - - - def ExportVirtualMethods(self): - # check if this class has any virtual methods - has_virtual_methods = False - for member in self.class_.members: - if type(member) == Method and member.virtual: - has_virtual_methods = True - break - - if has_virtual_methods: - generator = _VirtualWrapperGenerator(self.class_, self.info) - self.Add('template', generator.FullName()) - for definition in generator.GenerateDefinitions(): - self.Add('inside', definition) - self.Add('declaration', generator.GenerateVirtualWrapper(self.INDENT)) - - - # operators natively supported by boost - BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -='\ - '*= /= %= ^= &= |= <<= >>='.split() - # create a map for faster lookup - BOOST_SUPPORTED_OPERATORS = dict(zip(BOOST_SUPPORTED_OPERATORS, range(len(BOOST_SUPPORTED_OPERATORS)))) - - # a dict of operators that are not directly supported by boost, but can be exposed - # simply as a function with a special signature - BOOST_RENAME_OPERATORS = { - '()' : '__call__', - } - - # converters which has a special name in python - SPECIAL_CONVETERS = { - 'double' : '__float__', - 'float' : '__float__', - 'int' : '__int__', - } - - - def ExportOperators(self): - 'Export all member operators and free operators related to this class' - - def GetFreeOperators(): - 'Get all the free (global) operators related to this class' - operators = [] - for decl in self.declarations: - if isinstance(decl, Operator): - # check if one of the params is this class - for param in decl.parameters: - if param.name == self.class_.FullName(): - operators.append(decl) - break - return operators - - def GetOperand(param): - 'Returns the operand of this parameter (either "self", or "other")' - if param.name == self.class_.FullName(): - return namespaces.python + 'self' - else: - return namespaces.python + ('other< %s >()' % param.name) - - - def HandleSpecialOperator(operator): - # gatter information about the operator and its parameters - result_name = operator.result.name - param1_name = '' - if operator.parameters: - param1_name = operator.parameters[0].name - - # check for str - ostream = 'basic_ostream' - is_str = result_name.find(ostream) != -1 and param1_name.find(ostream) != -1 - if is_str: - namespace = namespaces.python + 'self_ns::' - self_ = namespaces.python + 'self' - return '.def(%sstr(%s))' % (namespace, self_) - - # is not a special operator - return None - - - - frees = GetFreeOperators() - members = [x for x in self.public_members if type(x) == ClassOperator] - all_operators = frees + members - operators = [x for x in all_operators if not self.info['operator'][x.name].exclude] - - for operator in operators: - # gatter information about the operator, for use later - wrapper = self.info['operator'][operator.name].wrapper - if wrapper: - pointer = '&' + wrapper.FullName() - if wrapper.code: - self.Add('declaration', wrapper.code) - elif isinstance(operator, ClassOperator) and self.class_.IsUnique(operator.name): - pointer = '&' + operator.FullName() - else: - pointer = operator.PointerDeclaration() - rename = self.info['operator'][operator.name].rename - - # check if this operator will be exported as a method - export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS - - # check if this operator has a special representation in boost - special_code = HandleSpecialOperator(operator) - has_special_representation = special_code is not None - - if export_as_method: - # export this operator as a normal method, renaming or using the given wrapper - if not rename: - if wrapper: - rename = wrapper.name - else: - rename = self.BOOST_RENAME_OPERATORS[operator.name] - policy = '' - policy_obj = self.info['operator'][operator.name].policy - if policy_obj: - policy = ', %s()' % policy_obj.Code() - self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy)) - - elif has_special_representation: - self.Add('inside', special_code) - - elif operator.name in self.BOOST_SUPPORTED_OPERATORS: - # export this operator using boost's facilities - op = operator - is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\ - isinstance(op, ClassOperator) and len(op.parameters) == 0 - if is_unary: - self.Add('inside', '.def( %s%sself )' % \ - (operator.name, namespaces.python)) - else: - # binary operator - if len(operator.parameters) == 2: - left_operand = GetOperand(operator.parameters[0]) - right_operand = GetOperand(operator.parameters[1]) - else: - left_operand = namespaces.python + 'self' - right_operand = GetOperand(operator.parameters[0]) - self.Add('inside', '.def( %s %s %s )' % \ - (left_operand, operator.name, right_operand)) - - # export the converters. - # export them as simple functions with a pre-determined name - - converters = [x for x in self.public_members if type(x) == ConverterOperator] - - def ConverterMethodName(converter): - result_fullname = converter.result.name - # extract the last name from the full name - result_name = _ID(result_fullname.split('::')[-1]) - return 'to_' + result_name - - for converter in converters: - info = self.info['operator'][converter.result.name] - # check if this operator should be excluded - if info.exclude: - continue - - special_code = HandleSpecialOperator(converter) - if info.rename or not special_code: - # export as method - name = info.rename or ConverterMethodName(converter) - if self.class_.IsUnique(converter.name): - pointer = '&' + converter.FullName() - else: - pointer = converter.PointerDeclaration() - policy_code = '' - if info.policy: - policy_code = ', %s()' % info.policy.Code() - self.Add('inside', '.def("%s", %s%s)' % (name, pointer, policy_code)) - - elif special_code: - self.Add('inside', special_code) - - - - def ExportNestedClasses(self, exported_names): - nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)] - for nested_class in nested_classes: - nested_info = self.info[nested_class.name] - nested_info.include = self.info.include - nested_info.name = nested_class.FullName() - exporter = ClassExporter(nested_info) - exporter.SetDeclarations(self.declarations + [nested_class]) - codeunit = CodeUnit(None) - exporter.Export(codeunit, exported_names) - self.nested_codeunits.append(codeunit) - - - def ExportNestedEnums(self): - nested_enums = [x for x in self.public_members if isinstance(x, ClassEnumeration)] - for enum in nested_enums: - enum_info = self.info[enum.name] - enum_info.include = self.info.include - enum_info.name = enum.FullName() - exporter = EnumExporter(enum_info) - exporter.SetDeclarations(self.declarations + [enum]) - codeunit = CodeUnit(None) - exporter.Export(codeunit, None) - self.nested_codeunits.append(codeunit) - - - - -def _ID(name): - 'Returns the name as a valid identifier' - for invalidchar in ('::', '<', '>', ' ', ','): - name = name.replace(invalidchar, '_') - # avoid duplications of '_' chars - names = [x for x in name.split('_') if x] - return '_'.join(names) - - -#============================================================================== -# Virtual Wrapper utils -#============================================================================== - -def _ParamsInfo(m, count=None): - if count is None: - count = len(m.parameters) - param_names = ['p%i' % i for i in range(count)] - param_types = [x.FullName() for x in m.parameters[:count]] - params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)] - #for i, p in enumerate(m.parameters[:count]): - # if p.default is not None: - # #params[i] += '=%s' % p.default - # params[i] += '=%s' % (p.name + '()') - params = ', '.join(params) - return params, param_names, param_types - - -class _VirtualWrapperGenerator(object): - 'Generates code to export the virtual methods of the given class' - - def __init__(self, class_, info): - self.class_ = class_ - self.info = info - self.wrapper_name = _ID(class_.FullName()) + '_Wrapper' - - - def DefaultImplementationNames(self, method): - '''Returns a list of default implementations for this method, one for each - number of default arguments. Always returns at least one name, and return from - the one with most arguments to the one with the least. - ''' - base_name = 'default_' + method.name - minArgs = method.minArgs - maxArgs = method.maxArgs - if minArgs == maxArgs: - return [base_name] - else: - return [base_name + ('_%i' % i) for i in range(minArgs, maxArgs+1)] - - - def Declaration(self, method, indent): - '''Returns a string with the declarations of the virtual wrapper and - its default implementations. This string must be put inside the Wrapper - body. - ''' - pyste = namespaces.pyste - python = namespaces.python - rename = self.info[method.name].rename or method.name - result = method.result.FullName() - return_str = 'return ' - if result == 'void': - return_str = '' - params, param_names, param_types = _ParamsInfo(method) - constantness = '' - if method.const: - constantness = ' const' - - # call_method callback - decl = indent + '%s %s(%s)%s {\n' % (result, method.name, params, constantness) - param_names_str = ', '.join(param_names) - if param_names_str: - param_names_str = ', ' + param_names_str - decl += indent*2 + '%s%scall_method<%s>(self, "%s"%s);\n' %\ - (return_str, python, result, rename, param_names_str) - decl += indent + '}\n' - - # default implementations (with overloading) - if not method.abstract: - minArgs = method.minArgs - maxArgs = method.maxArgs - impl_names = self.DefaultImplementationNames(method) - for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)): - params, param_names, param_types = _ParamsInfo(method, argNum) - decl += '\n' - decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness) - decl += indent*2 + '%s%s::%s(%s);\n' % \ - (return_str, self.class_.FullName(), method.name, ', '.join(param_names)) - decl += indent + '}\n' - return decl - - - def MethodDefinition(self, method): - '''Returns a list of lines, which should be put inside the class_ - statement to export this method.''' - # dont define abstract methods - if method.abstract: - return [] - pyste = namespaces.pyste - rename = self.info[method.name].rename or method.name - default_names = self.DefaultImplementationNames(method) - class_name = self.class_.FullName() - wrapper_name = pyste + self.wrapper_name - result = method.result.FullName() - is_method_unique = self.class_.IsUnique(method.name) - constantness = '' - if method.const: - constantness = ' const' - - # create a list of default-impl pointers - minArgs = method.minArgs - maxArgs = method.maxArgs - if is_method_unique: - default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names] - else: - default_pointers = [] - for impl_name, argNum in zip(default_names, range(minArgs, maxArgs+1)): - param_list = [x.FullName() for x in method.parameters[:argNum]] - params = ', '.join(param_list) - signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness) - default_pointer = '(%s)%s::%s' % (signature, wrapper_name, impl_name) - default_pointers.append(default_pointer) - - # get the pointer of the method - if is_method_unique: - pointer = '&' + method.FullName() - else: - pointer = method.PointerDeclaration() - - # generate the defs - definitions = [] - # basic def - definitions.append('.def("%s", %s, %s)' % (rename, pointer, default_pointers[-1])) - for default_pointer in default_pointers[:-1]: - definitions.append('.def("%s", %s)' % (rename, default_pointer)) - return definitions - - - def FullName(self): - return namespaces.pyste + self.wrapper_name - - - def VirtualMethods(self): - return [m for m in self.class_.members if type(m) == Method and m.virtual] - - - def Constructors(self): - return [m for m in self.class_.members if isinstance(m, Constructor)] - - - def GenerateDefinitions(self): - defs = [] - for method in self.VirtualMethods(): - if not self.info[method.name].exclude: - defs.extend(self.MethodDefinition(method)) - return defs - - - def GenerateVirtualWrapper(self, indent): - 'Return the wrapper for this class' - - # generate the class code - class_name = self.class_.FullName() - code = 'struct %s: %s\n' % (self.wrapper_name, class_name) - code += '{\n' - # generate constructors (with the overloads for each one) - for cons in self.Constructors(): - minArgs = cons.minArgs - maxArgs = cons.maxArgs - # from the min number of arguments to the max number, generate - # all version of the given constructor - cons_code = '' - for argNum in range(minArgs, maxArgs+1): - params, param_names, param_types = _ParamsInfo(cons, argNum) - if params: - params = ', ' + params - cons_code += indent + '%s(PyObject* self_%s):\n' % \ - (self.wrapper_name, params) - cons_code += indent*2 + '%s(%s), self(self_) {}\n\n' % \ - (class_name, ', '.join(param_names)) - code += cons_code - # generate the body - body = [] - for method in self.VirtualMethods(): - if not self.info[method.name].exclude: - body.append(self.Declaration(method, indent)) - body = '\n'.join(body) - code += body + '\n' - # add the self member - code += indent + 'PyObject* self;\n' - code += '};\n' - return code diff --git a/pyste/src/CodeUnit.py b/pyste/src/CodeUnit.py deleted file mode 100644 index ac123f99..00000000 --- a/pyste/src/CodeUnit.py +++ /dev/null @@ -1,78 +0,0 @@ -from settings import * - -#============================================================================== -# RemoveDuplicatedLines -#============================================================================== -def RemoveDuplicatedLines(text): - includes = text.splitlines() - d = dict([(include, 0) for include in includes]) - return '\n'.join(d.keys()) - - -#============================================================================== -# CodeUnit -#============================================================================== -class CodeUnit: - ''' - Represents a cpp file, where other objects can write in one of the - predefined sections. - The avaiable sections are: - include - The include area of the cpp file - declaration - The part before the module definition - module - Inside the BOOST_PYTHON_MODULE macro - ''' - - USING_BOOST_NS = True - - def __init__(self, modulename): - self.modulename = modulename - # define the avaiable sections - self.code = {} - self.code['include'] = '' - self.code['declaration'] = '' - self.code['module'] = '' - - - def Write(self, section, code): - 'write the given code in the section of the code unit' - if section not in self.code: - raise RuntimeError, 'Invalid CodeUnit section: %s' % section - self.code[section] += code - - - def Section(self, section): - return self.code[section] - - - def Save(self, filename): - 'Writes this code unit to the filename' - space = '\n\n' - fout = file(filename, 'w') - # includes - includes = RemoveDuplicatedLines(self.code['include']) - fout.write('\n' + self._leftEquals('Includes')) - fout.write('#include \n') - fout.write(includes) - fout.write(space) - # using - if self.USING_BOOST_NS: - fout.write(self._leftEquals('Using')) - fout.write('using namespace boost::python;\n\n') - # declarations - if self.code['declaration']: - pyste_namespace = namespaces.pyste[:-2] - fout.write(self._leftEquals('Declarations')) - fout.write('namespace %s {\n\n\n' % pyste_namespace) - fout.write(self.code['declaration']) - fout.write('\n\n}// namespace %s\n' % pyste_namespace) - fout.write(space) - # module - fout.write(self._leftEquals('Module')) - fout.write('BOOST_PYTHON_MODULE(%s)\n{\n' % self.modulename) - fout.write(self.code['module']) - fout.write('}\n') - - - def _leftEquals(self, s): - s = '// %s ' % s - return s + ('='*(80-len(s))) + '\n' diff --git a/pyste/src/CppParser.py b/pyste/src/CppParser.py deleted file mode 100644 index 2dd9c9ff..00000000 --- a/pyste/src/CppParser.py +++ /dev/null @@ -1,94 +0,0 @@ -from GCCXMLParser import ParseDeclarations -import tempfile -import shutil -import os -import os.path -import settings - -class CppParserError(Exception): pass - - -class CppParser: - 'Parses a header file and returns a list of declarations' - - def __init__(self, includes=None, defines=None): - 'includes and defines ar the directives given to gcc' - if includes is None: - includes = [] - if defines is None: - defines = [] - self.includes = includes - self.defines = defines - - - def _includeparams(self, filename): - includes = self.includes[:] - filedir = os.path.dirname(filename) - if not filedir: - filedir = '.' - includes.insert(0, filedir) - includes = ['-I "%s"' % x for x in includes] - return ' '.join(includes) - - - def _defineparams(self): - defines = ['-D "%s"' % x for x in self.defines] - return ' '.join(defines) - - - def FindFileName(self, include): - if os.path.isfile(include): - return include - for path in self.includes: - filename = os.path.join(path, include) - if os.path.isfile(filename): - return filename - name = os.path.basename(include) - raise RuntimeError, 'Header file "%s" not found!' % name - - - def parse(self, include, symbols=None, tail=None): - '''Parses the given filename, and returns (declaration, header). The - header returned is normally the same as the given to this method, - except if tail is not None: in this case, the header is copied to a temp - filename and the tail code is appended to it before being passed on to gcc. - This temp filename is then returned. - ''' - filename = self.FindFileName(include) - # copy file to temp folder, if needed - if tail: - tempfilename = tempfile.mktemp('.h') - infilename = tempfilename - shutil.copy(filename, infilename) - f = file(infilename, 'a') - f.write('\n\n'+tail) - f.close() - else: - infilename = filename - xmlfile = tempfile.mktemp('.xml') - try: - # get the params - includes = self._includeparams(filename) - defines = self._defineparams() - # call gccxml - cmd = 'gccxml %s %s %s -fxml=%s' \ - % (includes, defines, infilename, xmlfile) - if symbols: - cmd += ' -fxml-start=' + ','.join(symbols) - status = os.system(cmd) - if status != 0 or not os.path.isfile(xmlfile): - raise CppParserError, 'Error executing gccxml' - # parse the resulting xml - declarations = ParseDeclarations(xmlfile) - # return the declarations - return declarations, infilename - finally: - if settings.DEBUG and os.path.isfile(xmlfile): - filename = os.path.basename(include) - shutil.copy(xmlfile, os.path.splitext(filename)[0] + '.xml') - # delete the temporary files - try: - os.remove(xmlfile) - if tail: - os.remove(tempfilename) - except OSError: pass diff --git a/pyste/src/EnumExporter.py b/pyste/src/EnumExporter.py deleted file mode 100644 index fda4d721..00000000 --- a/pyste/src/EnumExporter.py +++ /dev/null @@ -1,30 +0,0 @@ -from Exporter import Exporter -from settings import * - -#============================================================================== -# EnumExporter -#============================================================================== -class EnumExporter(Exporter): - 'Exports enumerators' - - def __init__(self, info): - Exporter.__init__(self, info) - - - def SetDeclarations(self, declarations): - Exporter.SetDeclarations(self, declarations) - self.enum = self.GetDeclaration(self.info.name) - - - def Export(self, codeunit, expoted_names): - indent = self.INDENT - in_indent = self.INDENT*2 - rename = self.info.rename or self.enum.name - full_name = self.enum.FullName() - code = indent + namespaces.python + 'enum_< %s >("%s")\n' % (full_name, rename) - for name in self.enum.values: - rename = self.info[name].rename or name - value_fullname = self.enum.ValueFullName(name) - code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname) - code += indent + ';\n\n' - codeunit.Write('module', code) diff --git a/pyste/src/Exporter.py b/pyste/src/Exporter.py deleted file mode 100644 index 02259582..00000000 --- a/pyste/src/Exporter.py +++ /dev/null @@ -1,69 +0,0 @@ -import os.path - -#============================================================================== -# Exporter -#============================================================================== -class Exporter: - 'Base class for objects capable to generate boost.python code.' - - INDENT = ' ' * 4 - - def __init__(self, info, parser_tail=None): - self.info = info - self.parser_tail = parser_tail - - - def Parse(self, parser): - self.parser = parser - header = self.info.include - tail = self.parser_tail - declarations, parser_header = parser.parse(header, tail=tail) - self.parser_header = parser_header - self.SetDeclarations(declarations) - - - def SetDeclarations(self, declarations): - self.declarations = declarations - - - def GenerateCode(self, codeunit, exported_names): - self.WriteInclude(codeunit) - self.Export(codeunit, exported_names) - - - def WriteInclude(self, codeunit): - codeunit.Write('include', '#include <%s>\n' % self.info.include) - - - def Export(self, codeunit, exported_names): - 'subclasses must override this to do the real work' - pass - - - def Name(self): - '''Returns the name of this Exporter. The name will be added to the - list of names exported, which may have a use for other exporters. - ''' - return None - - - def GetDeclarations(self, fullname): - decls = [x for x in self.declarations if x.FullName() == fullname] - if not decls: - raise RuntimeError, 'no %s declaration found!' % fullname - return decls - - - def GetDeclaration(self, fullname): - decls = self.GetDeclarations(fullname) - assert len(decls) == 1 - return decls[0] - - - def Order(self): - '''Returns a number that indicates to which order this exporter - belongs. The exporters will be called from the lowest order to the - highest order. - This function will only be called after Parse has been called. - ''' - return None # don't care diff --git a/pyste/src/FunctionExporter.py b/pyste/src/FunctionExporter.py deleted file mode 100644 index 60735ca0..00000000 --- a/pyste/src/FunctionExporter.py +++ /dev/null @@ -1,85 +0,0 @@ -from Exporter import Exporter -from policies import * -from declarations import * -from settings import * - - -class FunctionExporter(Exporter): - 'Generates boost.python code to export the given function.' - - def __init__(self, info, tail=None): - Exporter.__init__(self, info, tail) - - - def Export(self, codeunit, exported_names): - decls = self.GetDeclarations(self.info.name) - for decl in decls: - self.CheckPolicy(decl) - self.ExportDeclaration(decl, len(decls) == 1, codeunit) - self.GenerateOverloads(decls, codeunit) - - - def Name(self): - return self.info.name - - - def CheckPolicy(self, func): - 'Warns the user if this function needs a policy' - def IsString(type): - return type.const and type.name == 'char' and isinstance(type, PointerType) - needs_policy = isinstance(func.result, (ReferenceType, PointerType)) - if IsString(func.result): - needs_policy = False - if needs_policy and self.info.policy is None: - print '---> Error: Function "%s" needs a policy.' % func.FullName() - print - - def ExportDeclaration(self, decl, unique, codeunit): - name = self.info.rename or decl.name - defs = namespaces.python + 'def("%s", ' % name - wrapper = self.info.wrapper - if wrapper: - pointer = '&' + wrapper.FullName() - elif not unique: - pointer = decl.PointerDeclaration() - else: - pointer = '&' + decl.FullName() - defs += pointer - defs += self.PolicyCode() - overload = self.OverloadName(decl) - if overload: - defs += ', %s()' % (namespaces.pyste + overload) - defs += ');' - codeunit.Write('module', self.INDENT + defs + '\n') - # add the code of the wrapper - if wrapper and wrapper.code: - codeunit.Write('declaration', code + '\n') - - - def OverloadName(self, decl): - if decl.minArgs != decl.maxArgs: - return '%s_overloads_%i_%i' % \ - (decl.name, decl.minArgs, decl.maxArgs) - else: - return '' - - - def GenerateOverloads(self, declarations, codeunit): - codes = {} - for decl in declarations: - overload = self.OverloadName(decl) - if overload and overload not in codes: - code = 'BOOST_PYTHON_FUNCTION_OVERLOADS(%s, %s, %i, %i)' %\ - (overload, decl.FullName(), decl.minArgs, decl.maxArgs) - codeunit.Write('declaration', code + '\n') - codes[overload] = None - - - def PolicyCode(self): - policy = self.info.policy - if policy is not None: - assert isinstance(policy, Policy) - return ', %s()' % policy.Code() - else: - return '' - diff --git a/pyste/src/GCCXMLParser.py b/pyste/src/GCCXMLParser.py deleted file mode 100644 index 937db92f..00000000 --- a/pyste/src/GCCXMLParser.py +++ /dev/null @@ -1,395 +0,0 @@ -from declarations import * -from elementtree.ElementTree import ElementTree -from xml.parsers.expat import ExpatError -from copy import deepcopy - - -class InvalidXMLError(Exception): pass - -class ParserError(Exception): pass - -class InvalidContextError(ParserError): pass - - -class GCCXMLParser(object): - 'Parse a GCC_XML file and extract the top-level declarations.' - - interested_tags = {'Class':0, 'Function':0, 'Variable':0, 'Enumeration':0} - - def Parse(self, filename): - self.elements = self.GetElementsFromXML(filename) - # high level declarations - self.declarations = [] - # parse the elements - for id in self.elements: - element, decl = self.elements[id] - if decl is None: - try: - self.ParseElement(id, element) - except InvalidContextError: - pass # ignore those nodes with invalid context - # (workaround gccxml bug) - - - def Declarations(self): - return self.declarations - - - def AddDecl(self, decl): - self.declarations.append(decl) - - - def ParseElement(self, id, element): - method = 'Parse' + element.tag - if hasattr(self, method): - func = getattr(self, method) - func(id, element) - - - def GetElementsFromXML(self,filename): - 'Extracts a dictionary of elements from the gcc_xml file.' - - tree = ElementTree() - try: - tree.parse(filename) - except ExpatError: - raise InvalidXMLError, 'Not a XML file: %s' % filename - - root = tree.getroot() - if root.tag != 'GCC_XML': - raise InvalidXMLError, 'Not a valid GCC_XML file' - - # build a dictionary of id -> element, None - elementlist = root.getchildren() - elements = {} - for element in elementlist: - id = element.get('id') - if id: - elements[id] = element, None - return elements - - - def GetDecl(self, id): - if id not in self.elements: - if id == '_0': - raise InvalidContextError, 'Invalid context found in the xml file.' - else: - msg = 'ID not found in elements: %s' % id - raise ParserError, msg - - elem, decl = self.elements[id] - if decl is None: - self.ParseElement(id, elem) - elem, decl = self.elements[id] - if decl is None: - raise ParserError, 'Could not parse element: %s' % elem.tag - return decl - - - def GetType(self, id): - const = False - volatile = False - if id[-1] == 'v': - volatile = True - id = id[:-1] - if id[-1] == 'c': - const = True - id = id[:-1] - decl = self.GetDecl(id) - if isinstance(decl, Type): - res = deepcopy(decl) - if const: - res.const = const - if volatile: - res.volatile = volatile - else: - res = Type(decl.FullName(), const) - res.volatile = volatile - return res - - - def GetLocation(self, location): - file, line = location.split(':') - file = self.GetDecl(file) - return file, int(line) - - - def Update(self, id, decl): - element, _ = self.elements[id] - self.elements[id] = element, decl - - - def ParseNamespace(self, id, element): - namespace = element.get('name') - context = element.get('context') - if context: - outerns = self.GetDecl(context) - if not outerns.endswith('::'): - outerns += '::' - namespace = outerns + namespace - if namespace.startswith('::'): - namespace = namespace[2:] - self.Update(id, namespace) - - - def ParseFile(self, id, element): - filename = element.get('name') - self.Update(id, filename) - - - def ParseVariable(self, id, element): - # in gcc_xml, a static Field is declared as a Variable, so we check - # this and call the Field parser if apply. - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - self.ParseField(id, element) - elem, decl = self.elements[id] - decl.static = True - else: - namespace = context - name = element.get('name') - type_ = self.GetType(element.get('type')) - location = self.GetLocation(element.get('location')) - variable = Variable(type_, name, namespace) - variable.location = location - self.AddDecl(variable) - self.Update(id, variable) - - - def GetArguments(self, element): - args = [] - for child in element: - if child.tag == 'Argument': - type_ = self.GetType(child.get('type')) - type_.default = child.get('default') - args.append(type_) - return args - - - def ParseFunction(self, id, element, functionType=Function): - '''functionType is used because a Operator is identical to a normal - function, only the type of the function changes.''' - name = element.get('name') - returns = self.GetType(element.get('returns')) - namespace = self.GetDecl(element.get('context')) - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - function = functionType(name, namespace, returns, params) - function.location = location - self.AddDecl(function) - self.Update(id, function) - - - def ParseOperatorFunction(self, id, element): - self.ParseFunction(id, element, Operator) - - - def GetBases(self, bases): - 'Parses the string "bases" from the xml into a list of Base instances.' - - if bases is None: - return [] - bases = bases.split() - baseobjs = [] - for base in bases: - # get the visibility - split = base.split(':') - if len(split) == 2: - visib = split[0] - base = split[1] - else: - visib = Scope.public - decl = self.GetDecl(base) - baseobj = Base(decl.FullName(), visib) - baseobjs.append(baseobj) - return baseobjs - - - def GetMembers(self, members): - # members must be a string with the ids of the members - if members is None: - return [] - memberobjs = [] - for member in members.split(): - memberobjs.append(self.GetDecl(member)) - return memberobjs - - - def ParseClass(self, id, element): - name = element.get('name') - abstract = bool(int(element.get('abstract', '0'))) - bases = self.GetBases(element.get('bases')) - location = self.GetLocation(element.get('location')) - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): # a nested class - visib = element.get('access', Scope.public) - class_ = NestedClass( - name, context.FullName(), visib, [], abstract, bases) - else: - assert isinstance(context, str) - class_ = Class(name, context, [], abstract, bases) - self.AddDecl(class_) - # we have to add the declaration of the class before trying - # to parse its members, to avoid recursion. - class_.location = location - self.Update(id, class_) - # now we can get the members - class_.members = self.GetMembers(element.get('members')) - - - def ParseStruct(self, id, element): - self.ParseClass(id, element) - - - def ParseFundamentalType(self, id, element): - name = element.get('name') - type_ = FundamentalType(name) - self.Update(id, type_) - - - def ParseArrayType(self, id, element): - type_ = self.GetType(element.get('type')) - min = element.get('min') - max = element.get('max') - if min: - min = int(min) - if max: - max = int(max) - array = ArrayType(type_.name, min, max, type_.const) - self.Update(id, array) - - - def ParseReferenceType(self, id, element): - type_ = self.GetType(element.get('type')) - expand = not isinstance(type_, FunctionType) - ref = ReferenceType(type_.name, type_.const, None, expand) - self.Update(id, ref) - - - def ParsePointerType(self, id, element): - type_ = self.GetType(element.get('type')) - expand = not isinstance(type_, FunctionType) - ref = PointerType(type_.name, type_.const, None, expand) - self.Update(id, ref) - - - def ParseFunctionType(self, id, element): - result = self.GetType(element.get('returns')) - args = self.GetArguments(element) - func = FunctionType(result, args) - self.Update(id, func) - - - def ParseMethodType(self, id, element): - class_ = self.GetDecl(element.get('basetype')).FullName() - result = self.GetType(element.get('returns')) - args = self.GetArguments(element) - method = MethodType(result, args, class_) - self.Update(id, method) - - - def ParseField(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - type_ = self.GetType(element.get('type')) - static = bool(int(element.get('extern', '0'))) - location = self.GetLocation(element.get('location')) - var = ClassVariable(type_, name, classname, visib, static) - var.location = location - self.Update(id, var) - - - def ParseMethod(self, id, element, methodType=Method): - name = element.get('name') - result = self.GetType(element.get('returns')) - classname = self.GetDecl(element.get('context')).FullName() - visib = element.get('access', Scope.public) - static = bool(int(element.get('static', '0'))) - virtual = bool(int(element.get('virtual', '0'))) - abstract = bool(int(element.get('pure_virtual', '0'))) - const = bool(int(element.get('const', '0'))) - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - method = methodType( - name, classname, result, params, visib, virtual, abstract, static, const) - method.location = location - self.Update(id, method) - - - def ParseOperatorMethod(self, id, element): - self.ParseMethod(id, element, ClassOperator) - - - def ParseConstructor(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - ctor = Constructor(name, classname, params, visib) - ctor.location = location - self.Update(id, ctor) - - - def ParseDestructor(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - virtual = bool(int(element.get('virtual', '0'))) - location = self.GetLocation(element.get('location')) - des = Destructor(name, classname, visib, virtual) - des.location = location - self.Update(id, des) - - - def ParseConverter(self, id, element): - self.ParseMethod(id, element, ConverterOperator) - - - def ParseTypedef(self, id, element): - name = element.get('name') - type = self.GetDecl(element.get('type')) - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - context = context.FullName() - typedef = Typedef(type, name, context) - self.Update(id, typedef) - self.AddDecl(typedef) - - - def ParseEnumeration(self, id, element): - name = element.get('name') - location = self.GetLocation(element.get('location')) - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - visib = element.get('access', Scope.public) - enum = ClassEnumeration(name, context.FullName(), visib) - else: - enum = Enumeration(name, context) - self.AddDecl(enum) # in this case, is a top level decl - enum.location = location - for child in element: - if child.tag == 'EnumValue': - name = child.get('name') - value = int(child.get('init')) - enum.values[name] = value - self.Update(id, enum) - - - def ParseUnimplemented(self, id, element): - 'No idea of what this is' - self.Update(id, Declaration('', '')) - - - def ParseUnion(self, id, element): - self.Update(id, Declaration(element.get('name'), '')) - - - -def ParseDeclarations(filename): - 'Returns a list of the top declarations found in the gcc_xml file.' - - parser = GCCXMLParser() - parser.Parse(filename) - return parser.Declarations() diff --git a/pyste/src/HeaderExporter.py b/pyste/src/HeaderExporter.py deleted file mode 100644 index 9234e8af..00000000 --- a/pyste/src/HeaderExporter.py +++ /dev/null @@ -1,67 +0,0 @@ -from Exporter import Exporter -from ClassExporter import ClassExporter -from FunctionExporter import FunctionExporter -from EnumExporter import EnumExporter -from infos import * -from declarations import * -import os.path -import exporters - -#============================================================================== -# HeaderExporter -#============================================================================== -class HeaderExporter(Exporter): - 'Exports all declarations found in the given header' - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - - - def WriteInclude(self, codeunit): - pass - - - def SetDeclarations(self, declarations): - def IsInternalName(name): - '''Returns true if the given name looks like a internal compiler - structure''' - return name.startswith('__') - - Exporter.SetDeclarations(self, declarations) - header = os.path.normpath(self.parser_header) - for decl in declarations: - # check if this declaration is in the header - location = os.path.normpath(decl.location[0]) - if location != header or IsInternalName(decl.name): - continue - # ok, check the type of the declaration and export it accordingly - self.HandleDeclaration(decl) - - - def HandleDeclaration(self, decl): - '''Dispatch the declaration to the appropriate method, that must create - a suitable info object for a Exporter, create a Exporter, set its - declarations and append it to the list of exporters. - ''' - dispatch_table = { - Class : ClassExporter, - Enumeration : EnumExporter, - Function : FunctionExporter, - } - - for decl_type, exporter_type in dispatch_table.items(): - if type(decl) == decl_type: - self.HandleExporter(decl, exporter_type) - break - - - def HandleExporter(self, decl, exporter_type): - info = self.info[decl.name] - info.name = decl.FullName() - info.include = self.info.include - exporter = exporter_type(info) - exporter.SetDeclarations(self.declarations) - exporters.exporters.append(exporter) - - - diff --git a/pyste/src/IncludeExporter.py b/pyste/src/IncludeExporter.py deleted file mode 100644 index 2a7b0602..00000000 --- a/pyste/src/IncludeExporter.py +++ /dev/null @@ -1,19 +0,0 @@ -import os.path -from Exporter import Exporter - -#============================================================================== -# IncludeExporter -#============================================================================== -class IncludeExporter(Exporter): - '''Writes an include declaration to the module. Useful to add extra code - for use in the Wrappers. - This class just reimplements the Parse method to do nothing: the - WriteInclude in Exporter already does the work for us. - ''' - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - - def Parse(self, parser): - pass - diff --git a/pyste/src/declarations.py b/pyste/src/declarations.py deleted file mode 100644 index adba6fd3..00000000 --- a/pyste/src/declarations.py +++ /dev/null @@ -1,452 +0,0 @@ -''' -Module declarations - - Defines classes that represent declarations found in C++ header files. - -''' - -class Declaration(object): - 'Represents a basic declaration.' - - def __init__(self, name, namespace): - # the declaration name - self.name = name - # all the namespaces, separated by '::' = 'boost::inner' - self.namespace = namespace - # tuple (filename, line) - self.location = '', -1 - - - def FullName(self): - 'Returns the full qualified name: "boost::inner::Test"' - namespace = self.namespace or '' - #if not namespace: - # namespace = '' - if namespace and not namespace.endswith('::'): - namespace += '::' - return namespace + self.name - - - def __repr__(self): - return '' % (self.FullName(), id(self)) - - - def __str__(self): - return 'Declaration of %s' % self.FullName() - - - -class Class(Declaration): - 'The declaration of a class or struct.' - - def __init__(self, name, namespace, members, abstract, bases): - Declaration.__init__(self, name, namespace) - # list of members - self.members = members - # whatever the class has any abstract methods - self.abstract = abstract - # instances of Base - self.bases = bases - self._members_count = {} - - - def __iter__(self): - return iter(self.members) - - - def IsAbstract(self): - 'Returns True if any method of this class is abstract' - for member in self.members: - if isinstance(member, Method): - if member.abstract: - return True - return False - - - def RawName(self): - 'Returns the raw name of a template class. name = Foo, raw = Foo' - lesspos = self.name.find('<') - if lesspos != -1: - return self.name[:lesspos] - else: - return self.name - - - def Constructors(self, publics_only=True): - constructors = [] - for member in self: - if isinstance(member, Constructor): - if publics_only and member.visibility != Scope.public: - continue - constructors.append(member) - return constructors - - - def HasCopyConstructor(self): - for cons in self.Constructors(): - if cons.IsCopy(): - return True - return False - - - def HasDefaultConstructor(self): - for cons in self.Constructors(): - if cons.IsDefault(): - return True - return False - - - def IsUnique(self, member_name): - if not self._members_count: - for m in self: - self._members_count[m.name] = self._members_count.get(m.name, 0) + 1 - try: - return self._members_count[member_name] == 1 - except KeyError: - print self._members_count - print 'Key', member_name - - - -class NestedClass(Class): - 'The declaration of a class/struct inside another class/struct.' - - def __init__(self, name, class_, visib, members, abstract, bases): - Class.__init__(self, name, None, members, abstract, bases) - self.class_ = class_ - self.visibility = visib - - - def FullName(self): - return '%s::%s' % (self.class_, self.name) - - - -class Base: - 'Represents a base class of another class.' - - def __init__(self, name, visibility=None): - # class_ is the full name of the base class - self.name = name - # visibility of the derivation - if visibility is None: - visibility = Scope.public - self.visibility = visibility - - - -class Scope: - public = 'public' - private = 'private' - protected = 'protected' - - - -class Function(Declaration): - 'The declaration of a function.' - - def __init__(self, name, namespace, result, params): - Declaration.__init__(self, name, namespace) - # the result type: instance of Type, or None (constructors) - self.result = result - # the parameters: instances of Type - self.parameters = params - - - def PointerDeclaration(self): - 'returns a declaration of a pointer to this function' - result = self.result.FullName() - params = ', '.join([x.FullName() for x in self.parameters]) - return '(%s (*)(%s))%s' % (result, params, self.FullName()) - - - def _MinArgs(self): - min = 0 - for arg in self.parameters: - if arg.default is None: - min += 1 - return min - - minArgs = property(_MinArgs) - - - def _MaxArgs(self): - return len(self.parameters) - - maxArgs = property(_MaxArgs) - - - -class Operator(Function): - 'The declaration of a custom operator.' - def FullName(self): - namespace = self.namespace or '' - if not namespace.endswith('::'): - namespace += '::' - return namespace + 'operator' + self.name - - - -class Method(Function): - 'The declaration of a method.' - - def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const): - Function.__init__(self, name, None, result, params) - self.visibility = visib - self.virtual = virtual - self.abstract = abstract - self.static = static - self.class_ = class_ - self.const = const - - - def FullName(self): - return self.class_ + '::' + self.name - - - def PointerDeclaration(self): - 'returns a declaration of a pointer to this function' - result = self.result.FullName() - params = ', '.join([x.FullName() for x in self.parameters]) - const = '' - if self.const: - const = 'const' - return '(%s (%s::*)(%s) %s)%s' %\ - (result, self.class_, params, const, self.FullName()) - - -class Constructor(Method): - 'A constructor of a class.' - - def __init__(self, name, class_, params, visib): - Method.__init__(self, name, class_, None, params, visib, False, False, False, False) - - - def IsDefault(self): - return len(self.parameters) == 0 - - - def IsCopy(self): - if len(self.parameters) != 1: - return False - param = self.parameters[0] - class_as_param = self.parameters[0].name == self.class_ - param_reference = isinstance(param, ReferenceType) - return param_reference and class_as_param and param.const - - -class Destructor(Method): - 'The destructor of a class.' - - def __init__(self, name, class_, visib, virtual): - Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False) - - def FullName(self): - return self.class_ + '::~' + self.name - - - -class ClassOperator(Method): - 'The declaration of a custom operator in a class.' - - def FullName(self): - return self.class_ + '::operator ' + self.name - - - -class ConverterOperator(ClassOperator): - 'An operator in the form "operator OtherClass()".' - - def FullName(self): - return self.class_ + '::operator ' + self.result.name - - - -class Type(Declaration): - 'Represents a type.' - - def __init__(self, name, const=False, default=None): - Declaration.__init__(self, name, None) - # whatever the type is constant or not - self.const = const - # used when the Type is a function argument - self.default = default - self.volatile = False - - def __repr__(self): - if self.const: - const = 'const ' - else: - const = '' - return '' - - - def FullName(self): - if self.const: - const = 'const ' - else: - const = '' - return const + self.name - - - -class ArrayType(Type): - 'Represents an array.' - - def __init__(self, name, min, max, const=False): - 'min and max can be None.' - Type.__init__(self, name, const) - self.min = min - self.max = max - - - -class ReferenceType(Type): - 'A reference type.' - - def __init__(self, name, const=False, default=None, expandRef=True): - Type.__init__(self, name, const, default) - self.expand = expandRef - - - def FullName(self): - 'expand is False for function pointers' - expand = ' &' - if not self.expand: - expand = '' - return Type.FullName(self) + expand - - - -class PointerType(Type): - 'A pointer type.' - - def __init__(self, name, const=False, default=None, expandPointer=False): - Type.__init__(self, name, const, default) - self.expand = expandPointer - - - def FullName(self): - 'expand is False for function pointer' - expand = ' *' - if not self.expand: - expand = '' - return Type.FullName(self) + expand - - - -class FundamentalType(Type): - 'One of the fundamental types (int, void...).' - - def __init__(self, name, const=False): - Type.__init__(self, name, const) - - - -class FunctionType(Type): - 'A pointer to a function.' - - def __init__(self, result, params): - Type.__init__(self, '', False) - self.result = result - self.parameters = params - self.name = self.FullName() - - - def FullName(self): - full = '%s (*)' % self.result.FullName() - params = [x.FullName() for x in self.parameters] - full += '(%s)' % ', '.join(params) - return full - - - -class MethodType(FunctionType): - 'A pointer to a member function of a class.' - - def __init__(self, result, params, class_): - Type.__init__(self, '', False) - self.result = result - self.parameters = params - self.class_ = class_ - self.name = self.FullName() - - def FullName(self): - full = '%s (%s::*)' % (self.result.FullName(), self.class_) - params = [x.FullName() for x in self.parameters] - full += '(%s)' % ', '.join(params) - return full - - - -class Variable(Declaration): - 'Represents a global variable.' - - def __init__(self, type, name, namespace): - Declaration.__init__(self, name, namespace) - # instance of Type - self.type = type - - - -class ClassVariable(Variable): - 'Represents a class variable.' - - def __init__(self, type, name, class_, visib, static): - Variable.__init__(self, type, name, None) - self.visibility = visib - self.static = static - self.class_ = class_ - - - def FullName(self): - return self.class_ + '::' + self.name - - - -class Enumeration(Declaration): - - def __init__(self, name, namespace): - Declaration.__init__(self, name, namespace) - self.values = {} # dict of str => int - - def ValueFullName(self, name): - assert name in self.values - namespace = self.namespace - if namespace: - namespace += '::' - return namespace + name - - - -class ClassEnumeration(Enumeration): - - def __init__(self, name, class_, visib): - Enumeration.__init__(self, name, None) - self.class_ = class_ - self.visibility = visib - - - def FullName(self): - return '%s::%s' % (self.class_, self.name) - - - def ValueFullName(self, name): - assert name in self.values - return '%s::%s' % (self.class_, name) - - - -class Typedef(Declaration): - - def __init__(self, type, name, namespace): - Declaration.__init__(self, name, namespace) - self.type = type - self.visibility = Scope.public - - - - - - - diff --git a/pyste/src/enumerate.py b/pyste/src/enumerate.py deleted file mode 100644 index 099e42ba..00000000 --- a/pyste/src/enumerate.py +++ /dev/null @@ -1,7 +0,0 @@ -from __future__ import generators - -def enumerate(seq): - i = 0 - for x in seq: - yield i, x - i += 1 diff --git a/pyste/src/exporters.py b/pyste/src/exporters.py deleted file mode 100644 index 65536780..00000000 --- a/pyste/src/exporters.py +++ /dev/null @@ -1,3 +0,0 @@ - -# a list of Exporter instances -exporters = [] diff --git a/pyste/src/exporterutils.py b/pyste/src/exporterutils.py deleted file mode 100644 index 5134a1e5..00000000 --- a/pyste/src/exporterutils.py +++ /dev/null @@ -1,26 +0,0 @@ -''' -Various helpers for interface files. -''' - -from settings import * - -#============================================================================== -# FunctionWrapper -#============================================================================== -class FunctionWrapper(object): - '''Holds information about a wrapper for a function or a method. It is in 2 - parts: the name of the Wrapper, and its code. The code is placed in the - declaration section of the module, while the name is used to def' the - function or method (with the pyste namespace prepend to it). If code is None, - the name is left unchanged. - ''' - - def __init__(self, name, code=None): - self.name = name - self.code = code - - def FullName(self): - if self.code: - return namespaces.pyste + self.name - else: - return self.name diff --git a/pyste/src/infos.py b/pyste/src/infos.py deleted file mode 100644 index ce8334c5..00000000 --- a/pyste/src/infos.py +++ /dev/null @@ -1,187 +0,0 @@ -import os.path -import copy -import exporters -from ClassExporter import ClassExporter -from FunctionExporter import FunctionExporter -from IncludeExporter import IncludeExporter -from EnumExporter import EnumExporter -from HeaderExporter import HeaderExporter -from exporterutils import FunctionWrapper - - -#============================================================================== -# DeclarationInfo -#============================================================================== -class DeclarationInfo: - - def __init__(self, otherInfo=None): - self.__infos = {} - self.__attributes = {} - if otherInfo is not None: - self.__infos = copy.deepcopy(otherInfo.__infos) - self.__attributes = copy.deepcopy(otherInfo.__attributes) - - - def __getitem__(self, name): - 'Used to access sub-infos' - if name.startswith('__'): - raise AttributeError - default = DeclarationInfo() - default._Attribute('name', name) - return self.__infos.setdefault(name, default) - - - def __getattr__(self, name): - return self[name] - - - def _Attribute(self, name, value=None): - if value is None: - # get value - return self.__attributes.get(name) - else: - # set value - self.__attributes[name] = value - - -#============================================================================== -# FunctionInfo -#============================================================================== -class FunctionInfo(DeclarationInfo): - - def __init__(self, name, include, tail=None, otherOption=None): - DeclarationInfo.__init__(self, otherOption) - self._Attribute('name', name) - self._Attribute('include', include) - # create a FunctionExporter - exporter = FunctionExporter(InfoWrapper(self), tail) - exporters.exporters.append(exporter) - - -#============================================================================== -# ClassInfo -#============================================================================== -class ClassInfo(DeclarationInfo): - - def __init__(self, name, include, tail=None, otherInfo=None): - DeclarationInfo.__init__(self, otherInfo) - self._Attribute('name', name) - self._Attribute('include', include) - # create a ClassExporter - exporter = ClassExporter(InfoWrapper(self), tail) - exporters.exporters.append(exporter) - - -#============================================================================== -# IncludeInfo -#============================================================================== -class IncludeInfo(DeclarationInfo): - - def __init__(self, include): - DeclarationInfo.__init__(self) - self._Attribute('include', include) - exporter = IncludeExporter(InfoWrapper(self)) - exporters.exporters.append(exporter) - - -#============================================================================== -# templates -#============================================================================== -def GenerateName(name, type_list): - name = name.replace('::', '_') - names = [name] + type_list - return '_'.join(names) - - -class ClassTemplateInfo(DeclarationInfo): - - def __init__(self, name, include): - DeclarationInfo.__init__(self) - self._Attribute('name', name) - self._Attribute('include', include) - - - def Instantiate(self, type_list, rename=None): - if not rename: - rename = GenerateName(self._Attribute('name'), type_list) - # generate code to instantiate the template - types = ', '.join(type_list) - tail = 'typedef %s< %s > %s;\n' % (self._Attribute('name'), types, rename) - tail += 'void __instantiate_%s()\n' % rename - tail += '{ sizeof(%s); }\n\n' % rename - # create a ClassInfo - class_ = ClassInfo(rename, self._Attribute('include'), tail, self) - return class_ - - - def __call__(self, types, rename=None): - if isinstance(types, str): - types = types.split() - return self.Instantiate(types, rename) - -#============================================================================== -# EnumInfo -#============================================================================== -class EnumInfo(DeclarationInfo): - - def __init__(self, name, include): - DeclarationInfo.__init__(self) - self._Attribute('name', name) - self._Attribute('include', include) - exporter = EnumExporter(InfoWrapper(self)) - exporters.exporters.append(exporter) - - -#============================================================================== -# HeaderInfo -#============================================================================== -class HeaderInfo(DeclarationInfo): - - def __init__(self, include): - DeclarationInfo.__init__(self) - self._Attribute('include', include) - exporter = HeaderExporter(InfoWrapper(self)) - exporters.exporters.append(exporter) - - -#============================================================================== -# InfoWrapper -#============================================================================== -class InfoWrapper: - 'Provides a nicer interface for a info' - - def __init__(self, info): - self.__dict__['_info'] = info # so __setattr__ is not called - - def __getitem__(self, name): - return InfoWrapper(self._info[name]) - - def __getattr__(self, name): - return self._info._Attribute(name) - - def __setattr__(self, name, value): - self._info._Attribute(name, value) - - -#============================================================================== -# Functions -#============================================================================== -def exclude(option): - option._Attribute('exclude', True) - -def set_policy(option, policy): - option._Attribute('policy', policy) - -def rename(option, name): - option._Attribute('rename', name) - -def set_wrapper(option, wrapper): - if isinstance(wrapper, str): - wrapper = FunctionWrapper(wrapper) - option._Attribute('wrapper', wrapper) - -def instantiate(template, types, rename=None): - if isinstance(types, str): - types = types.split() - return template.Instantiate(types, rename) - diff --git a/pyste/src/policies.py b/pyste/src/policies.py deleted file mode 100644 index 977e7f92..00000000 --- a/pyste/src/policies.py +++ /dev/null @@ -1,75 +0,0 @@ - - -class Policy: - 'Represents one of the call policies of boost.python.' - - def __init__(self): - raise RuntimeError, "Can't create an instance of the class Policy" - - - def Code(self): - 'Returns the string corresponding to a instancialization of the policy.' - pass - - - def _next(self): - if self.next is not None: - return ', %s >' % self.next.Code() - else: - return ' >' - - - -class return_internal_reference(Policy): - 'Ties the return value to one of the parameters.' - - def __init__(self, param=1, next=None): - ''' - param is the position of the parameter, or None for "self". - next indicates the next policy, or None. - ''' - self.param = param - self.next=next - - - def Code(self): - c = 'return_internal_reference< %i' % self.param - c += self._next() - return c - - - -class with_custodian_and_ward(Policy): - 'Ties lifetime of two arguments of a function.' - - def __init__(self, custodian, ward, next=None): - self.custodian = custodian - self.ward = ward - self.next = next - - def Code(self): - c = 'with_custodian_and_ward< %i, %i' % (self.custodian, self.ward) - c += self._next() - return c - - - -class return_value_policy(Policy): - 'Policy to convert return values.' - - def __init__(self, which, next=None): - self.which = which - self.next = next - - - def Code(self): - c = 'return_value_policy< %s' % self.which - c += self._next() - return c - - -# values for return_value_policy -reference_existing_object = 'reference_existing_object' -copy_const_reference = 'copy_const_reference' -copy_non_const_reference = 'copy_non_const_reference' -manage_new_object = 'manage_new_object' diff --git a/pyste/src/pyste-profile.py b/pyste/src/pyste-profile.py deleted file mode 100644 index d7afff45..00000000 --- a/pyste/src/pyste-profile.py +++ /dev/null @@ -1,17 +0,0 @@ -import profile -import pstats -import pyste - -import psyco -import elementtree.XMLTreeBuilder as XMLTreeBuilder -import GCCXMLParser - - -if __name__ == '__main__': - #psyco.bind(XMLTreeBuilder.fixtext) - #psyco.bind(XMLTreeBuilder.fixname) - #psyco.bind(XMLTreeBuilder.TreeBuilder) - #psyco.bind(GCCXMLParser.GCCXMLParser) - profile.run('pyste.Main()', 'profile') - p = pstats.Stats('profile') - p.strip_dirs().sort_stats(-1).print_stats() diff --git a/pyste/src/pyste.py b/pyste/src/pyste.py deleted file mode 100644 index 090c7fd9..00000000 --- a/pyste/src/pyste.py +++ /dev/null @@ -1,154 +0,0 @@ -''' -Usage: - pyste [options] --module= interface-files - -where options are: - -I add an include path - -D define symbol - --no-using do not declare "using namespace boost"; - use explicit declarations instead - --pyste-ns= set the namespace where new types will be declared; - default is "pyste" -''' - -import sys -import os -import getopt -import exporters -import CodeUnit -import infos -import exporterutils -import settings -from policies import * -from CppParser import CppParser, CppParserError -from Exporter import Exporter -from FunctionExporter import FunctionExporter -from ClassExporter import ClassExporter -from IncludeExporter import IncludeExporter -from HeaderExporter import HeaderExporter - - -def GetDefaultIncludes(): - if 'INCLUDE' in os.environ: - include = os.environ['INCLUDE'] - return include.split(os.pathsep) - else: - return [] - - -def ParseArguments(): - - def Usage(): - print __doc__ - sys.exit(1) - - options, files = getopt.getopt(sys.argv[1:], 'I:D:', ['module=', 'out=', 'no-using', 'pyste-ns=', 'debug']) - includes = GetDefaultIncludes() - defines = [] - module = None - out = None - for opt, value in options: - if opt == '-I': - includes.append(value) - elif opt == '-D': - defines.append(value) - elif opt == '--module': - module = value - elif opt == '--out': - out = value - elif opt == '--no-using': - settings.namespaces.python = 'boost::python::' - CodeUnit.CodeUnit.USING_BOOST_NS = False - elif opt == '--pyste-ns': - settings.namespaces.pyste = value + '::' - elif opt == '--debug': - settings.DEBUG = True - else: - print 'Unknown option:', opt - Usage() - - if not files or not module: - Usage() - if not out: - out = module + '.cpp' - return includes, defines, module, out, files - - -def CreateContext(): - 'create the context where a interface file can be executed' - context = {} - # infos - context['Function'] = infos.FunctionInfo - context['Class'] = infos.ClassInfo - context['Include'] = infos.IncludeInfo - context['Template'] = infos.ClassTemplateInfo - context['Enum'] = infos.EnumInfo - context['AllFromHeader'] = infos.HeaderInfo - # functions - context['rename'] = infos.rename - context['set_policy'] = infos.set_policy - context['exclude'] = infos.exclude - context['set_wrapper'] = infos.set_wrapper - # policies - context['return_internal_reference'] = return_internal_reference - context['with_custodian_and_ward'] = with_custodian_and_ward - context['return_value_policy'] = return_value_policy - context['reference_existing_object'] = reference_existing_object - context['copy_const_reference'] = copy_const_reference - context['copy_non_const_reference'] = copy_non_const_reference - context['manage_new_object'] = manage_new_object - # utils - context['Wrapper'] = exporterutils.FunctionWrapper - return context - - -def Main(): - includes, defines, module, out, interfaces = ParseArguments() - # execute the interface files - for interface in interfaces: - context = CreateContext() - execfile(interface, context) - # parse all the C++ code - parser = CppParser(includes, defines) - exports = exporters.exporters[:] - for export in exports: - try: - export.Parse(parser) - except CppParserError, e: - print '\n' - print '***', e, ': exitting' - return 2 - print - # sort the exporters by its order - exports = [(x.Order(), x) for x in exporters.exporters] - exports.sort() - exports = [x for _, x in exports] - # now generate the wrapper code - codeunit = CodeUnit.CodeUnit(module) - exported_names = [] - for export in exports: - export.GenerateCode(codeunit, exported_names) - exported_names.append(export.Name()) - codeunit.Save(out) - print 'Module %s generated' % module - return 0 - - -def UsePsyco(): - 'Tries to use psyco if it is installed' - try: - import psyco - import elementtree.XMLTreeBuilder as XMLTreeBuilder - import GCCXMLParser - - psyco.bind(XMLTreeBuilder.fixtext) - psyco.bind(XMLTreeBuilder.fixname) - psyco.bind(XMLTreeBuilder.TreeBuilder) - psyco.bind(GCCXMLParser.GCCXMLParser) - except ImportError: pass - - -if __name__ == '__main__': - UsePsyco() - status = Main() - sys.exit(status) diff --git a/pyste/src/settings.py b/pyste/src/settings.py deleted file mode 100644 index e5adfc25..00000000 --- a/pyste/src/settings.py +++ /dev/null @@ -1,12 +0,0 @@ - -#============================================================================== -# Global information -#============================================================================== - -DEBUG = False - -class namespaces: - boost = 'boost::' - pyste = '' - python = '' # default is to not use boost::python namespace explicitly, so - # use the "using namespace" statement instead diff --git a/pyste/tests/GCCXMLParserUT.py b/pyste/tests/GCCXMLParserUT.py deleted file mode 100644 index c0a17b33..00000000 --- a/pyste/tests/GCCXMLParserUT.py +++ /dev/null @@ -1,338 +0,0 @@ -import sys -sys.path.append('..') -import unittest -import tempfile -import os.path -import GCCXMLParser -from declarations import * - - -class Tester(unittest.TestCase): - - def TestConstructor(self, class_, method, visib): - self.assert_(isinstance(method, Constructor)) - self.assertEqual(method.FullName(), class_.FullName() + '::' + method.name) - self.assertEqual(method.result, None) - self.assertEqual(method.visibility, visib) - self.assert_(not method.virtual) - self.assert_(not method.abstract) - self.assert_(not method.static) - - def TestDefaultConstructor(self, class_, method, visib): - self.TestConstructor(class_, method, visib) - self.assert_(method.IsDefault()) - - def TestCopyConstructor(self, class_, method, visib): - self.TestConstructor(class_, method, visib) - self.assertEqual(len(method.parameters), 1) - param = method.parameters[0] - self.TestType( - param, - ReferenceType, - class_.FullName(), - 'const %s &' % class_.FullName(), - True) - self.assert_(method.IsCopy()) - - - def TestType(self, type_, classtype_, name, fullname, const): - self.assert_(isinstance(type_, classtype_)) - self.assertEqual(type_.name, name) - self.assertEqual(type_.namespace, None) - self.assertEqual(type_.FullName(), fullname) - self.assertEqual(type_.const, const) - - -class ClassBaseTest(Tester): - - def setUp(self): - self.base = GetDecl('Base') - - def testClass(self): - 'test the properties of the class Base' - self.assert_(isinstance(self.base, Class)) - self.assert_(self.base.abstract) - self.assertEqual(self.base.RawName(), 'Base') - - - def testFoo(self): - 'test function foo in class Base' - foo = GetMember(self.base, 'foo') - self.assert_(isinstance(foo, Method)) - self.assertEqual(foo.visibility, Scope.public) - self.assert_(foo.virtual) - self.assert_(foo.abstract) - self.failIf(foo.static) - self.assertEqual(foo.class_, 'test::Base') - self.failIf(foo.const) - self.assertEqual(foo.FullName(), 'test::Base::foo') - self.assertEqual(foo.result.name, 'void') - self.assertEqual(len(foo.parameters), 1) - param = foo.parameters[0] - self.TestType(param, FundamentalType, 'int', 'int', False) - self.assertEqual(foo.namespace, None) - self.assertEqual( - foo.PointerDeclaration(), '(void (test::Base::*)(int) )test::Base::foo') - - def testX(self): - 'test the member x in class Base' - x = GetMember(self.base, 'x') - self.assertEqual(x.class_, 'test::Base') - self.assertEqual(x.FullName(), 'test::Base::x') - self.assertEqual(x.namespace, None) - self.assertEqual(x.visibility, Scope.private) - self.TestType(x.type, FundamentalType, 'int', 'int', False) - self.assertEqual(x.static, False) - - def testConstructors(self): - 'test constructors in class Base' - constructors = GetMembers(self.base, 'Base') - for cons in constructors: - if len(cons.parameters) == 0: - self.TestDefaultConstructor(self.base, cons, Scope.public) - elif len(cons.parameters) == 1: # copy constructor - self.TestCopyConstructor(self.base, cons, Scope.public) - elif len(cons.parameters) == 2: # other constructor - intp, floatp = cons.parameters - self.TestType(intp, FundamentalType, 'int', 'int', False) - self.TestType(floatp, FundamentalType, 'float', 'float', False) - - def testSimple(self): - 'test function simple in class Base' - simple = GetMember(self.base, 'simple') - self.assert_(isinstance(simple, Method)) - self.assertEqual(simple.visibility, Scope.protected) - self.assertEqual(simple.FullName(), 'test::Base::simple') - self.assertEqual(len(simple.parameters), 1) - param = simple.parameters[0] - self.TestType(param, ReferenceType, 'std::string', 'const std::string &', True) - self.TestType(simple.result, FundamentalType, 'bool', 'bool', False) - self.assertEqual( - simple.PointerDeclaration(), - '(bool (test::Base::*)(const std::string &) )test::Base::simple') - - - def testZ(self): - z = GetMember(self.base, 'z') - self.assert_(isinstance(z, Variable)) - self.assertEqual(z.visibility, Scope.public) - self.assertEqual(z.FullName(), 'test::Base::z') - self.assertEqual(z.type.name, 'int') - self.assertEqual(z.type.const, False) - self.assert_(z.static) - - -class ClassTemplateTest(Tester): - - def setUp(self): - self.template = GetDecl('Template') - - def testClass(self): - 'test the properties of the Template class' - self.assert_(isinstance(self.template, Class)) - self.assert_(not self.template.abstract) - self.assertEqual(self.template.FullName(), 'Template') - self.assertEqual(self.template.namespace, '') - self.assertEqual(self.template.name, 'Template') - self.assertEqual(self.template.RawName(), 'Template') - - def testConstructors(self): - 'test the automatic constructors of the class Template' - constructors = GetMembers(self.template, 'Template') - for cons in constructors: - if len(cons.parameters) == 0: - self.TestDefaultConstructor(self.template, cons, Scope.public) - elif len(cons.parameters) == 1: - self.TestCopyConstructor(self.template, cons, Scope.public) - - - def testValue(self): - 'test the class variable value' - value = GetMember(self.template, 'value') - self.assert_(isinstance(value, ClassVariable)) - self.assert_(value.name, 'value') - self.TestType(value.type, FundamentalType, 'int', 'int', False) - self.assert_(not value.static) - self.assertEqual(value.visibility, Scope.public) - self.assertEqual(value.class_, 'Template') - self.assertEqual(value.FullName(), 'Template::value') - - def testBase(self): - 'test the superclasses of Template' - bases = self.template.bases - self.assertEqual(len(bases), 1) - base = bases[0] - self.assert_(isinstance(base, Base)) - self.assertEqual(base.name, 'test::Base') - self.assertEqual(base.visibility, Scope.protected) - - - -class FreeFuncTest(Tester): - - def setUp(self): - self.func = GetDecl('FreeFunc') - - def testFunc(self): - 'test attributes of FreeFunc' - self.assert_(isinstance(self.func, Function)) - self.assertEqual(self.func.name, 'FreeFunc') - self.assertEqual(self.func.FullName(), 'test::FreeFunc') - self.assertEqual(self.func.namespace, 'test') - self.assertEqual( - self.func.PointerDeclaration(), - '(const test::Base & (*)(const std::string &, int))test::FreeFunc') - - - def testResult(self): - 'test the return value of FreeFunc' - res = self.func.result - self.TestType(res, ReferenceType, 'test::Base', 'const test::Base &', True) - - def testParameters(self): - 'test the parameters of FreeFunc' - self.assertEqual(len(self.func.parameters), 2) - strp, intp = self.func.parameters - self.TestType(strp, ReferenceType, 'std::string', 'const std::string &', True) - self.assertEqual(strp.default, None) - self.TestType(intp, FundamentalType, 'int', 'int', False) - self.assertEqual(intp.default, '10') - - - -class testFunctionPointers(Tester): - - def testMethodPointer(self): - 'test declaration of a pointer-to-method' - meth = GetDecl('MethodTester') - param = meth.parameters[0] - fullname = 'void (test::Base::*)(int)' - self.TestType(param, PointerType, fullname, fullname, False) - - def testFunctionPointer(self): - 'test declaration of a pointer-to-function' - func = GetDecl('FunctionTester') - param = func.parameters[0] - fullname = 'void (*)(int)' - self.TestType(param, PointerType, fullname, fullname, False) - - - -# ============================================================================= -# Support routines -# ============================================================================= - -cppcode = ''' -namespace std { - class string; -} -namespace test { -class Base -{ -public: - Base(); - Base(const Base&); - Base(int, float); - - virtual void foo(int = 0.0) = 0; - static int z; -protected: - bool simple(const std::string&); -private: - int x; -}; - -void MethodTester( void (Base::*)(int) ); -void FunctionTester( void (*)(int) ); - - -const Base & FreeFunc(const std::string&, int=10); - -} - -template -struct Template: protected test::Base -{ - T value; - virtual void foo(int); -}; - -Template __aTemplateInt; -''' - -def GetXMLFile(): - '''Generates an gccxml file using the code from the global cppcode. - Returns the xml's filename.''' - # write the code to a header file - tmpfile = tempfile.mktemp() + '.h' - f = file(tmpfile, 'w') - f.write(cppcode) - f.close() - # run gccxml - outfile = tmpfile + '.xml' - if os.system('gccxml "%s" "-fxml=%s"' % (tmpfile, outfile)) != 0: - raise RuntimeError, 'Error executing GCCXML.' - # read the output file into the xmlcode - f = file(outfile) - xmlcode = f.read() - #print xmlcode - f.close() - # remove the header - os.remove(tmpfile) - return outfile - - - -def GetDeclarations(): - 'Uses the GCCXMLParser module to get the declarations.' - xmlfile = GetXMLFile() - declarations = GCCXMLParser.ParseDeclarations(xmlfile) - os.remove(xmlfile) - return declarations - -# the declarations to be analysed -declarations = GetDeclarations() - - -def GetDecl(name): - 'returns one of the top declarations given its name' - for decl in declarations: - if decl.name == name: - return decl - else: - raise RuntimeError, 'Declaration not found: %s' % name - - -def GetMember(class_, name): - 'gets the member of the given class by its name' - - res = None - multipleFound = False - for member in class_: - if member.name == name: - if res is not None: - multipleFound = True - break - res = member - if res is None or multipleFound: - raise RuntimeError, \ - 'No member or more than one member found in class %s: %s' \ - % (class_.name, name) - return res - - -def GetMembers(class_, name): - 'gets the members of the given class by its name' - res = [] - for member in class_: - if member.name == name: - res.append(member) - if len(res) in (0, 1): - raise RuntimeError, \ - 'GetMembers: 0 or 1 members found in class %s: %s' \ - % (class_.name, name) - return res - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/infosUT.py b/pyste/tests/infosUT.py deleted file mode 100644 index 71d5e368..00000000 --- a/pyste/tests/infosUT.py +++ /dev/null @@ -1,50 +0,0 @@ -import sys -sys.path.append('../src') -from infos import * -from policies import * -from exporterutils import * -import unittest - - -class InfosTest(unittest.TestCase): - - def testFunctionInfo(self): - info = FunctionInfo('test::foo', 'foo.h') - rename(info, 'hello') - set_policy(info, return_internal_reference()) - set_wrapper(info, FunctionWrapper('foo_wrapper')) - - info = InfoWrapper(info) - - self.assertEqual(info.rename, 'hello') - self.assertEqual(info.policy.Code(), 'return_internal_reference< 1 >') - self.assertEqual(info.wrapper.name, 'foo_wrapper') - - - def testClassInfo(self): - info = ClassInfo('test::IFoo', 'foo.h') - rename(info.name, 'Name') - rename(info.exclude, 'Exclude') - rename(info, 'Foo') - rename(info.Bar, 'bar') - set_policy(info.Baz, return_internal_reference()) - rename(info.operator['>>'], 'from_string') - exclude(info.Bar) - set_wrapper(info.Baz, FunctionWrapper('baz_wrapper')) - - info = InfoWrapper(info) - - self.assertEqual(info.rename, 'Foo') - self.assertEqual(info['Bar'].rename, 'bar') - self.assertEqual(info['name'].rename, 'Name') - self.assertEqual(info['exclude'].rename, 'Exclude') - self.assertEqual(info['Bar'].exclude, True) - self.assertEqual(info['Baz'].policy.Code(), 'return_internal_reference< 1 >') - self.assertEqual(info['Baz'].wrapper.name, 'baz_wrapper') - self.assertEqual(info['operator']['>>'].rename, 'from_string') - - - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/policiesUT.py b/pyste/tests/policiesUT.py deleted file mode 100644 index bde08543..00000000 --- a/pyste/tests/policiesUT.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys -sys.path.append('..') -import unittest -from policies import * - -class PoliciesTest(unittest.TestCase): - - def testReturnInternal(self): - 'tests the code from a simple internal_reference' - - x = return_internal_reference(1) - self.assertEqual(x.Code(), 'return_internal_reference< 1 >') - x = return_internal_reference(3) - self.assertEqual(x.Code(), 'return_internal_reference< 3 >') - - - def testCustodian(self): - 'tests the code from a simple custodian_and_ward' - - x = with_custodian_and_ward(1,2) - self.assertEqual(x.Code(), 'with_custodian_and_ward< 1, 2 >') - x = with_custodian_and_ward(3,4) - self.assertEqual(x.Code(), 'with_custodian_and_ward< 3, 4 >') - - - def testReturnPolicies(self): - 'tests all the return_value_policies' - - ret = 'return_value_policy< %s >' - x = return_value_policy(reference_existing_object) - self.assertEqual(x.Code(), ret % 'reference_existing_object') - x = return_value_policy(copy_const_reference) - self.assertEqual(x.Code(), ret % 'copy_const_reference') - x = return_value_policy(copy_non_const_reference) - self.assertEqual(x.Code(), ret % 'copy_non_const_reference') - x = return_value_policy(manage_new_object) - self.assertEqual(x.Code(), ret % 'manage_new_object') - - - def testReturnWithCustodiam(self): - 'test the mix of return_internal with custodian' - - x = return_internal_reference(1, with_custodian_and_ward(3,2)) - self.assertEqual( - x.Code(), - 'return_internal_reference< 1, with_custodian_and_ward< 3, 2 > >') - - - def testReturnPoliciesWithInternal(self): - 'test the mix of return_internal with return_policy' - - x = return_internal_reference(1, return_value_policy(manage_new_object)) - self.assertEqual( - x.Code(), - 'return_internal_reference< 1, return_value_policy< manage_new_object > >') - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/runtests.py b/pyste/tests/runtests.py deleted file mode 100644 index f670e3d4..00000000 --- a/pyste/tests/runtests.py +++ /dev/null @@ -1,14 +0,0 @@ -import sys -sys.path.append('../src') -import unittest -import os.path -from glob import glob - -if __name__ == '__main__': - loader = unittest.defaultTestLoader - tests = [] - for name in glob('*UT.py'): - module = __import__(os.path.splitext(name)[0]) - tests.append(loader.loadTestsFromModule(module)) - runner = unittest.TextTestRunner() - runner.run(unittest.TestSuite(tests)) diff --git a/release_notes.txt b/release_notes.txt deleted file mode 100644 index 8932a0aa..00000000 --- a/release_notes.txt +++ /dev/null @@ -1,217 +0,0 @@ -2000-11-22 10:00 - Ullrich fixed bug in operator_dispatcher. - -2000-11-21 10:00 - Changed all class and function names into lower_case. - - Ullrich updated documentation for operator wrapping. - -2000-11-20 10:00 - Ullrich renamed ExtensionClass:register_coerce() into - ExtensionClass:def_standard_coerce() and made it public - - Ullrich improved shared_pod_manager. - -2000-11-17 15:04 - Changed allocation strategy of shared_pod_manager to make it portable. - - Added pickling support + tests thanks to "Ralf W. Grosse-Kunstleve" - - - Added a specialization of Callback to prevent unsafe usage. - - Fixed Ullrich's operator_dispatcher refcount bug - - Removed const char* return values from virtual functions in tests; that - usage was unsafe. - - Ullrich changed Module::add() so that it steals a reference (fix of refcount bug) - - Ullrich added operator_dispatcher::create() optimization - - Ullrich changed design and implementation of TypeObjectBase::enable() (to eliminate low-level - code) and added shared_pod_manager optimization. - - -2000-11-15 12:01 - Fixed refcount bugs in operator calls. - - Added callback_adjust_refcount(PyObject*, Type) to account for different ownership - semantics of Callback's return types and Caller's arguments (which both use from_python()) - This bug caused refcount errors during operator calls. - - Moved operator_dispatcher into extclass.cpp - Gave it shared ownership of the objects it wraps - - Introduced sequence points in extension_class_coerce for exception-safety - - UPPER_CASE_MACRO_NAMES - - MixedCase template type argument names - - Changed internal error reporting to use Python exceptions so we don't force the - user to link in iostreams code - - Changed error return value of call_cmp to -1 - - Moved unwrap_* functions out of operator_dispatcher. This was transitional: when - I realized they didn't need to be declared in extclass.h I moved them out, but - now that operator_dispatcher itself is in extclass.cpp they could go back in. - - Numerous formatting tweaks - - Updated the BoundFunction::create() optimization and enabled it so it could actually be used! - -2000-11-15 00:26 - - Made Ullrich's operators support work with MSVC - - Cleaned up operators.h such that invalid define_operator<0> is no longer needed. - - Ullrich created operators.h to support wrapping of C++ operators (including the "__r*__" forms). - He added several auxiliary classes to extclass.h and extclass.cpp (most importantly, - py::detail::operator_dispatcher and py::operators) - -2000-11-13 22:29 - - removed obsolete ExtensionClassFromPython for good. - - removed unused class ExtensionType forward declaration - -2000-11-12 13:08 - - Added enum_as_int_converters for easier enum wrapping - - Introduced new conversion namespace macros: - PY_BEGIN_CONVERSION_NAMESPACE, - PY_END_CONVERSION_NAMESPACE, - PY_CONVERSION - - callback.h, gen_callback.py: - Added call() function so that a regular python function (as opposed to - method or other function-as-attribute) can be called. - - Added newlines for readability. - - class_wrapper.h: - Fixed a bug in add(), which allows non-method class attributes - - Ullrich has added def_raw for simple varargs and keyword support. - - Fixed version number check for __MWERKS__ - - Added tests for enums and non-method class attributes - - objects.h/objects.cpp: - Added py::String operator*= and operator* for repetition - - Change Dict::items(), keys(), and values() to return a List - - Added template versions of set_item, etc., methods so that users can optionally - use C++ types that have to_python() functions as parameters. - - Changed various Ptr by-value parameters to const Ptr& - - -======= Release ======= -2000-11-06 0:22 - Lots of documentation updates - - added 4-argument template constructor to py::Tuple - - added "add" member function to ClassWrapper<> to allow arbitrary Python - objects to be added to an extension class. - - gen_all.py now generates support for n argument member functions and n+1 - argument member functions at the suggestion of "Ralf W. Grosse-Kunstleve" - - - Added regression tests and re-ordered declare_base calls to verify that the - phantom base class issue is resolved. - -2000-11-04 17:35 - - Integrated Ullrich Koethe's brilliant from_python_experiment for better - error-reporting in many cases. - - extclass.h, gen_extclass.py: - removed special-case MSVC code - added much commentary - removed unused py_copy_to_new_value_holder - - init_function.h, gen_init_function.py: - added missing 'template' keyword on type-dependent template member usage - removed special-case MSVC code - added much commentary - -2000-11-04 0:36 - - Removed the need for the phantom base class that screwed up inheritance - hierarchies, introduced error-prone ordering dependencies, and complexified - logic in many places! - - extclass.h: Added some explanatory comments, removed wasteful m_self member - of HeldInstance - - extclass_demo.cpp: Added #pragmas which allow compilation in ansi strict - mode under Metrowerks - - functions.h: Added virtual_function as part of phantom base class removal; - expanded commentary - - pyptr.h: Added some missing 'typename's and a GCC workaround fix - - subclass.cpp: Added missing string literal const_cast<>s. - -2000-11-03 10:58 - - Fix friend function instantiation bug caught by Metrowerks (thanks - Metrowerks!) - - Add proof-of-concept for one technique of wrapping function that return a - pointer - - Worked around MSVC optimizer bug by writing to_python(double) and - to_python(float) out-of-line - -2000-11-02 23:25 - - Add /Zm200 option to vc6_prj to deal with MSVC resource limitations - - Remove conflicting /Ot option from vc6_prj release build - -======= Release ======= -2000-11-02 17:42 - - Added a fix for interactions between default virtual function - implementations and declare_base(). You still need to write your - declare_base() /after/ all member functions have been def()d for the two - classes concerned. Many, many thanks to Ullrich Koethe - for all his work on this. - - Added missing conversions: - to_python(float) - from_python(const char* const&) - from_python(const double&) - from_python(const float&) - - Added a Regression test for a reference-counting bug thanks to Mark Evans - () - - const-ify ClassBase::getattr() - - Add repr() function to Class - - Add to_python/from_python conversions for PyPtr - - Standardize set_item/get_item interfaces (instead of proxies) for Dict and List - - Add Reprable<> template to newtypes.h - - Fix a bug wherein the __module__ attribute would be lost for classes that have a - default virtual function implementation. - - Remove extra ';' in module.cpp thanks to "Ralf W. Grosse-Kunstleve" - - - Fix a bug in the code of example1.html diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp deleted file mode 100644 index 3eb9f097..00000000 --- a/src/aix_init_module.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifdef _AIX -#include -#include - -extern "C" -{ -#include -#include -} - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -namespace -{ - static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; - extern "C" void initlibboost_python() - { - Py_InitModule("libboost_python", initial_methods); - } - - struct find_and_open_file - { - FILE* fp; - std::string libpath; // -- search path - std::string filename; // -- filename to look for - std::string fullpath; // -- full path to file - - find_and_open_file( - const std::string& libpath_env - , const std::string& file); - }; - - find_and_open_file::find_and_open_file( - const std::string& libpath_env - , const std::string& file) - : fp(0) - { - char* value = std::getenv(libpath_env.c_str()); - - if(value == 0) - return; - - libpath = value; - - if (libpath == "") - return; - - std::string::size_type pos = 0, prev_pos = 0; - - // -- loop through all search paths looking for file - while((pos = libpath.find_first_of(":",pos)) != std::string::npos) - { - fullpath = libpath.substr(prev_pos,pos - prev_pos) + "/" + file; - if (::access(fullpath.c_str(), R_OK) == 0) - { - struct stat filestat; - ::stat(fullpath.c_str(), &filestat); - if (!S_ISDIR(filestat.st_mode)) - { - fp = std::fopen(fullpath.c_str(), "r"); - if (fp) - { - filename = file; - } - return; - } - } - prev_pos = ++pos; - } - - // -- mop up odd path - if (libpath.find_first_of(":", prev_pos) == std::string::npos) - { - fullpath = libpath.substr(prev_pos, libpath.size() - prev_pos) + "/" + file; - if (::access(fullpath.c_str(), R_OK) == 0) - { - struct stat filestat; - ::stat(fullpath.c_str(),&filestat); - if (!S_ISDIR(filestat.st_mode)) - { - fp = std::fopen(fullpath.c_str(), "r"); - filename = file; - } - } - } - } -} - -void aix_init_module( - so_load_function load_dynamic_module - , char const* module_name - , void (*init_module)()) -{ - static bool initialized; - if (!initialized) - { - char const* const name = "libboost_python.so"; - find_and_open_file dynlib("LIBPATH", name); - if (dynlib.fp == 0) - { - fprintf(stderr, " Error: could not find %s\n", name); - return; - } - - std::string::size_type pos = pos = dynlib.filename.rfind(".so"); - if (pos != dynlib.filename.size() - 3) - { - fprintf(stderr, "dynamic library %s must end with .so\n", dynlib.filename.c_str()); - return; - } - - PyObject* m = - load_dynamic_module( - const_cast(dynlib.filename.substr(0,pos).c_str()), - const_cast(dynlib.fullpath.c_str()), - dynlib.fp); - - if (m == 0) - { - fprintf(stderr, "failed to load library %s\n", name); - return; - } - Py_DECREF(m); - - initialized = true; - } - python::detail::init_module(module_name, init_module); -} - -}}} // namespace boost::python -#endif diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp deleted file mode 100644 index 9849071e..00000000 --- a/src/converter/arg_to_python_base.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - arg_to_python_base::arg_to_python_base( - void const volatile* source, registration const& converters) -# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179 - : handle<> -# else - : m_ptr -# endif - (converters.to_python(source)) - { - } -} - -}}} // namespace boost::python::converter diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp deleted file mode 100644 index 72437e8c..00000000 --- a/src/converter/builtin_converters.cpp +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace boost { namespace python { namespace converter { - -shared_ptr_deleter::shared_ptr_deleter(handle<> owner) - : owner(owner) -{} - -shared_ptr_deleter::~shared_ptr_deleter() {} - -void shared_ptr_deleter::operator()(void const*) -{ - owner.reset(); -} - -namespace -{ - // An lvalue conversion function which extracts a char const* from a - // Python String. - void* convert_to_cstring(PyObject* obj) - { - return PyString_Check(obj) ? PyString_AsString(obj) : 0; - } - - // Given a target type and a SlotPolicy describing how to perform a - // given conversion, registers from_python converters which use the - // SlotPolicy to extract the type. - template - struct slot_rvalue_from_python - { - public: - slot_rvalue_from_python() - { - registry::insert( - &slot_rvalue_from_python::convertible - , &slot_rvalue_from_python::construct - , type_id() - ); - } - - private: - static void* convertible(PyObject* obj) - { - unaryfunc* slot = SlotPolicy::get_slot(obj); - return slot && *slot ? slot : 0; - } - - static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) - { - // Get the (intermediate) source object - unaryfunc creator = *static_cast(data->convertible); - handle<> intermediate(creator(obj)); - - // Get the location in which to construct - void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; - new (storage) T(SlotPolicy::extract(intermediate.get())); - - // record successful construction - data->convertible = storage; - } - }; - - // A SlotPolicy for extracting signed integer types from Python objects - struct signed_int_rvalue_from_python_base - { - static unaryfunc* get_slot(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - return (PyInt_Check(obj) || PyLong_Check(obj)) - ? &number_methods->nb_int : 0; - } - }; - - template - struct signed_int_rvalue_from_python : signed_int_rvalue_from_python_base - { - static T extract(PyObject* intermediate) - { - long x = PyInt_AsLong(intermediate); - if (PyErr_Occurred()) - throw_error_already_set(); - return numeric_cast(x); - } - }; - - // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc - // "slot" which just returns its argument. - extern "C" PyObject* identity_unaryfunc(PyObject* x) - { - Py_INCREF(x); - return x; - } - unaryfunc py_object_identity = identity_unaryfunc; - - // A SlotPolicy for extracting unsigned integer types from Python objects - struct unsigned_int_rvalue_from_python_base - { - static unaryfunc* get_slot(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - return (PyInt_Check(obj) || PyLong_Check(obj)) - ? &py_object_identity : 0; - } - }; - - template - struct unsigned_int_rvalue_from_python : unsigned_int_rvalue_from_python_base - { - static T extract(PyObject* intermediate) - { - return numeric_cast( - PyLong_Check(intermediate) - ? PyLong_AsUnsignedLong(intermediate) - : PyInt_AS_LONG(intermediate)); - } - }; - -// Checking Python's macro instead of Boost's - we don't seem to get -// the config right all the time. Furthermore, Python's is defined -// when long long is absent but __int64 is present. - -#ifdef HAVE_LONG_LONG - // A SlotPolicy for extracting long long types from Python objects - - struct long_long_rvalue_from_python_base - { - static unaryfunc* get_slot(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - // Return the identity conversion slot to avoid creating a - // new object. We'll handle that in the extract function - if (PyInt_Check(obj)) - return &number_methods->nb_int; - else if (PyLong_Check(obj)) - return &number_methods->nb_long; - else - return 0; - } - }; - - struct long_long_rvalue_from_python : long_long_rvalue_from_python_base - { - static LONG_LONG extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return PyInt_AS_LONG(intermediate); - } - else - { - LONG_LONG result = PyLong_AsLongLong(intermediate); - - if (PyErr_Occurred()) - throw_error_already_set(); - - return result; - } - } - }; - - struct unsigned_long_long_rvalue_from_python : long_long_rvalue_from_python_base - { - static unsigned LONG_LONG extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return numeric_cast(PyInt_AS_LONG(intermediate)); - } - else - { - unsigned LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate); - - if (PyErr_Occurred()) - throw_error_already_set(); - - return result; - } - } - }; -#endif - - // A SlotPolicy for extracting bool from a Python object - struct bool_rvalue_from_python - { - static unaryfunc* get_slot(PyObject* obj) - { - return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0; - } - - static bool extract(PyObject* intermediate) - { - return PyObject_IsTrue(intermediate); - } - }; - - // A SlotPolicy for extracting floating types from Python objects. - struct float_rvalue_from_python - { - static unaryfunc* get_slot(PyObject* obj) - { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - if (number_methods == 0) - return 0; - - // For integer types, return the tp_int conversion slot to avoid - // creating a new object. We'll handle that below - if (PyInt_Check(obj)) - return &number_methods->nb_int; - - return (PyLong_Check(obj) || PyFloat_Check(obj)) - ? &number_methods->nb_float : 0; - } - - static double extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return PyInt_AS_LONG(intermediate); - } - else - { - return PyFloat_AS_DOUBLE(intermediate); - } - } - }; - - // A SlotPolicy for extracting C++ strings from Python objects. - struct string_rvalue_from_python - { - // If the underlying object is "string-able" this will succeed - static unaryfunc* get_slot(PyObject* obj) - { - return (PyString_Check(obj)) - ? &obj->ob_type->tp_str : 0; - }; - - // Remember that this will be used to construct the result object - static std::string extract(PyObject* intermediate) - { - return std::string(PyString_AsString(intermediate),PyString_Size(intermediate)); - } - }; - - struct complex_rvalue_from_python - { - static unaryfunc* get_slot(PyObject* obj) - { - if (PyComplex_Check(obj)) - return &py_object_identity; - else - return float_rvalue_from_python::get_slot(obj); - } - - static std::complex extract(PyObject* intermediate) - { - if (PyComplex_Check(intermediate)) - { - return std::complex( - PyComplex_RealAsDouble(intermediate) - , PyComplex_ImagAsDouble(intermediate)); - } - else if (PyInt_Check(intermediate)) - { - return PyInt_AS_LONG(intermediate); - } - else - { - return PyFloat_AS_DOUBLE(intermediate); - } - } - }; -} - -BOOST_PYTHON_DECL PyObject* do_return_to_python(char x) -{ - return PyString_FromStringAndSize(&x, 1); -} - -BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x) -{ - return x ? PyString_FromString(x) : boost::python::detail::none(); -} - -BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x) -{ - return x ? x : boost::python::detail::none(); -} - -BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject* x) -{ - if (x == 0) - return boost::python::detail::none(); - - Py_INCREF(x); - return x; -} - -#define REGISTER_INT_CONVERTERS(signedness, U) \ - slot_rvalue_from_python< \ - signedness U \ - ,signedness##_int_rvalue_from_python \ - >() - -#define REGISTER_INT_CONVERTERS2(U) \ - REGISTER_INT_CONVERTERS(signed, U); \ - REGISTER_INT_CONVERTERS(unsigned, U) - -void initialize_builtin_converters() -{ - // booleans - slot_rvalue_from_python(); - - // integer types - REGISTER_INT_CONVERTERS2(char); - REGISTER_INT_CONVERTERS2(short); - REGISTER_INT_CONVERTERS2(int); - REGISTER_INT_CONVERTERS2(long); - -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG - slot_rvalue_from_python(); - slot_rvalue_from_python(); -# endif - - // floating types - slot_rvalue_from_python(); - slot_rvalue_from_python(); - slot_rvalue_from_python(); - - slot_rvalue_from_python,complex_rvalue_from_python>(); - slot_rvalue_from_python,complex_rvalue_from_python>(); - slot_rvalue_from_python,complex_rvalue_from_python>(); - - // Add an lvalue converter for char which gets us char const* - registry::insert(convert_to_cstring,type_id()); - - // Register by-value converters to std::string - slot_rvalue_from_python(); -} - -}}} // namespace boost::python::converter diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp deleted file mode 100644 index e633debf..00000000 --- a/src/converter/from_python.cpp +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#include -#include - -namespace boost { namespace python { namespace converter { - -// rvalue_from_python_stage1 -- do the first stage of a conversion -// from a Python object to a C++ rvalue. -// -// source - the Python object to be converted -// converters - the registry entry for the target type T -// -// Postcondition: where x is the result, one of: -// -// 1. x.convertible == 0, indicating failure -// -// 2. x.construct == 0, x.convertible is the address of an object of -// type T. Indicates a successful lvalue conversion -// -// 3. where y is of type rvalue_from_python_data, -// x.construct(source, y) constructs an object of type T -// in y.storage.bytes and then sets y.convertible == y.storage.bytes, -// or else throws an exception and has no effect. -BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( - PyObject* source - , registration const& converters) -{ - rvalue_from_python_stage1_data data; - - // First check to see if it's embedded in an extension class - // instance, as a special case. - data.convertible = objects::find_instance_impl(source, converters.target_type); - if (data.convertible) - { - data.construct = 0; - } - else - { - for (rvalue_from_python_chain const* chain = converters.rvalue_chain; - chain != 0; - chain = chain->next) - { - void* r = chain->convertible(source); - if (r != 0) - { - data.convertible = r; - data.construct = chain->construct; - break; - } - } - } - return data; -} - -// rvalue_result_from_python -- return the address of a C++ object which -// can be used as the result of calling a Python function. -// -// src - the Python object to be converted -// -// data - a reference to the base part of a -// rvalue_from_python_data object, where T is the -// target type of the conversion. -// -// Requires: data.convertible == ®istered::converters -// -BOOST_PYTHON_DECL void* rvalue_result_from_python( - PyObject* src, rvalue_from_python_stage1_data& data) -{ - // Retrieve the registration - // Cast in two steps for less-capable compilers - void const* converters_ = data.convertible; - registration const& converters = *static_cast(converters_); - - // Look for an eligible converter - data = rvalue_from_python_stage1(src, converters); - return rvalue_from_python_stage2(src, data, converters); -} - -BOOST_PYTHON_DECL void* rvalue_from_python_stage2( - PyObject* source, rvalue_from_python_stage1_data& data, registration const& converters) -{ - if (!data.convertible) - { - handle<> msg( - ::PyString_FromFormat( - "No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s" - , converters.target_type.name() - , source->ob_type->tp_name - )); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - throw_error_already_set(); - } - - // If a construct function was registered (i.e. we found an - // rvalue conversion), call it now. - if (data.construct != 0) - data.construct(source, &data); - - // Return the address of the resulting C++ object - return data.convertible; -} - -BOOST_PYTHON_DECL void* get_lvalue_from_python( - PyObject* source - , registration const& converters) -{ - // Check to see if it's embedded in a class instance - void* x = objects::find_instance_impl(source, converters.target_type); - if (x) - return x; - - lvalue_from_python_chain const* chain = converters.lvalue_chain; - for (;chain != 0; chain = chain->next) - { - void* r = chain->convert(source); - if (r != 0) - return r; - } - return 0; -} - -namespace -{ - // Prevent looping in implicit conversions. This could/should be - // much more efficient, but will work for now. - typedef std::vector visited_t; - static visited_t visited; - - inline bool visit(rvalue_from_python_chain const* chain) - { - visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); - if (p != visited.end() && *p == chain) - return false; - visited.insert(p, chain); - return true; - } - - // RAII class for managing global visited marks. - struct unvisit - { - unvisit(rvalue_from_python_chain const* chain) - : chain(chain) {} - - ~unvisit() - { - visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); - assert(p != visited.end()); - visited.erase(p); - } - private: - rvalue_from_python_chain const* chain; - }; -} - - -BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python( - PyObject* source - , registration const& converters) -{ - if (objects::find_instance_impl(source, converters.target_type)) - return true; - - rvalue_from_python_chain const* chain = converters.rvalue_chain; - - if (!visit(chain)) - return false; - - unvisit protect(chain); - - for (;chain != 0; chain = chain->next) - { - if (chain->convertible(source)) - return true; - } - - return false; -} - -namespace -{ - void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type) - { - handle<> msg( - ::PyString_FromFormat( - "No registered converter was able to extract a C++ %s to type %s" - " from this Python object of type %s" - , ref_type - , converters.target_type.name() - , source->ob_type->tp_name - )); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - - void* lvalue_result_from_python( - PyObject* source - , registration const& converters - , char const* ref_type) - { - handle<> holder(source); - if (source->ob_refcnt <= 2) - { - handle<> msg( - ::PyString_FromFormat( - "Attempt to return dangling %s to object of type: %s" - , ref_type - , converters.target_type.name())); - - PyErr_SetObject(PyExc_ReferenceError, msg.get()); - - throw_error_already_set(); - } - - void* result = get_lvalue_from_python(source, converters); - if (!result) - (throw_no_lvalue_from_python)(source, converters, ref_type); - return result; - } - -} - -BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject* source, registration const& converters) -{ - (throw_no_lvalue_from_python)(source, converters, "pointer"); -} - -BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject* source, registration const& converters) -{ - (throw_no_lvalue_from_python)(source, converters, "reference"); -} - -BOOST_PYTHON_DECL void* reference_result_from_python( - PyObject* source - , registration const& converters) -{ - return (lvalue_result_from_python)(source, converters, "reference"); -} - -BOOST_PYTHON_DECL void* pointer_result_from_python( - PyObject* source - , registration const& converters) -{ - if (source == Py_None) - { - Py_DECREF(source); - return 0; - } - return (lvalue_result_from_python)(source, converters, "pointer"); -} - -BOOST_PYTHON_DECL void void_result_from_python(PyObject* o) -{ - Py_DECREF(expect_non_null(o)); -} - -} // namespace boost::python::converter - -BOOST_PYTHON_DECL PyObject* -pytype_check(PyTypeObject* type_, PyObject* source) -{ - if (!PyObject_IsInstance(source, python::upcast(type_))) - { - ::PyErr_Format( - PyExc_TypeError - , "Expecting an object of type %s; got an object of type %s instead" - , type_->tp_name - , source->ob_type->tp_name - ); - throw_error_already_set(); - } - return source; -} - -}} // namespace boost::python diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp deleted file mode 100644 index b4891941..00000000 --- a/src/converter/registry.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -#include - -#include -#include - -#ifdef BOOST_PYTHON_TRACE_REGISTRY -# include -#endif - -namespace boost { namespace python { namespace converter { - -BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const -{ - if (this->m_class_object == 0) - { - ::PyErr_Format( - PyExc_TypeError - , const_cast("No Python class registered for C++ class %s") - , target_type.name()); - - throw_error_already_set(); - } - - return this->m_class_object; -} - -BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source) const -{ - if (this->m_to_python == 0) - { - handle<> msg( - ::PyString_FromFormat( - "No to_python (by-value) converter found for C++ type: %s" - , this->target_type.name())); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - - return source == 0 - ? incref(Py_None) - : this->m_to_python(const_cast(source)); -} - -namespace // -{ - typedef registration entry; - - typedef std::set registry_t; - - registry_t& entries() - { - static registry_t registry; - -# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION - static bool builtin_converters_initialized = false; - if (!builtin_converters_initialized) - { - // Make this true early because registering the builtin - // converters will cause recursion. - builtin_converters_initialized = true; - - initialize_builtin_converters(); - } -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "registry: "; - for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p) - { - std::cout << p->target_type << "; "; - } - std::cout << '\n'; -# endif -# endif - return registry; - } - - entry* get(type_info type) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - registry_t::iterator p = entries().find(entry(type)); - - std::cout << "looking up " << type - << (p == entries().end() || p->target_type != type - ? "...NOT found\n" : "...found\n"); -# endif - return const_cast( - &*entries().insert(entry(type)).first - ); - } -} // namespace - -namespace registry -{ - void insert(to_python_function_t f, type_info source_t) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "inserting to_python " << source_t << "\n"; -# endif - to_python_function_t& slot = get(source_t)->m_to_python; - - assert(slot == 0); // we have a problem otherwise - if (slot != 0) - { - throw std::runtime_error( - "trying to register to_python_converter for a type which already has a registered to_python_converter"); - } - slot = f; - } - - // Insert an lvalue from_python converter - void insert(convertible_function convert, type_info key) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "inserting lvalue from_python " << key << "\n"; -# endif - entry* found = get(key); - lvalue_from_python_chain *registration = new lvalue_from_python_chain; - registration->convert = convert; - registration->next = found->lvalue_chain; - found->lvalue_chain = registration; - - insert(convert, 0, key); - } - - // Insert an rvalue from_python converter - void insert(void* (*convertible)(PyObject*) - , constructor_function construct - , type_info key) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "inserting rvalue from_python " << key << "\n"; -# endif - entry* found = get(key); - rvalue_from_python_chain *registration = new rvalue_from_python_chain; - registration->convertible = convertible; - registration->construct = construct; - registration->next = found->rvalue_chain; - found->rvalue_chain = registration; - } - - // Insert an rvalue from_python converter - void push_back(void* (*convertible)(PyObject*) - , constructor_function construct - , type_info key) - { -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "push_back rvalue from_python " << key << "\n"; -# endif - rvalue_from_python_chain** found = &get(key)->rvalue_chain; - while (*found != 0) - found = &(*found)->next; - - rvalue_from_python_chain *registration = new rvalue_from_python_chain; - registration->convertible = convertible; - registration->construct = construct; - registration->next = 0; - *found = registration; - } - - registration const& lookup(type_info key) - { - return *get(key); - } - - registration const* query(type_info type) - { - registry_t::iterator p = entries().find(entry(type)); -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "querying " << type - << (p == entries().end() || p->target_type != type - ? "...NOT found\n" : "...found\n"); -# endif - return (p == entries().end() || p->target_type != type) ? 0 : &*p; - } -} // namespace registry - -}}} // namespace boost::python::converter diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp deleted file mode 100644 index 74bcd39b..00000000 --- a/src/converter/type_id.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT -# include -#else -# include -#endif - -namespace boost { namespace python { - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_info const& x) -{ - return os << x.name(); -} - -namespace detail -{ - BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, detail::decorated_type_info const& x) - { - os << x.m_base_type; - if (x.m_decoration & decorated_type_info::const_) - os << " const"; - if (x.m_decoration & decorated_type_info::volatile_) - os << " volatile"; - if (x.m_decoration & decorated_type_info::reference) - os << "&"; - return os; - } -} -}} // namespace boost::python::converter diff --git a/src/dict.cpp b/src/dict.cpp deleted file mode 100644 index f1b8df84..00000000 --- a/src/dict.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include - -namespace boost { namespace python { namespace detail { -namespace -{ - // When returning list objects from methods, it may turn out that the - // derived class is returning something else, perhaps something not - // even derived from list. Since it is generally harmless for a - // Boost.Python wrapper object to hold an object of a different - // type, and because calling list() with an object may in fact - // perform a conversion, the least-bad alternative is to assume that - // we have a Python list object and stuff it into the list result. - list assume_list(object const& o) - { - return list(detail::borrowed_reference(o.ptr())); - } - - // No PyDict_CheckExact; roll our own. - inline bool check_exact(dict_base const* p) - { - return p->ptr()->ob_type == &PyDict_Type; - } -} - -detail::new_reference dict_base::call(object const& arg_) -{ - return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyDict_Type, "(O)", - arg_.ptr()); -} - -dict_base::dict_base() - : object(detail::new_reference(PyDict_New())) -{} - -dict_base::dict_base(object_cref data) - : object(call(data)) -{} - -void dict_base::clear() -{ - if (check_exact(this)) - PyDict_Clear(this->ptr()); - else - this->attr("clear")(); -} - -dict dict_base::copy() -{ - if (check_exact(this)) - { - return dict(detail::new_reference( - PyDict_Copy(this->ptr()))); - } - else - { - return dict(detail::borrowed_reference( - this->attr("copy")().ptr() - )); - } -} - -object dict_base::get(object_cref k) const -{ - if (check_exact(this)) - { - PyObject* result = PyDict_GetItem(this->ptr(),k.ptr()); - return object(detail::borrowed_reference(result ? result : Py_None)); - } - else - { - return this->attr("get")(k); - } -} - -object dict_base::get(object_cref k, object_cref d) const -{ - return this->attr("get")(k,d); -} - -bool dict_base::has_key(object_cref k) const -{ - return extract(this->attr("has_key")(k)); -} - -list dict_base::items() const -{ - if (check_exact(this)) - { - return list(detail::new_reference( - PyDict_Items(this->ptr()))); - } - else - { - return assume_list(this->attr("items")()); - } -} - -object dict_base::iteritems() const -{ - return this->attr("iteritems")(); -} - -object dict_base::iterkeys() const -{ - return this->attr("iterkeys")(); -} - -object dict_base::itervalues() const -{ - return this->attr("itervalues")(); -} - -list dict_base::keys() const -{ - if (check_exact(this)) - { - return list(detail::new_reference( - PyDict_Keys(this->ptr()))); - } - else - { - return assume_list(this->attr("keys")()); - } -} - -tuple dict_base::popitem() -{ - return tuple(detail::borrowed_reference( - this->attr("popitem")().ptr() - )); -} - -object dict_base::setdefault(object_cref k) -{ - return this->attr("setdefault")(k); -} - -object dict_base::setdefault(object_cref k, object_cref d) -{ - return this->attr("setdefault")(k,d); -} - -void dict_base::update(object_cref other) -{ - if (check_exact(this)) - { - if (PyDict_Update(this->ptr(),other.ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("update")(other); - } -} - -list dict_base::values() const -{ - if (check_exact(this)) - { - return list(detail::new_reference( - PyDict_Values(this->ptr()))); - } - else - { - return assume_list(this->attr("values")()); - } -} - -}}} // namespace boost::python diff --git a/src/errors.cpp b/src/errors.cpp deleted file mode 100644 index 8cda9f0e..00000000 --- a/src/errors.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#ifndef BOOST_PYTHON_SOURCE -# define BOOST_PYTHON_SOURCE -#endif - -#include -#include -#include - -namespace boost { namespace python { - -// IMPORTANT: this function may only be called from within a catch block! -BOOST_PYTHON_DECL bool handle_exception_impl(function0 f) -{ - try - { - if (detail::exception_handler::chain) - return detail::exception_handler::chain->handle(f); - f(); - return false; - } - catch(const boost::python::error_already_set&) - { - // The python error reporting has already been handled. - } - catch(const std::bad_alloc&) - { - PyErr_NoMemory(); - } - catch(const bad_numeric_cast& x) - { - PyErr_SetString(PyExc_OverflowError, x.what()); - } - catch(const std::exception& x) - { - PyErr_SetString(PyExc_RuntimeError, x.what()); - } - catch(...) - { - PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); - } - return true; -} - -void BOOST_PYTHON_DECL throw_argument_error() -{ - throw argument_error(); -} - -void BOOST_PYTHON_DECL throw_error_already_set() -{ - throw error_already_set(); -} - -namespace detail { - - BOOST_PYTHON_DECL void expect_complex(PyObject* p) - { - if (!PyComplex_Check(p)) - { - PyErr_SetString(PyExc_TypeError, "expected a complex number"); - boost::python::throw_argument_error(); - } - } - -// needed by void_adaptor (see void_adaptor.hpp) -BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 }; - -bool exception_handler::operator()(function0 const& f) const -{ - if (m_next) - { - return m_next->handle(f); - } - else - { - f(); - return false; - } -} - -exception_handler::exception_handler(handler_function const& impl) - : m_impl(impl) - , m_next(0) -{ - if (chain != 0) - tail->m_next = this; - else - chain = this; - tail = this; -} - -exception_handler* exception_handler::chain; -exception_handler* exception_handler::tail; - -BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f) -{ - // the constructor links the new object into a handler chain, so - // this object isn't actaully leaked (until, of course, the - // interpreter exits). - new exception_handler(f); -} - -} // namespace boost::python::detail - -}} // namespace boost::python - - diff --git a/src/list.cpp b/src/list.cpp deleted file mode 100644 index aab01bc3..00000000 --- a/src/list.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include - -namespace boost { namespace python { namespace detail { - -detail::new_non_null_reference list_base::call(object const& arg_) -{ - return (detail::new_non_null_reference) - (expect_non_null)( - PyObject_CallFunction( - (PyObject*)&PyList_Type, "(O)", - arg_.ptr())); -} - -list_base::list_base() - : object(detail::new_reference(PyList_New(0))) -{} - -list_base::list_base(object_cref sequence) - : object(list_base::call(sequence)) -{} - -void list_base::append(object_cref x) -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Append(this->ptr(), x.ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("append")(x); - } -} - -long list_base::count(object_cref value) const -{ - object result_obj(this->attr("count")(value)); - long result = PyInt_AsLong(result_obj.ptr()); - if (result == -1) - throw_error_already_set(); - return result; -} - -void list_base::extend(object_cref sequence) -{ - this->attr("extend")(sequence); -} - -long list_base::index(object_cref value) const -{ - object result_obj(this->attr("index")(value)); - long result = PyInt_AsLong(result_obj.ptr()); - if (result == -1) - throw_error_already_set(); - return result; -} - -void list_base::insert(int index, object_cref item) -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Insert(this->ptr(), index, item.ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("insert")(index, item); - } -} - -void list_base::insert(object const& index, object_cref x) -{ - long index_ = PyInt_AsLong(index.ptr()); - if (index_ == -1 && PyErr_Occurred()) - throw_error_already_set(); - this->insert(index_, x); -} - -object list_base::pop() -{ - return this->attr("pop")(); -} - -object list_base::pop(long index) -{ - return this->pop(object(index)); -} - -object list_base::pop(object const& index) -{ - return this->attr("pop")(index); -} - -void list_base::remove(object_cref value) -{ - this->attr("remove")(value); -} - -void list_base::reverse() -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Reverse(this->ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("reverse")(); - } -} - -void list_base::sort() -{ - if (PyList_CheckExact(this->ptr())) - { - if (PyList_Sort(this->ptr()) == -1) - throw_error_already_set(); - } - else - { - this->attr("sort")(); - } -} - -void list_base::sort(object_cref cmpfunc) -{ - this->attr("sort")(cmpfunc); -} - -}}} // namespace boost::python diff --git a/src/long.cpp b/src/long.cpp deleted file mode 100644 index bfc09257..00000000 --- a/src/long.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include - -namespace boost { namespace python { namespace detail { - -new_non_null_reference long_base::call(object const& arg_) -{ - return (detail::new_non_null_reference)PyObject_CallFunction( - (PyObject*)&PyLong_Type, "(O)", - arg_.ptr()); -} - -new_non_null_reference long_base::call(object const& arg_, object const& base) -{ - return (detail::new_non_null_reference)PyObject_CallFunction( - (PyObject*)&PyLong_Type, "(OO)", - arg_.ptr(), base.ptr()); -} - -long_base::long_base() - : object( - detail::new_reference( - PyObject_CallFunction((PyObject*)&PyLong_Type, "()")) - ) -{} - -long_base::long_base(object_cref arg) - : object(long_base::call(arg)) -{} - -long_base::long_base(object_cref arg, object_cref base) - : object(long_base::call(arg, base)) -{} - - -}}} // namespace boost::python diff --git a/src/module.cpp b/src/module.cpp deleted file mode 100644 index 42bb7a8c..00000000 --- a/src/module.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#include -#include - -namespace boost { namespace python { namespace detail { - -BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char const* doc) -{ - // Use function::add_to_namespace to achieve overloading if - // appropriate. - scope current; - objects::add_to_namespace(current, name, x, doc); -} - -namespace -{ - PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; -} - -BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)()) -{ - - PyObject* m - = Py_InitModule(const_cast(name), initial_methods); - - if (m != 0) - { - // Create the current module scope - scope current_module( - (object( - ((borrowed_reference_t*)m) - )) - ); - - handle_exception(init_function); - } -} - -}}} // namespace boost::python::detail - -namespace boost { namespace python { - -BOOST_PYTHON_DECL PyObject* scope::current_scope = 0; - -}} diff --git a/src/numeric.cpp b/src/numeric.cpp deleted file mode 100644 index 7d275ff0..00000000 --- a/src/numeric.cpp +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { namespace numeric { - -namespace -{ - enum state_t { failed = -1, unknown, succeeded }; - state_t state = unknown; - std::string module_name; - std::string type_name; - - handle<> array_module; - handle<> array_type; - handle<> array_function; - - void throw_load_failure() - { - PyErr_Format( - PyExc_ImportError - , "No module named '%s' or its type '%s' did not follow the NumPy protocol" - , module_name.c_str(), type_name.c_str()); - throw_error_already_set(); - - } - - bool load(bool throw_on_error) - { - if (!state) - { - if (module_name.size() == 0) - { - module_name = "numarray"; - type_name = "NDArray"; - if (load(false)) - return true; - module_name = "Numeric"; - type_name = "ArrayType"; - } - - state = failed; - PyObject* module = ::PyImport_Import(object(module_name).ptr()); - if (module) - { - PyObject* type = ::PyObject_GetAttrString(module, const_cast(type_name.c_str())); - - if (type && PyType_Check(type)) - { - array_type = handle<>(type); - PyObject* function = ::PyObject_GetAttrString(module, const_cast("array")); - - if (function && PyCallable_Check(function)) - { - array_function = handle<>(function); - state = succeeded; - } - } - } - } - - if (state == succeeded) - return true; - - if (throw_on_error) - throw_load_failure(); - - PyErr_Clear(); - return false; - } - - object demand_array_function() - { - load(true); - return object(array_function); - } -} - -void array::set_module_and_type(char const* package_name, char const* type_attribute_name) -{ - state = unknown; - module_name = package_name ? package_name : "" ; - type_name = type_attribute_name ? type_attribute_name : "" ; -} - - -namespace aux -{ - bool array_object_manager_traits::check(PyObject* obj) - { - if (!load(false)) - return false; - return ::PyObject_IsInstance(obj, array_type.get()); - } - - python::detail::new_non_null_reference - array_object_manager_traits::adopt(PyObject* obj) - { - load(true); - return detail::new_non_null_reference( - pytype_check(downcast(array_type.get()), obj)); - } - - -# define BOOST_PYTHON_AS_OBJECT(z, n, _) object(x##n) -# define BOOST_PP_LOCAL_MACRO(n) \ - array_base::array_base(BOOST_PP_ENUM_PARAMS(n, object const& x)) \ - : object(demand_array_function()(BOOST_PP_ENUM_PARAMS(n, x))) \ - {} -# define BOOST_PP_LOCAL_LIMITS (1, 6) -# include BOOST_PP_LOCAL_ITERATE() -# undef BOOST_PYTHON_AS_OBJECT - - array_base::array_base(BOOST_PP_ENUM_PARAMS(7, object const& x)) - : object(demand_array_function()(BOOST_PP_ENUM_PARAMS(7, x))) - {} - - object array_base::argmax(long axis) - { - return attr("argmax")(axis); - } - - object array_base::argmin(long axis) - { - return attr("argmin")(axis); - } - - object array_base::argsort(long axis) - { - return attr("argsort")(axis); - } - - object array_base::astype(object const& type) - { - return attr("astype")(type); - } - - void array_base::byteswap() - { - attr("byteswap")(); - } - - object array_base::copy() const - { - return attr("copy")(); - } - - object array_base::diagonal(long offset, long axis1, long axis2) const - { - return attr("diagonal")(offset, axis1, axis2); - } - - void array_base::info() const - { - attr("info")(); - } - - bool array_base::is_c_array() const - { - return extract(attr("is_c_array")()); - } - - bool array_base::isbyteswapped() const - { - return extract(attr("isbyteswapped")()); - } - - object array_base::new_(object type) const - { - return attr("new")(type); - } - - void array_base::sort() - { - attr("sort")(); - } - - object array_base::trace(long offset, long axis1, long axis2) const - { - return attr("trace")(offset, axis1, axis2); - } - - object array_base::type() const - { - return attr("type")(); - } - - char array_base::typecode() const - { - return extract(attr("typecode")()); - } - - object array_base::factory(object const& buffer - , object const& type - , object const& shape - , bool copy - , bool savespace - , object typecode) - { - return attr("array")(buffer, type, shape, copy, savespace, typecode); - } - - object array_base::getflat() const - { - return attr("getflat")(); - } - - long array_base::getrank() const - { - return extract(attr("getrank")()); - } - - object array_base::getshape() const - { - return attr("getshape")(); - } - - bool array_base::isaligned() const - { - return extract(attr("isaligned")); - } - - bool array_base::iscontiguous() const - { - return extract(attr("isaligned")); - } - - long array_base::itemsize() const - { - return extract(attr("itemsize")); - } - - long array_base::nelements() const - { - return extract(attr("nelements")); - } - - object array_base::nonzero() const - { - return attr("nonzero")(); - } - - void array_base::put(object const& indices, object const& values) - { - attr("put")(indices, values); - } - - void array_base::ravel() - { - attr("ravel")(); - } - - object array_base::repeat(object const& repeats, long axis) - { - return attr("repeat")(repeats, axis); - } - - void array_base::resize(object const& shape) - { - attr("resize")(shape); - } - - void array_base::setflat(object const& flat) - { - attr("setflat")(flat); - } - - void array_base::setshape(object const& shape) - { - attr("setshape")(shape); - } - - void array_base::swapaxes(long axis1, long axis2) - { - attr("swapaxes")(axis1, axis2); - } - - object array_base::take(object const& sequence, long axis) const - { - return attr("take")(sequence, axis); - } - - void array_base::tofile(object const& file) const - { - attr("tofile")(file); - } - - str array_base::tostring() const - { - return str(attr("tostring")()); - } - - void array_base::transpose(object const& axes) - { - attr("transpose")(axes); - } - - object array_base::view() const - { - return attr("view")(); - } -} - -}}} // namespace boost::python::numeric diff --git a/src/object/class.cpp b/src/object/class.cpp deleted file mode 100644 index ff14c9b7..00000000 --- a/src/object/class.cpp +++ /dev/null @@ -1,514 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -# ifdef BOOST_PYTHON_SELF_IS_CLASS -namespace self_ns -{ - self_t self; -} -# endif - -instance_holder::instance_holder() - : m_next(0) -{ -} - -instance_holder::~instance_holder() -{ -} - -// This is copied from typeobject.c in the Python sources. Even though -// class_metatype_object doesn't set Py_TPFLAGS_HAVE_GC, that bit gets -// filled in by the base class initialization process in -// PyType_Ready(). However, tp_is_gc is *not* copied from the base -// type, making it assume that classes are GC-able even if (like -// class_type_object) they're statically allocated. -static int -type_is_gc(PyTypeObject *python_type) -{ - return python_type->tp_flags & Py_TPFLAGS_HEAPTYPE; -} - -static PyTypeObject class_metatype_object = { - PyObject_HEAD_INIT(0)//&PyType_Type) - 0, - "Boost.Python.class", - PyType_Type.tp_basicsize, - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyType_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, // filled in with type_new /* tp_new */ - 0, // filled in with __PyObject_GC_Del /* tp_free */ - (inquiry)type_is_gc, /* tp_is_gc */ -}; - -// Install the instance data for a C++ object into a Python instance -// object. -void instance_holder::install(PyObject* self) throw() -{ - assert(self->ob_type->ob_type == &class_metatype_object); - m_next = ((objects::instance<>*)self)->objects; - ((objects::instance<>*)self)->objects = this; -} - - -namespace objects -{ -// Get the metatype object for all extension classes. - BOOST_PYTHON_DECL type_handle class_metatype() - { - if (class_metatype_object.tp_dict == 0) - { - class_metatype_object.ob_type = &PyType_Type; - class_metatype_object.tp_base = &PyType_Type; - if (PyType_Ready(&class_metatype_object)) - return type_handle(); - } - return type_handle(borrowed(&class_metatype_object)); - } - extern "C" - { - static void instance_dealloc(PyObject* inst) - { - instance<>* kill_me = (instance<>*)inst; - - for (instance_holder* p = kill_me->objects, *next; p != 0; p = next) - { - next = p->next(); - p->~instance_holder(); - instance_holder::deallocate(inst, dynamic_cast(p)); - } - - // Python 2.2.1 won't add weak references automatically when - // tp_itemsize > 0, so we need to manage that - // ourselves. Accordingly, we also have to clean up the - // weakrefs ourselves. - if (kill_me->weakrefs != NULL) - PyObject_ClearWeakRefs(inst); - - Py_XDECREF(kill_me->dict); - - inst->ob_type->tp_free(inst); - } - - static PyObject * - instance_new(PyTypeObject* type_, PyObject* args, PyObject *kw) - { - // Attempt to find the __instance_size__ attribute. If not present, no problem. - PyObject* d = type_->tp_dict; - PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__"); - - long instance_size = 0; - if (instance_size != 0) - instance_size = PyInt_AsLong(instance_size_obj); - - if (instance_size < 0) - instance_size = 0; - PyErr_Clear(); // Clear any errors that may have occurred. - - instance<>* result = (instance<>*)type_->tp_alloc(type_, instance_size); - if (result) - { - // Guido says we can use ob_size for any purpose we - // like, so we'll store the total size of the object - // there. A negative number indicates that the extra - // instance memory is not yet allocated to any holders. - result->ob_size = -(offsetof(instance<>,storage) + instance_size); - } - return (PyObject*)result; - } - - static PyObject* instance_get_dict(PyObject* op, void*) - { - instance<>* inst = downcast >(op); - if (inst->dict == 0) - inst->dict = PyDict_New(); - return python::xincref(inst->dict); - } - - static int instance_set_dict(PyObject* op, PyObject* dict, void*) - { - instance<>* inst = downcast >(op); - python::xdecref(inst->dict); - inst->dict = python::incref(dict); - return 0; - } - } - - - static PyGetSetDef instance_getsets[] = { - {"__dict__", instance_get_dict, instance_set_dict, NULL}, - {0} - }; - - - static PyMemberDef instance_members[] = { - {"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0}, - {0} - }; - - static PyTypeObject class_type_object = { - PyObject_HEAD_INIT(0) //&class_metatype_object) - 0, - "Boost.Python.instance", - offsetof(instance<>,storage), /* tp_basicsize */ - 1, /* tp_itemsize */ - instance_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(instance<>,weakrefs), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - instance_members, /* tp_members */ - instance_getsets, /* tp_getset */ - 0, //&PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(instance<>,dict), /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - instance_new /* tp_new */ - }; - - BOOST_PYTHON_DECL type_handle class_type() - { - if (class_type_object.tp_dict == 0) - { - class_type_object.ob_type = incref(class_metatype().get()); - class_type_object.tp_base = &PyBaseObject_Type; - if (PyType_Ready(&class_type_object)) - return type_handle(); - } - return type_handle(borrowed(&class_type_object)); - } - - BOOST_PYTHON_DECL void* - find_instance_impl(PyObject* inst, type_info type) - { - if (inst->ob_type->ob_type != &class_metatype_object) - return 0; - - instance<>* self = reinterpret_cast*>(inst); - - for (instance_holder* match = self->objects; match != 0; match = match->next()) - { - void* const found = match->holds(type); - if (found) - return found; - } - return 0; - } - - object module_prefix() - { - return object( - PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) - ? object(scope().attr("__name__")) - : api::getattr(scope(), "__module__", str()) - ); - } - - namespace - { - // Find a registered class object corresponding to id. Return a - // null handle if no such class is registered. - inline type_handle query_class(class_id id) - { - converter::registration const* p = converter::registry::query(id); - return type_handle( - python::borrowed( - python::allow_null(p ? p->m_class_object : 0)) - ); - } - - // Find a registered class corresponding to id. If not found, - // throw an appropriate exception. - type_handle get_class(class_id id) - { - type_handle result(query_class(id)); - - if (result.get() == 0) - { - object report("extension class wrapper for base class "); - report = report + id.name() + " has not been created yet"; - PyErr_SetObject(PyExc_RuntimeError, report.ptr()); - throw_error_already_set(); - } - return result; - } - - // class_base constructor - // - // name - the name of the new Python class - // - // num_types - one more than the number of declared bases - // - // types - array of python::type_info, the first item - // corresponding to the class being created, and the - // rest corresponding to its declared bases. - // - inline object - new_class(char const* name, std::size_t num_types, class_id const* const types, char const* doc) - { - assert(num_types >= 1); - - // Build a tuple of the base Python type objects. If no bases - // were declared, we'll use our class_type() as the single base - // class. - std::size_t const num_bases = std::max(num_types - 1, static_cast(1)); - handle<> bases(PyTuple_New(num_bases)); - - for (std::size_t i = 1; i <= num_bases; ++i) - { - type_handle c = (i >= num_types) ? class_type() : get_class(types[i]); - // PyTuple_SET_ITEM steals this reference - PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); - } - - // Call the class metatype to create a new class - dict d; - - object m = module_prefix(); - if (m) d["__module__"] = m; - - if (doc != 0) - d["__doc__"] = doc; - - object result = object(class_metatype())(name, bases, d); - assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type)); - - if (scope().ptr() != Py_None) - scope().attr(name) = result; - - return result; - } - } - - class_base::class_base( - char const* name, std::size_t num_types, class_id const* const types, char const* doc) - : object(new_class(name, num_types, types, doc)) - { - // Insert the new class object in the registry - converter::registration& converters = const_cast( - converter::registry::lookup(types[0])); - - // Class object is leaked, for now - converters.m_class_object = (PyTypeObject*)incref(this->ptr()); - } - - void class_base::set_instance_size(std::size_t instance_size) - { - this->attr("__instance_size__") = instance_size; - } - - extern "C" - { - // This declaration needed due to broken Python 2.2 headers - extern DL_IMPORT(PyTypeObject) PyProperty_Type; - } - - void class_base::add_property(char const* name, object const& fget) - { - object property( - (python::detail::new_reference) - PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr())); - - this->setattr(name, property); - } - - void class_base::add_property(char const* name, object const& fget, object const& fset) - { - object property( - (python::detail::new_reference) - PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr())); - - this->setattr(name, property); - } - - void class_base::setattr(char const* name, object const& x) - { - if (PyObject_SetAttrString(this->ptr(), const_cast(name), x.ptr()) < 0) - throw_error_already_set(); - } - - namespace - { - extern "C" PyObject* no_init(PyObject*, PyObject*) - { - ::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python"); - return NULL; - } - static ::PyMethodDef no_init_def = { - "__init__", no_init, METH_VARARGS, - "Raises an exception\n" - "This class cannot be instantiated from Python\n" - }; - } - - void class_base::def_no_init() - { - handle<> f(::PyCFunction_New(&no_init_def, 0)); - this->setattr("__init__", object(f)); - } - - void class_base::enable_pickling(bool getstate_manages_dict) - { - setattr("__reduce__", object(make_instance_reduce_function())); - setattr("__safe_for_unpickling__", object(true)); - - if (getstate_manages_dict) - { - setattr("__getstate_manages_dict__", object(true)); - } - } - - namespace - { - PyObject* callable_check(PyObject* callable) - { - if (PyCallable_Check(expect_non_null(callable))) - return callable; - - ::PyErr_Format( - PyExc_TypeError - , "staticmethod expects callable object; got an object of type %s, which is not callable" - , callable->ob_type->tp_name - ); - - throw_error_already_set(); - return 0; - } - } - - void class_base::make_method_static(const char * method_name) - { - PyTypeObject* self = downcast(this->ptr()); - dict d((handle<>(borrowed(self->tp_dict)))); - - object method(d[method_name]); - - this->attr(method_name) = object( - handle<>( - PyStaticMethod_New((callable_check)(method.ptr()) ) - )); - } - - BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) - { - return query_class(id); - } -} // namespace objects - - -void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size) -{ - assert(self_->ob_type->ob_type == &class_metatype_object); - objects::instance<>* self = (objects::instance<>*)self_; - - int total_size_needed = holder_offset + holder_size; - - if (-self->ob_size >= total_size_needed) - { - // holder_offset should at least point into the variable-sized part - assert(holder_offset >= offsetof(objects::instance<>,storage)); - - // Record the fact that the storage is occupied, noting where it starts - self->ob_size = holder_offset; - return (char*)self + holder_offset; - } - else - { - void* const result = PyMem_Malloc(holder_size); - if (result == 0) - throw std::bad_alloc(); - return result; - } -} - -void instance_holder::deallocate(PyObject* self_, void* storage) throw() -{ - assert(self_->ob_type->ob_type == &class_metatype_object); - objects::instance<>* self = (objects::instance<>*)self_; - if (storage != (char*)self + self->ob_size) - { - PyMem_Free(storage); - } -} - -}} // namespace boost::python diff --git a/src/object/enum.cpp b/src/object/enum.cpp deleted file mode 100644 index c297abb7..00000000 --- a/src/object/enum.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { namespace objects { - -struct enum_object -{ - PyIntObject base_object; - PyObject* name; -}; - -static PyMemberDef enum_members[] = { - {"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY}, - {0} -}; - - -extern "C" -{ - static int - enum_print(PyObject *v, BOOST_CSTD_::FILE *fp, int flags) - { - PyObject* s - = (flags & Py_PRINT_RAW) ? v->ob_type->tp_str(v) : v->ob_type->tp_repr(v); - if (s == 0) - return -1; - - char const* text = PyString_AsString(s); - if (text == 0) - return -1; - - BOOST_CSTD_::fprintf(fp, text); - return 0; - } - - /* flags -- not used but required by interface */ - static PyObject* enum_repr(PyObject* self_) - { - enum_object* self = downcast(self_); - if (!self->name) - { - return PyString_FromFormat("%s(%ld)", self_->ob_type->tp_name, PyInt_AS_LONG(self_)); - } - else - { - char* name = PyString_AsString(self->name); - if (name == 0) - return 0; - - return PyString_FromFormat("%s.%s", self_->ob_type->tp_name, name); - } - } - - static PyObject* enum_str(PyObject* self_) - { - enum_object* self = downcast(self_); - if (!self->name) - { - return PyInt_Type.tp_str(self_); - } - else - { - return incref(self->name); - } - } -} - -static PyTypeObject enum_type_object = { - PyObject_HEAD_INIT(0) // &PyType_Type - 0, - "Boost.Python.enum", - sizeof(enum_object), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - enum_print, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - enum_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - enum_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_CHECKTYPES - | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - enum_members, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyInt_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0 /* tp_new */ -}; - -object module_prefix(); - -namespace -{ - object new_enum_type(char const* name) - { - if (enum_type_object.tp_dict == 0) - { - enum_type_object.ob_type = incref(&PyType_Type); - enum_type_object.tp_base = &PyInt_Type; - if (PyType_Ready(&enum_type_object)) - throw_error_already_set(); - } - - type_handle metatype(borrowed(&PyType_Type)); - type_handle base(borrowed(&enum_type_object)); - - // suppress the instance __dict__ in these enum objects. There - // may be a slicker way, but this'll do for now. - dict d; - d["__slots__"] = tuple(); - d["values"] = dict(); - - object module_name = module_prefix(); - if (module_name) - module_name += '.'; - - object result = (object(metatype))( - module_name + name, make_tuple(base), d); - - scope().attr(name) = result; - - return result; - } -} - -enum_base::enum_base( - char const* name - , converter::to_python_function_t to_python - , converter::convertible_function convertible - , converter::constructor_function construct - , type_info id - ) - : object(new_enum_type(name)) -{ - converter::registration& converters - = const_cast( - converter::registry::lookup(id)); - - converters.m_class_object = downcast(this->ptr()); - converter::registry::insert(to_python, id); - converter::registry::insert(convertible, construct, id); -} - -void enum_base::add_value(char const* name_, long value) -{ - // Convert name to Python string - object name(name_); - - // Create a new enum instance by calling the class with a value - object x = (*this)(value); - - // Store the object in the enum class - (*this).attr(name_) = x; - - dict d = extract(this->attr("values"))(); - d[value] = x; - - // Set the name field in the new enum instanec - enum_object* p = downcast(x.ptr()); - Py_XDECREF(p->name); - p->name = incref(name.ptr()); -} - -void enum_base::export_values() -{ - dict d = extract(this->attr("values"))(); - list values = d.values(); - scope current; - - for (unsigned i = 0, max = len(values); i < max; ++i) - { - api::setattr(current, object(values[i].attr("name")), values[i]); - } - } - -PyObject* enum_base::to_python(PyTypeObject* type_, long x) -{ - object type((type_handle(borrowed(type_)))); - - dict d = extract(type.attr("values"))(); - object v = d.get(x, object()); - return incref( - (v == object() ? type(x) : v).ptr()); -} - -}}} // namespace boost::python::object diff --git a/src/object/function.cpp b/src/object/function.cpp deleted file mode 100644 index 761a9866..00000000 --- a/src/object/function.cpp +++ /dev/null @@ -1,527 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace boost { namespace python { namespace objects { - -extern PyTypeObject function_type; - -function::function( - py_function const& implementation - , unsigned min_arity - , unsigned max_arity - , python::detail::keyword const* names_and_defaults - , unsigned num_keywords - ) - : m_fn(implementation) - , m_min_arity(min_arity) - // was using std::max here, but a problem with MinGW-2.95 and - // our directory prevents it. - , m_max_arity(max_arity > min_arity ? max_arity : min_arity) -{ - if (names_and_defaults != 0) - { - unsigned keyword_offset - = m_max_arity > num_keywords ? m_max_arity - num_keywords : 0; - - - unsigned tuple_size = num_keywords ? m_max_arity : 0; - m_arg_names = object(handle<>(PyTuple_New(tuple_size))); - - if (num_keywords != 0) - { - for (unsigned j = 0; j < keyword_offset; ++j) - PyTuple_SET_ITEM(m_arg_names.ptr(), j, incref(Py_None)); - } - - for (unsigned i = 0; i < num_keywords; ++i) - { - PyTuple_SET_ITEM( - m_arg_names.ptr() - , i + keyword_offset - , expect_non_null( - PyString_FromString(const_cast(names_and_defaults[i].name)) - ) - ); - } - } - - PyObject* p = this; - if (function_type.ob_type == 0) - { - function_type.ob_type = &PyType_Type; - ::PyType_Ready(&function_type); - } - PyObject_INIT(p, &function_type); -} - -function::~function() -{ -} - -PyObject* function::call(PyObject* args, PyObject* keywords) const -{ - std::size_t nargs = PyTuple_GET_SIZE(args); - std::size_t nkeywords = keywords ? PyDict_Size(keywords) : 0; - std::size_t total_args = nargs + nkeywords; - - function const* f = this; - - // Try overloads looking for a match - do - { - // Check for a plausible number of arguments - if (total_args >= f->m_min_arity && total_args <= f->m_max_arity) - { - // This will be the args that actually get passed - handle<> args2(allow_null(borrowed(args))); - - if (nkeywords > 0) // Keyword arguments were supplied - { - if (f->m_arg_names.ptr() == Py_None) // this overload doesn't accept keywords - { - args2 = handle<>(); // signal failure - } - else - { - std::size_t max_args - = static_cast(PyTuple_Size(f->m_arg_names.ptr())); - - // "all keywords are none" is a special case - // indicating we will accept any number of keyword - // arguments - if (max_args == 0) - { - // no argument preprocessing - } - else if (max_args < total_args) - { - args2 = handle<>(); - } - else - { - // build a new arg tuple - args2 = handle<>(PyTuple_New(total_args)); - - // Fill in the positional arguments - for (std::size_t i = 0; i < nargs; ++i) - PyTuple_SET_ITEM(args2.get(), i, incref(PyTuple_GET_ITEM(args, i))); - - // Grab remaining arguments by name from the keyword dictionary - for (std::size_t j = nargs; j < total_args; ++j) - { - PyObject* value = PyDict_GetItem( - keywords, PyTuple_GET_ITEM(f->m_arg_names.ptr(), j)); - - if (!value) - { - PyErr_Clear(); - args2 = handle<>(); - break; - } - PyTuple_SET_ITEM(args2.get(), j, incref(value)); - } - } - } - } - - // Call the function. Pass keywords in case it's a - // function accepting any number of keywords - PyObject* result = args2 ? f->m_fn(args2.get(), keywords) : 0; - - // If the result is NULL but no error was set, m_fn failed - // the argument-matching test. - - // This assumes that all other error-reporters are - // well-behaved and never return NULL to python without - // setting an error. - if (result != 0 || PyErr_Occurred()) - return result; - } - f = f->m_overloads.get(); - } - while (f); - // None of the overloads matched; time to generate the error message - argument_error(args, keywords); - return 0; -} - -void function::argument_error(PyObject* args, PyObject* keywords) const -{ - // This function needs to be improved to do better error reporting. - PyErr_BadArgument(); -} - -void function::add_overload(handle const& overload_) -{ - function* parent = this; - - while (parent->m_overloads) - parent = parent->m_overloads.get(); - - parent->m_overloads = overload_; - - // If we have no documentation, get the docs from the overload - if (!m_doc) - m_doc = overload_->m_doc; -} - -namespace -{ - char const* const binary_operator_names[] = - { - "add__", - "and__", - "div__", - "divmod__", - "eq__", - "floordiv__", - "ge__", - "gt__", - "le__", - "lshift__", - "lt__", - "mod__", - "mul__", - "ne__", - "or__", - "pow__", - "radd__", - "rand__", - "rdiv__", - "rdivmod__", - "rfloordiv__", - "rlshift__", - "rmod__", - "rmul__", - "ror__", - "rpow__", - "rrshift__", - "rshift__", - "rsub__", - "rtruediv__", - "rxor__", - "sub__", - "truediv__", - "xor__" - }; - - struct less_cstring - { - bool operator()(char const* x, char const* y) const - { - return BOOST_CSTD_::strcmp(x,y) < 0; - } - }; - - inline bool is_binary_operator(char const* name) - { - return name[0] == '_' - && name[1] == '_' - && std::binary_search( - &binary_operator_names[0] - , binary_operator_names + sizeof(binary_operator_names)/sizeof(*binary_operator_names) - , name + 2 - , less_cstring() - ); - } - - // Something for the end of the chain of binary operators - PyObject* not_implemented_impl(PyObject*, PyObject*) - { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - handle not_implemented_function() - { - static object keeper( - function_object(¬_implemented_impl, 2, 3 - , python::detail::keyword_range()) - ); - return handle(borrowed(downcast(keeper.ptr()))); - } -} - -void function::add_to_namespace( - object const& name_space, char const* name_, object const& attribute) -{ - str const name(name_); - PyObject* const ns = name_space.ptr(); - - if (attribute.ptr()->ob_type == &function_type) - { - function* new_func = downcast(attribute.ptr()); - PyObject* dict = 0; - - if (PyClass_Check(ns)) - dict = ((PyClassObject*)ns)->cl_dict; - else if (PyType_Check(ns)) - dict = ((PyTypeObject*)ns)->tp_dict; - else - dict = PyObject_GetAttrString(ns, "__dict__"); - - if (dict == 0) - throw_error_already_set(); - - // This isn't quite typesafe. We'll shoot first by assuming - // the thing is a function*, then ask questions later. The code works nicer that way. - handle existing( - allow_null(downcast(::PyObject_GetItem(dict, name.ptr()))) - ); - - if (existing) - { - if (existing->ob_type == &function_type) - { - new_func->add_overload(existing); - } - else if (existing->ob_type == &PyStaticMethod_Type) - { - char const* name_space_name = extract(name_space.attr("__name__")); - - ::PyErr_Format( - PyExc_RuntimeError - , "Boost.Python - All overloads must be exported " - "before calling \'class_<...>(\"%s\").staticmethod(\"%s\")\'" - , name_space_name - , name_ - ); - throw_error_already_set(); - } - } - else if (is_binary_operator(name_)) - { - // Binary operators need an additional overload which - // returns NotImplemented, so that Python will try the - // __rxxx__ functions on the other operand. We add this - // when no overloads for the operator already exist. - new_func->add_overload(not_implemented_function()); - } - - // A function is named the first time it is added to a namespace. - if (new_func->name().ptr() == Py_None) - new_func->m_name = name; - } - - // The PyObject_GetAttrString() call above left an active error - PyErr_Clear(); - if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0) - throw_error_already_set(); -} - -void function::add_to_namespace( - object const& name_space, char const* name_, object const& attribute, char const* doc) -{ - add_to_namespace(name_space, name_, attribute); - if (doc != 0) - { - object attr_copy(attribute); - attr_copy.attr("__doc__") = doc; - } -} - -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute) -{ - function::add_to_namespace(name_space, name, attribute); -} - -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc) -{ - function::add_to_namespace(name_space, name, attribute, doc); -} - - -namespace -{ - struct bind_return - { - bind_return(PyObject*& result, function const* f, PyObject* args, PyObject* keywords) - : m_result(result) - , m_f(f) - , m_args(args) - , m_keywords(keywords) - {} - - void operator()() const - { - m_result = m_f->call(m_args, m_keywords); - } - - private: - PyObject*& m_result; - function const* m_f; - PyObject* m_args; - PyObject* m_keywords; - }; -} - -extern "C" -{ - // Stolen from Python's funcobject.c - static PyObject * - function_descr_get(PyObject *func, PyObject *obj, PyObject *type_) - { - if (obj == Py_None) - obj = NULL; - return PyMethod_New(func, obj, type_); - } - - static void - function_dealloc(PyObject* p) - { - delete static_cast(p); - } - - static PyObject * - function_call(PyObject *func, PyObject *args, PyObject *kw) - { - PyObject* result = 0; - handle_exception(bind_return(result, static_cast(func), args, kw)); - return result; - } - - // - // Here we're using the function's tp_getset rather than its - // tp_members to set up __doc__ and __name__, because tp_members - // really depends on having a POD object type (it relies on - // offsets). It might make sense to reformulate function as a POD - // at some point, but this is much more expedient. - // - static PyObject* function_get_doc(PyObject* op, void*) - { - function* f = downcast(op); - return python::incref(f->doc().ptr()); - } - - static int function_set_doc(PyObject* op, PyObject* doc, void*) - { - function* f = downcast(op); - f->doc(doc ? object(python::detail::borrowed_reference(doc)) : object()); - return 0; - } - - static PyObject* function_get_name(PyObject* op, void*) - { - function* f = downcast(op); - if (f->name().ptr() == Py_None) - return PyString_InternFromString(""); - else - return python::incref(f->name().ptr()); - } -} - -static PyGetSetDef function_getsetlist[] = { - {"__name__", (getter)function_get_name, 0 }, - {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, - {NULL} /* Sentinel */ -}; - -PyTypeObject function_type = { - PyObject_HEAD_INIT(0) - 0, - "Boost.Python.function", - sizeof(function), - 0, - (destructor)function_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, //(reprfunc)func_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - function_call, /* tp_call */ - 0, /* tp_str */ - 0, // PyObject_GenericGetAttr, /* tp_getattro */ - 0, // PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */ - 0, /* tp_doc */ - 0, // (traverseproc)func_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, //offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, // func_memberlist, /* tp_members */ - function_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - function_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, //offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, - 0 /* tp_new */ -}; - -object function_object( - py_function const& f, unsigned min_arity, unsigned max_arity - , python::detail::keyword_range const& keywords) -{ - return python::object( - python::detail::new_non_null_reference( - new function( - f, min_arity, max_arity, keywords.first, keywords.second - keywords.first))); -} - -object function_object( - py_function const& f - , unsigned arity - , python::detail::keyword_range const& kw) -{ - return function_object(f, arity, arity, kw); -} - -object function_object(py_function const& f, unsigned arity) -{ - return function_object(f, arity, arity, python::detail::keyword_range()); -} - - -handle<> function_handle_impl(py_function const& f, unsigned min_arity, unsigned max_arity) -{ - return python::handle<>( - allow_null( - new function(f, min_arity, max_arity, 0, 0))); -} - -} - -namespace detail -{ - object BOOST_PYTHON_DECL make_raw_function(objects::py_function f, std::size_t min_args) - { - static keyword k; - - return objects::function_object( - f - , min_args - , std::numeric_limits::max() - , keyword_range(&k,&k)); - } -} - -}} // namespace boost::python::objects diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp deleted file mode 100644 index 13dfaef0..00000000 --- a/src/object/inheritance.cpp +++ /dev/null @@ -1,496 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#if _MSC_FULL_VER >= 13102171 && _MSC_FULL_VER <= 13102179 -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Procedure: -// -// The search is a BFS over the space of (type,address) pairs -// guided by the edges of the casting graph whose nodes -// correspond to classes, and whose edges are traversed by -// applying associated cast functions to an address. We use -// vertex distance to the goal node in the cast_graph to rate the -// paths. The vertex distance to any goal node is calculated on -// demand and outdated by the addition of edges to the graph. - -namespace boost { -namespace -{ - enum edge_cast_t { edge_cast = 8010 }; -} - -// Install properties -BOOST_INSTALL_PROPERTY(edge, cast); - -namespace -{ - typedef void*(*cast_function)(void*); - - // - // Here we put together the low-level data structures of the - // casting graph representation. - // - typedef python::type_info class_id; - - // represents a graph of available casts - -#if 0 - struct cast_graph - : -#else - typedef -#endif - adjacency_list > > -#if 0 - {}; -#else - cast_graph; -#endif - - typedef cast_graph::vertex_descriptor vertex_t; - typedef cast_graph::edge_descriptor edge_t; - - struct smart_graph - { - typedef std::vector::const_iterator node_distance_map; - - typedef std::pair out_edges_t; - - // Return a map of the distances from any node to the given - // target node - node_distance_map distances_to(vertex_t target) const - { - std::size_t n = num_vertices(m_topology); - if (m_distances.size() != n * n) - { - m_distances.clear(); - m_distances.resize(n * n, std::numeric_limits::max()); - m_known_vertices = n; - } - - std::vector::iterator to_target = m_distances.begin() + n * target; - - // this node hasn't been used as a target yet - if (to_target[target] != 0) - { - typedef reverse_graph reverse_cast_graph; - reverse_cast_graph reverse_topology(m_topology); - - to_target[target] = 0; - - breadth_first_search( - reverse_topology, target - , visitor( - make_bfs_visitor( - record_distances( - make_iterator_property_map( - to_target - , get(vertex_index, reverse_topology) -# ifdef BOOST_NO_STD_ITERATOR_TRAITS - , *to_target -# endif - ) - , on_tree_edge() - )))); - } - - return to_target; - } - - cast_graph& topology() { return m_topology; } - cast_graph const& topology() const { return m_topology; } - - std::size_t known_vertices() const { return m_known_vertices; } - - smart_graph() - : m_known_vertices(0) - {} - - private: - cast_graph m_topology; - mutable std::vector m_distances; - mutable std::size_t m_known_vertices; - }; - - smart_graph& full_graph() - { - static smart_graph x; - return x; - } - - smart_graph& up_graph() - { - static smart_graph x; - return x; - } - - // - // Our index of class types - // - using boost::python::objects::dynamic_id_function; - typedef tuples::tuple< - class_id // static type - , vertex_t // corresponding vertex - , dynamic_id_function // dynamic_id if polymorphic, or 0 - > - index_entry_interface; - typedef index_entry_interface::inherited index_entry; - enum { ksrc_static_t, kvertex, kdynamic_id }; - - typedef std::vector type_index_t; - - - type_index_t& type_index() - { - static type_index_t x; - return x; - } - - template - struct select1st - { - typedef typename tuples::element<0, Tuple>::type result_type; - - result_type const& operator()(Tuple const& x) const - { - return tuples::get<0>(x); - } - }; - - // map a type to a position in the index - inline type_index_t::iterator type_position(class_id type) - { - typedef index_entry entry; - - return std::lower_bound( - type_index().begin(), type_index().end() - , boost::make_tuple(type, vertex_t(), dynamic_id_function(0)) - , boost::bind(std::less() - , boost::bind(select1st(), _1) - , boost::bind(select1st(), _2))); - } - - inline index_entry* seek_type(class_id type) - { - type_index_t::iterator p = type_position(type); - if (p == type_index().end() || tuples::get(*p) != type) - return 0; - else - return &*p; - } - - // Get the entry for a type, inserting if neccessary - inline type_index_t::iterator demand_type(class_id type) - { - type_index_t::iterator p = type_position(type); - - if (p != type_index().end() && tuples::get(*p) == type) - return p; - - vertex_t v = add_vertex(full_graph().topology()); - vertex_t v2 = add_vertex(up_graph().topology()); - assert(v == v2); - return type_index().insert(p, boost::make_tuple(type, v, dynamic_id_function(0))); - } - - // Map a two types to a vertex in the graph, inserting if neccessary - typedef std::pair - type_index_iterator_pair; - - inline type_index_iterator_pair - demand_types(class_id t1, class_id t2) - { - // be sure there will be no reallocation - type_index().reserve(type_index().size() + 2); - type_index_t::iterator first = demand_type(t1); - type_index_t::iterator second = demand_type(t2); - if (first == second) - ++first; - return std::make_pair(first, second); - } - - struct q_elt - { - q_elt(std::size_t distance - , void* src_address - , vertex_t target - , cast_function cast - ) - : distance(distance) - , src_address(src_address) - , target(target) - , cast(cast) - {} - - std::size_t distance; - void* src_address; - vertex_t target; - cast_function cast; - - bool operator<(q_elt const& rhs) const - { - return distance < rhs.distance; - } - }; - - // Optimization: - // - // Given p, src_t, dst_t - // - // Get a pointer pd to the most-derived object - // if it's polymorphic, dynamic_cast to void* - // otherwise pd = p - // - // Get the most-derived typeid src_td - // - // ptrdiff_t offset = p - pd - // - // Now we can keep a cache, for [src_t, offset, src_td, dst_t] of - // the cast transformation function to use on p and the next src_t - // in the chain. src_td, dst_t don't change throughout this - // process. In order to represent unreachability, when a pair is - // found to be unreachable, we stick a 0-returning "dead-cast" - // function in the cache. - - // This is needed in a few places below - inline void* identity_cast(void* p) - { - return p; - } - - void* search(smart_graph const& g, void* p, vertex_t src, vertex_t dst) - { - // I think this test was thoroughly bogus -- dwa - // If we know there's no path; bail now. - // if (src > g.known_vertices() || dst > g.known_vertices()) - // return 0; - - smart_graph::node_distance_map d(g.distances_to(dst)); - - if (d[src] == std::numeric_limits::max()) - return 0; - - typedef property_map::const_type cast_map; - cast_map casts = get(edge_cast, g.topology()); - - typedef std::pair search_state; - typedef std::vector visited_t; - visited_t visited; - std::priority_queue q; - - q.push(q_elt(d[src], p, src, identity_cast)); - while (!q.empty()) - { - q_elt top = q.top(); - q.pop(); - - // Check to see if we have a real state - void* dst_address = top.cast(top.src_address); - if (dst_address == 0) - continue; - - if (top.target == dst) - return dst_address; - - search_state s(top.target,dst_address); - - visited_t::iterator pos = std::lower_bound( - visited.begin(), visited.end(), s); - - // If already visited, continue - if (pos != visited.end() && *pos == s) - continue; - - visited.insert(pos, s); // mark it - - // expand it: - smart_graph::out_edges_t edges = out_edges(s.first, g.topology()); - for (cast_graph::out_edge_iterator p = edges.first - , finish = edges.second - ; p != finish - ; ++p - ) - { - edge_t e = *p; - q.push(q_elt( - d[target(e, g.topology())] - , dst_address - , target(e, g.topology()) - , boost::get(casts, e))); - } - } - return 0; - } - - struct cache_element - { - typedef tuples::tuple< - class_id // source static type - , class_id // target type - , std::ptrdiff_t // offset within source object - , class_id // source dynamic type - >::inherited key_type; - - cache_element(key_type const& k) - : key(k) - , offset(0) - {} - - key_type key; - std::ptrdiff_t offset; - - BOOST_STATIC_CONSTANT( - std::ptrdiff_t, not_found = integer_traits::const_min); - - bool operator<(cache_element const& rhs) const - { - return this->key < rhs.key; - } - - bool unreachable() const - { - return offset == not_found; - } - }; - - enum { kdst_t = ksrc_static_t + 1, koffset, ksrc_dynamic_t }; - typedef std::vector cache_t; - - cache_t& cache() - { - static cache_t x; - return x; - } - - inline void* convert_type(void* const p, class_id src_t, class_id dst_t, bool polymorphic) - { - // Quickly rule out unregistered types - index_entry* src_p = seek_type(src_t); - if (src_p == 0) - return 0; - - index_entry* dst_p = seek_type(dst_t); - if (dst_p == 0) - return 0; - - // Look up the dynamic_id function and call it to get the dynamic - // info - boost::python::objects::dynamic_id_t dynamic_id = polymorphic - ? tuples::get(*src_p)(p) - : std::make_pair(p, src_t); - - // Look in the cache first for a quickie address translation - std::ptrdiff_t offset = (char*)p - (char*)dynamic_id.first; - - cache_element seek(boost::make_tuple(src_t, dst_t, offset, dynamic_id.second)); - cache_t& c = cache(); - cache_t::iterator const cache_pos - = std::lower_bound(c.begin(), c.end(), seek); - - - // if found in the cache, we're done - if (cache_pos != c.end() && cache_pos->key == seek.key) - { - return cache_pos->offset == cache_element::not_found - ? 0 : (char*)p + cache_pos->offset; - } - - // If we are starting at the most-derived type, only look in the up graph - smart_graph const& g = polymorphic && dynamic_id.second != src_t - ? full_graph() : up_graph(); - - void* result = search( - g, p, tuples::get(*src_p) - , tuples::get(*dst_p)); - - // update the cache - c.insert(cache_pos, seek)->offset - = (result == 0) ? cache_element::not_found : (char*)result - (char*)p; - - return result; - } -} - -namespace python { namespace objects { - -BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src_t, class_id dst_t) -{ - return convert_type(p, src_t, dst_t, true); -} - -BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src_t, class_id dst_t) -{ - return convert_type(p, src_t, dst_t, false); -} - -BOOST_PYTHON_DECL void add_cast( - class_id src_t, class_id dst_t, cast_function cast, bool is_downcast) -{ - // adding an edge will invalidate any record of unreachability in - // the cache. - static std::size_t expected_cache_len = 0; - cache_t& c = cache(); - if (c.size() > expected_cache_len) - { - c.erase(std::remove_if( - c.begin(), c.end(), - mem_fn(&cache_element::unreachable)) - , c.end()); - - // If any new cache entries get added, we'll have to do this - // again when the next edge is added - expected_cache_len = c.size(); - } - - type_index_iterator_pair types = demand_types(src_t, dst_t); - vertex_t src = tuples::get(*types.first); - vertex_t dst = tuples::get(*types.second); - - cast_graph* const g[2] = { &up_graph().topology(), &full_graph().topology() }; - - for (cast_graph*const* p = g + (is_downcast ? 1 : 0); p < g + 2; ++p) - { - edge_t e; - bool added; - - tie(e, added) = add_edge(src, dst, **p); - assert(added); - - put(get(edge_cast, **p), e, cast); - put(get(edge_index, **p), e, num_edges(full_graph().topology()) - 1); - } -} - -BOOST_PYTHON_DECL void register_dynamic_id_aux( - class_id static_id, dynamic_id_function get_dynamic_id) -{ - tuples::get(*demand_type(static_id)) = get_dynamic_id; -} - -}}} // namespace boost::python::objects diff --git a/src/object/iterator.cpp b/src/object/iterator.cpp deleted file mode 100644 index 1718ee59..00000000 --- a/src/object/iterator.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include - -namespace boost { namespace python { namespace objects { - -static PyObject* identity(PyObject* args_, PyObject*) -{ - PyObject* x = PyTuple_GET_ITEM(args_,0); - Py_INCREF(x); - return x; -} - -BOOST_PYTHON_DECL object const& identity_function() -{ - static object result(function_object(&identity, 1)); - return result; -} - -void set_stop_iteration_error() -{ - PyErr_SetObject(PyExc_StopIteration, Py_None); -} - -}}} // namespace boost::python::objects diff --git a/src/object/life_support.cpp b/src/object/life_support.cpp deleted file mode 100644 index ae414bbe..00000000 --- a/src/object/life_support.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -namespace boost { namespace python { namespace objects { - -struct life_support -{ - PyObject_HEAD - PyObject* patient; -}; - -extern "C" -{ - static void - life_support_dealloc(PyObject* self) - { - Py_XDECREF(((life_support*)self)->patient); - self->ob_type->tp_free(self); - } - - static PyObject * - life_support_call(PyObject *self, PyObject *arg, PyObject *kw) - { - // Let the patient die now - Py_XDECREF(((life_support*)self)->patient); - ((life_support*)self)->patient = 0; - // Let the weak reference die. This probably kills us. - Py_XDECREF(PyTuple_GET_ITEM(arg, 0)); - return detail::none(); - } -} - -PyTypeObject life_support_type = { - PyObject_HEAD_INIT(0)//(&PyType_Type) - 0, - "Boost.Python.life_support", - sizeof(life_support), - 0, - life_support_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, //(reprfunc)func_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - life_support_call, /* tp_call */ - 0, /* tp_str */ - 0, // PyObject_GenericGetAttr, /* tp_getattro */ - 0, // PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */ - 0, /* tp_doc */ - 0, // (traverseproc)func_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, //offsetof(PyLife_SupportObject, func_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, // func_memberlist, /* tp_members */ - 0, //func_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, //offsetof(PyLife_SupportObject, func_dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, - 0 /* tp_new */ -}; - -PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient) -{ - if (nurse == Py_None) - return incref(nurse); - - if (life_support_type.ob_type == 0) - { - life_support_type.ob_type = &PyType_Type; - PyType_Ready(&life_support_type); - } - - life_support* system = PyObject_New(life_support, &life_support_type); - if (!system) - return 0; - - system->patient = 0; - - // We're going to leak this reference, but don't worry; the - // life_support system decrements it when the nurse dies. - PyObject* weakref = PyWeakref_NewRef(nurse, (PyObject*)system); - if (!weakref) - { - Py_XDECREF(system); - return 0; - } - - system->patient = patient; - Py_XINCREF(patient); // hang on to the patient until death - return weakref; -} - -}}} // namespace boost::python::objects diff --git a/src/object/pickle_support.cpp b/src/object/pickle_support.cpp deleted file mode 100644 index 6f37517f..00000000 --- a/src/object/pickle_support.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// (C) Copyright R.W. Grosse-Kunstleve 2002. -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. This -// software is provided "as is" without express or implied warranty, and -// with no claim as to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace { - - tuple instance_reduce(object instance_obj) - { - list result; - object instance_class(instance_obj.attr("__class__")); - result.append(instance_class); - object none; - object getinitargs = getattr(instance_obj, "__getinitargs__", none); - tuple initargs; - if (getinitargs.ptr() != none.ptr()) { - initargs = tuple(getinitargs()); - } - result.append(initargs); - object getstate = getattr(instance_obj, "__getstate__", none); - object instance_dict = getattr(instance_obj, "__dict__", none); - long len_instance_dict = 0; - if (instance_dict.ptr() != none.ptr()) { - len_instance_dict = len(instance_dict); - } - if (getstate.ptr() != none.ptr()) { - if (len_instance_dict > 0) { - object getstate_manages_dict = getattr( - instance_obj, "__getstate_manages_dict__", none); - if (getstate_manages_dict.ptr() == none.ptr()) { - PyErr_SetString(PyExc_RuntimeError, - "Incomplete pickle support" - " (__getstate_manages_dict__ not set)"); - throw_error_already_set(); - } - } - result.append(getstate()); - } - else if (len_instance_dict > 0) { - result.append(instance_dict); - } - return tuple(result); - } - -} // namespace - -object const& make_instance_reduce_function() -{ - static object result(&instance_reduce); - return result; -} - -}} // namespace boost::python diff --git a/src/object_operators.cpp b/src/object_operators.cpp deleted file mode 100644 index 40cdeba3..00000000 --- a/src/object_operators.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include - -namespace boost { namespace python { namespace api { - -#define BOOST_PYTHON_BINARY_OPERATOR(op, name) \ -BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \ -{ \ - return object( \ - detail::new_reference( \ - PyNumber_##name(l.ptr(), r.ptr())) \ - ); \ -} - -BOOST_PYTHON_BINARY_OPERATOR(+, Add) -BOOST_PYTHON_BINARY_OPERATOR(-, Subtract) -BOOST_PYTHON_BINARY_OPERATOR(*, Multiply) -BOOST_PYTHON_BINARY_OPERATOR(/, Divide) -BOOST_PYTHON_BINARY_OPERATOR(%, Remainder) -BOOST_PYTHON_BINARY_OPERATOR(<<, Lshift) -BOOST_PYTHON_BINARY_OPERATOR(>>, Rshift) -BOOST_PYTHON_BINARY_OPERATOR(&, And) -BOOST_PYTHON_BINARY_OPERATOR(^, Xor) -BOOST_PYTHON_BINARY_OPERATOR(|, Or) -#undef BOOST_PYTHON_BINARY_OPERATOR - -#define BOOST_PYTHON_INPLACE_OPERATOR(op, name) \ -BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \ -{ \ - return l = object( \ - (detail::new_reference) \ - PyNumber_InPlace##name(l.ptr(), r.ptr())); \ -} - -BOOST_PYTHON_INPLACE_OPERATOR(+, Add) -BOOST_PYTHON_INPLACE_OPERATOR(-, Subtract) -BOOST_PYTHON_INPLACE_OPERATOR(*, Multiply) -BOOST_PYTHON_INPLACE_OPERATOR(/, Divide) -BOOST_PYTHON_INPLACE_OPERATOR(%, Remainder) -BOOST_PYTHON_INPLACE_OPERATOR(<<, Lshift) -BOOST_PYTHON_INPLACE_OPERATOR(>>, Rshift) -BOOST_PYTHON_INPLACE_OPERATOR(&, And) -BOOST_PYTHON_INPLACE_OPERATOR(^, Xor) -BOOST_PYTHON_INPLACE_OPERATOR(|, Or) -#undef BOOST_PYTHON_INPLACE_OPERATOR - -object::object(handle<> const& x) - : object_base(python::incref(python::expect_non_null(x.get()))) -{} - -}}} // namespace boost::python diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp deleted file mode 100755 index 11979f8f..00000000 --- a/src/object_protocol.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include - -namespace boost { namespace python { namespace api { - -BOOST_PYTHON_DECL object getattr(object const& target, object const& key) -{ - return object(detail::new_reference(PyObject_GetAttr(target.ptr(), key.ptr()))); -} - -BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_) -{ - PyObject* result = PyObject_GetAttr(target.ptr(), key.ptr()); - if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) - { - PyErr_Clear(); - return default_; - } - return object(detail::new_reference(result)); -} - -BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value) -{ - if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) - throw_error_already_set(); -} - -BOOST_PYTHON_DECL void delattr(object const& target, object const& key) -{ - if (PyObject_DelAttr(target.ptr(), key.ptr()) == -1) - throw_error_already_set(); -} - -BOOST_PYTHON_DECL object getattr(object const& target, char const* key) -{ - return object( - detail::new_reference( - PyObject_GetAttrString(target.ptr(), const_cast(key)) - )); -} - -BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_) -{ - PyObject* result = PyObject_GetAttrString(target.ptr(), const_cast(key)); - if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) - { - PyErr_Clear(); - return default_; - } - return object(detail::new_reference(result)); - -} -BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value) -{ - if (PyObject_SetAttrString( - target.ptr(), const_cast(key), value.ptr()) == -1 - ) - { - throw_error_already_set(); - } -} - -BOOST_PYTHON_DECL void delattr(object const& target, char const* key) -{ - if (PyObject_DelAttrString( - target.ptr(), const_cast(key)) == -1 - ) - { - throw_error_already_set(); - } -} - -BOOST_PYTHON_DECL object getitem(object const& target, object const& key) -{ - return object(detail::new_reference( - PyObject_GetItem(target.ptr(), key.ptr()))); -} - -BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value) -{ - if (PyObject_SetItem(target.ptr(), key.ptr(), value.ptr()) == -1) - throw_error_already_set(); -} - -BOOST_PYTHON_DECL void delitem(object const& target, object const& key) -{ - if (PyObject_DelItem(target.ptr(), key.ptr()) == -1) - throw_error_already_set(); -} - -namespace // slicing code copied directly out of the Python implementation -{ - #undef ISINT - #define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x)) - - static PyObject * - apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */ - { - PyTypeObject *tp = u->ob_type; - PySequenceMethods *sq = tp->tp_as_sequence; - - if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) { - int ilow = 0, ihigh = INT_MAX; - if (!_PyEval_SliceIndex(v, &ilow)) - return NULL; - if (!_PyEval_SliceIndex(w, &ihigh)) - return NULL; - return PySequence_GetSlice(u, ilow, ihigh); - } - else { - PyObject *slice = PySlice_New(v, w, NULL); - if (slice != NULL) { - PyObject *res = PyObject_GetItem(u, slice); - Py_DECREF(slice); - return res; - } - else - return NULL; - } - } - - static int - assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x) - /* u[v:w] = x */ - { - PyTypeObject *tp = u->ob_type; - PySequenceMethods *sq = tp->tp_as_sequence; - - if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) { - int ilow = 0, ihigh = INT_MAX; - if (!_PyEval_SliceIndex(v, &ilow)) - return -1; - if (!_PyEval_SliceIndex(w, &ihigh)) - return -1; - if (x == NULL) - return PySequence_DelSlice(u, ilow, ihigh); - else - return PySequence_SetSlice(u, ilow, ihigh, x); - } - else { - PyObject *slice = PySlice_New(v, w, NULL); - if (slice != NULL) { - int res; - if (x != NULL) - res = PyObject_SetItem(u, slice, x); - else - res = PyObject_DelItem(u, slice); - Py_DECREF(slice); - return res; - } - else - return -1; - } - } -} - -BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end) -{ - return object( - detail::new_reference( - apply_slice(target.ptr(), begin.get(), end.get()))); -} - -BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value) -{ - if (assign_slice( - target.ptr(), begin.get(), end.get(), value.ptr()) == -1 - ) - { - throw_error_already_set(); - } -} - -BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end) -{ - if (assign_slice( - target.ptr(), begin.get(), end.get(), 0) == -1 - ) - { - throw_error_already_set(); - } -} - -}}} // namespace boost::python::api diff --git a/src/str.cpp b/src/str.cpp deleted file mode 100644 index a8a2383f..00000000 --- a/src/str.cpp +++ /dev/null @@ -1,324 +0,0 @@ -#include -#include - -namespace boost { namespace python { namespace detail { - -detail::new_reference str_base::call(object const& arg_) -{ - return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyString_Type, "(O)", - arg_.ptr()); -} - -str_base::str_base() - : object(detail::new_reference(PyString_FromString(""))) -{} - -str_base::str_base(const char* s) - : object(detail::new_reference(PyString_FromString(s))) -{} - -str_base::str_base(object_cref other) - : object(str_base::call(other)) -{} - -namespace -{ - new_reference new_attr_reference(object const* obj, char const* name) - { - return new_reference(incref(object(obj->attr(name)).ptr())); - } -} - -#define BOOST_PYTHON_FORMAT_OBJECT(z, n, data) "O" -#define BOOST_PYTHON_OBJECT_PTR(z, n, data) , x##n .ptr() - -#define BOOST_PYTHON_DEFINE_STR_METHOD(name, arity) \ -str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const \ -{ \ - return str(new_reference( \ - expect_non_null( \ - PyObject_CallMethod( \ - this->ptr(), #name, \ - "(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \ - BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \ -} - -BOOST_PYTHON_DEFINE_STR_METHOD(capitalize, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(center, 1) - -long str_base::count(object_cref sub) const -{ - return extract(this->attr("count")(sub)); -} - -long str_base::count(object_cref sub, object_cref start) const -{ - return extract(this->attr("count")(sub,start)); -} - -long str_base::count(object_cref sub, object_cref start, object_cref end) const -{ - return extract(this->attr("count")(sub,start,end)); -} - -object str_base::decode() const -{ - return this->attr("decode")(); -} - -object str_base::decode(object_cref encoding) const -{ - return this->attr("decode")(encoding); -} - -object str_base::decode(object_cref encoding, object_cref errors) const -{ - return this->attr("decode")(encoding,errors); -} - -object str_base::encode() const -{ - return this->attr("encode")(); -} - -object str_base::encode(object_cref encoding) const -{ - return this->attr("encode")(encoding); -} - -object str_base::encode(object_cref encoding, object_cref errors) const -{ - return this->attr("encode")(encoding,errors); -} - -bool str_base::endswith(object_cref suffix) const -{ - bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 1) - -long str_base::find(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("find")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::find(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("find")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::find(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::index(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("index")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::index(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("index")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::index(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isalnum() const -{ - bool result = PyInt_AsLong(this->attr("isalnum")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isalpha() const -{ - bool result = PyInt_AsLong(this->attr("isalpha")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isdigit() const -{ - bool result = PyInt_AsLong(this->attr("isdigit")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::islower() const -{ - bool result = PyInt_AsLong(this->attr("islower")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isspace() const -{ - bool result = PyInt_AsLong(this->attr("isspace")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::istitle() const -{ - bool result = PyInt_AsLong(this->attr("istitle")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::isupper() const -{ - bool result = PyInt_AsLong(this->attr("isupper")().ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(join, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(ljust, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(lower, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(lstrip, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(replace, 2) -BOOST_PYTHON_DEFINE_STR_METHOD(replace, 3) - -long str_base::rfind(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("rfind")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rfind(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rfind(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rindex(object_cref sub) const -{ - long result = PyInt_AsLong(this->attr("rindex")(sub).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rindex(object_cref sub, object_cref start) const -{ - long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -long str_base::rindex(object_cref sub, object_cref start, object_cref end) const -{ - long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(rjust, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(rstrip, 0) - -list str_base::split() const -{ - return list(this->attr("split")()); -} - -list str_base::split(object_cref sep) const -{ - return list(this->attr("split")(sep)); -} - -list str_base::split(object_cref sep, object_cref maxsplit) const -{ - return list(this->attr("split")(sep,maxsplit)); -} - -list str_base::splitlines() const -{ - return list(this->attr("splitlines")()); -} - -list str_base::splitlines(object_cref keepends) const -{ - return list(this->attr("splitlines")(keepends)); -} - -bool str_base::startswith(object_cref prefix) const -{ - bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::startswith(object_cref prefix, object_cref start) const -{ - bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -bool str_base::startswith(object_cref prefix, object_cref start, object_cref end) const -{ - bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr()); - if (PyErr_Occurred()) - throw_error_already_set(); - return result; -} - -BOOST_PYTHON_DEFINE_STR_METHOD(strip, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(swapcase, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(title, 0) -BOOST_PYTHON_DEFINE_STR_METHOD(translate, 1) -BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2) -BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0) - -}}} // namespace boost::python diff --git a/src/tuple.cpp b/src/tuple.cpp deleted file mode 100644 index 2762ab27..00000000 --- a/src/tuple.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include - -namespace boost { namespace python { namespace detail { - -detail::new_reference tuple_base::call(object const& arg_) -{ - return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyTuple_Type, "(O)", - arg_.ptr()); -} - -tuple_base::tuple_base() - : object(detail::new_reference(PyTuple_New(0))) -{} - -tuple_base::tuple_base(object_cref sequence) - : object(call(sequence)) -{} - -}}} // namespace boost::python diff --git a/test/args.cpp b/test/args.cpp deleted file mode 100644 index a65933cb..00000000 --- a/test/args.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include -#include "test_class.hpp" - -using namespace boost::python; - -tuple f(int x = 1, double y = 4.25, char const* z = "wow") -{ - return make_tuple(x, y, z); -} - -BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3) - -typedef test_class<> Y; - -struct X -{ - X(int a0 = 0, int a1 = 1) : inner0(a0), inner1(a1) {} - tuple f(int x = 1, double y = 4.25, char const* z = "wow") - { - return make_tuple(x, y, z); - } - - Y const& inner(bool n) const { return n ? inner1 : inner0; } - - Y inner0; - Y inner1; -}; - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3) - - -tuple raw_func(tuple args, dict kw) -{ - return make_tuple(args, kw); -} - -BOOST_PYTHON_MODULE(args_ext) -{ - def("f", f, args("x", "y", "z") - , "This is f's docstring" - ); - - def("raw", raw_function(raw_func)); - -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 - // MSVC6 gives a fatal error LNK1179: invalid or corrupt file: - // duplicate comdat error if we try to re-use the exact type of f - // here, so substitute long for int. - tuple (*f)(long,double,char const*) = 0; -#endif - def("f1", f, f_overloads("f1's docstring", args("x", "y", "z"))); - def("f2", f, f_overloads(args("x", "y", "z"))); - def("f3", f, f_overloads(args("x", "y", "z"), "f3's docstring")); - - class_("Y", init(args("value"), "Y's docstring")) - .def("value", &Y::value) - .def("raw", raw_function(raw_func)) - ; - - class_("X", "This is X's docstring") - .def(init >(args("a0", "a1"))) - .def("f", &X::f - , "This is X.f's docstring" - , args("x", "y", "z")) - - // Just to prove that all the different argument combinations work - .def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring") - .def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n")) - - .def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring") - .def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n")) - - .def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>()) - .def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>()) - - .def("f1", &X::f, X_f_overloads(args("x", "y", "z"))) - ; - - def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>()); -} diff --git a/test/args.py b/test/args.py deleted file mode 100644 index 2c9218b1..00000000 --- a/test/args.py +++ /dev/null @@ -1,169 +0,0 @@ -""" ->>> from args_ext import * - ->>> raw(3, 4, foo = 'bar', baz = 42) -((3, 4), {'foo': 'bar', 'baz': 42}) - ->>> f(x= 1, y = 3, z = 'hello') -(1, 3.0, 'hello') - ->>> f(z = 'hello', x = 3, y = 2.5) -(3, 2.5, 'hello') - ->>> f(1, z = 'hi', y = 3) -(1, 3.0, 'hi') - ->>> try: f(1, 2, 'hello', bar = 'baz') -... except TypeError: pass -... else: print 'expected an exception: unknown keyword' - - - Exercise the functions using default stubs - ->>> f1(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> f1(y = .125, x = 2) -(2, 0.125, 'wow') ->>> f1(x = 2) -(2, 4.25, 'wow') ->>> f1() -(1, 4.25, 'wow') - ->>> f2(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> f2(y = .125, x = 2) -(2, 0.125, 'wow') ->>> f2(x = 2) -(2, 4.25, 'wow') ->>> f2() -(1, 4.25, 'wow') - ->>> f3(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> f3(y = .125, x = 2) -(2, 0.125, 'wow') ->>> f3(x = 2) -(2, 4.25, 'wow') ->>> f3() -(1, 4.25, 'wow') - - Member function tests - ->>> q = X() ->>> q.f(x= 1, y = 3, z = 'hello') -(1, 3.0, 'hello') - ->>> q.f(z = 'hello', x = 3, y = 2.5) -(3, 2.5, 'hello') - ->>> q.f(1, z = 'hi', y = 3) -(1, 3.0, 'hi') - ->>> try: q.f(1, 2, 'hello', bar = 'baz') -... except TypeError: pass -... else: print 'expected an exception: unknown keyword' - - Exercise member functions using default stubs - ->>> q.f1(z = 'nix', y = .125, x = 2) -(2, 0.125, 'nix') ->>> q.f1(y = .125, x = 2) -(2, 0.125, 'wow') ->>> q.f1(x = 2) -(2, 4.25, 'wow') ->>> q.f1() -(1, 4.25, 'wow') - ->>> X.f.__doc__ -"This is X.f's docstring" - ->>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5) ->>> for f in xfuncs: -... print f(q,1).value(), -... print f(q, n = 1).value(), -... print f(q, n = 0).value(), -... print f.__doc__ -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring -1 1 0 docstring - ->>> x = X(a1 = 44, a0 = 22) ->>> x.inner0(0).value() -22 ->>> x.inner0(1).value() -44 - ->>> x = X(a0 = 7) ->>> x.inner0(0).value() -7 ->>> x.inner0(1).value() -1 - ->>> inner(n = 1, self = q).value() -1 - ->>> y = Y(value = 33) ->>> y.raw(this = 1, that = 'the other')[1] -{'this': 1, 'that': 'the other'} - -""" -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/as_to_python_function.cpp b/test/as_to_python_function.cpp deleted file mode 100644 index 814749d1..00000000 --- a/test/as_to_python_function.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include - -struct hopefully_illegal -{ - static PyObject* convert(int&); -}; - -PyObject* x = boost::python::converter::as_to_python_function::convert(0); diff --git a/test/auto_ptr.cpp b/test/auto_ptr.cpp deleted file mode 100644 index 22e2df73..00000000 --- a/test/auto_ptr.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include - -#include - -#include "test_class.hpp" -#include - -using namespace boost::python; - -typedef test_class<> X; - -struct Y : X -{ - Y(int n) : X(n) {}; -}; - -int look(std::auto_ptr const& x) -{ - return (x.get()) ? x->value() : -1; -} - -int steal(std::auto_ptr x) -{ - return x->value(); -} - -int maybe_steal(std::auto_ptr& x, bool doit) -{ - int n = x->value(); - if (doit) - x.release(); - return n; -} - -std::auto_ptr make() -{ - return std::auto_ptr(new X(77)); -} - -std::auto_ptr callback(object f) -{ - std::auto_ptr x(new X(77)); - return call >(f.ptr(), x); -} - -std::auto_ptr extract_(object o) -{ - return extract&>(o) -#if BOOST_MSVC <= 1300 - () -#endif - ; -} - -BOOST_PYTHON_MODULE(auto_ptr_ext) -{ - class_, boost::noncopyable>("X", init()) - .def("value", &X::value) - ; - - class_, bases, boost::noncopyable>("Y", init()) - ; - - // VC6 auto_ptrs do not have converting constructors -#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 306) - scope().attr("broken_auto_ptr") = 1; -#else - scope().attr("broken_auto_ptr") = 0; - implicitly_convertible, std::auto_ptr >(); -#endif - - def("look", look); - def("steal", steal); - def("maybe_steal", maybe_steal); - def("make", make); - def("callback", callback); - def("extract", extract_); -} - -#include "module_tail.cpp" - diff --git a/test/auto_ptr.py b/test/auto_ptr.py deleted file mode 100644 index cd83208f..00000000 --- a/test/auto_ptr.py +++ /dev/null @@ -1,77 +0,0 @@ -''' ->>> from auto_ptr_ext import * ->>> x = X(42) ->>> x.value() -42 ->>> look(x), look(x) -(42, 42) - ->>> maybe_steal(x, 0) -42 ->>> look(x) -42 - ->>> maybe_steal(x, 1) -42 ->>> broken_auto_ptr and -1 or look(x) --1 - ->>> x = X(69) ->>> steal(x) -69 ->>> broken_auto_ptr and -1 or look(x) --1 - ->>> if not broken_auto_ptr: -... try: x.value() -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> x = make() ->>> look(x) -77 - ->>> z = callback(lambda z: z) ->>> z.value() -77 - ->>> extract(x).value() -77 - -# -# Test derived to base conversions -# - ->>> y = Y(42) ->>> y.value() -42 - ->>> try: maybe_steal(y, 0) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> y.value() -42 - ->>> broken_auto_ptr and 42 or steal(y) -42 - ->>> if not broken_auto_ptr: -... try: y.value() -... except TypeError: pass -... else: print 'expected a TypeError exception' - -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/back_reference.cpp b/test/back_reference.cpp deleted file mode 100644 index 75233c6b..00000000 --- a/test/back_reference.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// This test shows that a class can be wrapped "as itself" but also -// acquire a back-reference iff has_back_reference<> is appropriately -// specialized. -using namespace boost::python; - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; - -int X::counter; - -struct Y : X -{ - Y(PyObject* self, int x) : X(x) {}; - Y(PyObject* self, Y const& rhs) : X(rhs), self(self) {}; - private: - Y(Y const&); - PyObject* self; -}; - -struct Z : X -{ - Z(PyObject* self, int x) : X(x) {}; - Z(PyObject* self, Z const& rhs) : X(rhs), self(self) {}; - private: - Z(Z const&); - PyObject* self; -}; - -Y const& copy_Y(Y const& y) { return y; } -Z const& copy_Z(Z const& z) { return z; } - -namespace boost { namespace python -{ - template <> - struct has_back_reference - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template <> - struct has_back_reference - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; -}} - -// prove that back_references get initialized with the right PyObject* -object y_identity(back_reference y) -{ - return y.source(); -} - -// prove that back_references contain the right value -bool y_equality(back_reference y1, Y const& y2) -{ - return &y1.get() == &y2; -} - -BOOST_PYTHON_MODULE(back_reference_ext) -{ - def("copy_Y", copy_Y, return_value_policy()); - def("copy_Z", copy_Z, return_value_policy()); - def("x_instances", &X::count); - - class_("Y", init()) - .def("value", &Y::value) - .def("set", &Y::set) - ; - - class_ >("Z", init()) - .def("value", &Z::value) - .def("set", &Z::set) - ; - - def("y_identity", y_identity); - def("y_equality", y_equality); - -} - -#include "module_tail.cpp" diff --git a/test/back_reference.py b/test/back_reference.py deleted file mode 100644 index 7eac13c3..00000000 --- a/test/back_reference.py +++ /dev/null @@ -1,29 +0,0 @@ -''' ->>> from back_reference_ext import * ->>> y = Y(3) ->>> z = Z(4) ->>> x_instances() -2 ->>> y2 = copy_Y(y) ->>> x_instances() -3 ->>> z2 = copy_Z(z) ->>> x_instances() -4 ->>> assert y_identity(y) is y ->>> y_equality(y, y) -1 -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/bases.cpp b/test/bases.cpp deleted file mode 100644 index e4f91990..00000000 --- a/test/bases.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -struct A; -struct B; - -template -struct choose_bases - : boost::python::detail::select_bases< - X - , typename boost::python::detail::select_bases< - Y - , typename boost::python::detail::select_bases::type - >::type> -{ - -}; - -int main() -{ - BOOST_STATIC_ASSERT((boost::python::detail::specifies_bases< - boost::python::bases >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - boost::python::bases& >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - void* >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - int >::value)); - - BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< - int[5] >::value)); - - typedef boost::python::detail::select_bases< - int - , boost::python::detail::select_bases::type > collected1; - - BOOST_STATIC_ASSERT((boost::is_same >::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,boost::python::bases<> >::value)); - - typedef boost::python::detail::select_bases< - int - , boost::python::detail::select_bases< - boost::python::bases - , boost::python::detail::select_bases< - A - >::type - >::type - > collected2; - - BOOST_STATIC_ASSERT((boost::is_same >::value)); - BOOST_STATIC_ASSERT((boost::is_same,long>::type,boost::python::bases >::value)); - - return 0; -} diff --git a/test/ben_scott1.cpp b/test/ben_scott1.cpp deleted file mode 100644 index 3c0d5522..00000000 --- a/test/ben_scott1.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -using namespace boost::python; -using namespace boost; - -struct Product {}; -typedef shared_ptr ProductPtr; - - -struct Creator -{ - virtual ~Creator() {} - virtual ProductPtr create() = 0; -}; - - -struct Factory -{ - void reg(Creator* c) { mC = c; } - ProductPtr create() - { - std::cout << "Name: " << (typeid(*mC)).name() << std::endl; - return mC->create(); - } - -private: - Creator* mC; -}; - -struct CreatorWrap : public Creator -{ - CreatorWrap(PyObject* self) : mSelf(self) {} - ProductPtr create() { return call_method(mSelf, "create"); } - PyObject* mSelf; -}; - -BOOST_PYTHON_MODULE(ben_scott1_ext) -{ - class_("Product"); - - class_("Creator") - .def("create", &CreatorWrap::create) - ; - - class_("Factory") - .def("reg", &Factory::reg, with_custodian_and_ward<1,2>()) - .def("create", &Factory::create) - ; -} - -#include "../test/module_tail.cpp" diff --git a/test/ben_scott1.py b/test/ben_scott1.py deleted file mode 100644 index 1475e3d0..00000000 --- a/test/ben_scott1.py +++ /dev/null @@ -1,14 +0,0 @@ -# This regression test checks that call_method(...) where T is a -# non-reference, non-pointer type that happens to be held inside the -# result object (and thus is found as an lvalue) works. -from ben_scott1_ext import * - -class CreatorImpl(Creator): - def create(self): - return Product() - -factory = Factory() -c = CreatorImpl() -factory.reg(c) - -a = factory.create() diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp deleted file mode 100644 index 4f3b107d..00000000 --- a/test/bienstman1.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include - -struct A {}; - -struct V -{ - - virtual void f() = 0; - - const A* inside() {return &a;} - - A a; -}; - -const A* outside(const V& v) {return &v.a;} - -BOOST_PYTHON_MODULE(bienstman1_ext) -{ - using namespace boost::python; - using boost::shared_ptr; - using boost::python::return_value_policy; - using boost::python::reference_existing_object; - - class_("A"); - - class_("V", no_init) - .def("inside", &V::inside, - return_value_policy()) - .def("outside", outside, - return_value_policy()) - ; -} - diff --git a/test/bienstman1.py b/test/bienstman1.py deleted file mode 100644 index d5ec22b5..00000000 --- a/test/bienstman1.py +++ /dev/null @@ -1,18 +0,0 @@ -''' -# Try to reproduce a Numeric interaction bug if Numeric is installed. ->>> from bienstman1_ext import * ->>> try: from Numeric import * -... except: pass -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/bienstman2.cpp b/test/bienstman2.cpp deleted file mode 100644 index 17ade499..00000000 --- a/test/bienstman2.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -struct C {}; - -struct D {}; - -struct E -{ - const D fe (const C&) {return D();} - const D fe2(const C&, const C&) {return D();} -}; - -BOOST_PYTHON_MODULE(bienstman2_ext) -{ - using namespace boost::python; - - class_("C"); - class_("D"); - class_("E") - .def("fe", &E::fe) // this compiles. - .def("fe2", &E::fe2) // this doesn't... well, now it does ;-) - ; -} diff --git a/test/bienstman2.py b/test/bienstman2.py deleted file mode 100644 index 45ee4134..00000000 --- a/test/bienstman2.py +++ /dev/null @@ -1,15 +0,0 @@ -''' ->>> import bienstman2_ext -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp deleted file mode 100644 index 9248ef8f..00000000 --- a/test/bienstman3.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -struct V -{ - virtual void f() = 0; -}; - -struct B -{ - B(const V&) {} -}; - -BOOST_PYTHON_MODULE(bienstman3_ext) -{ - using namespace boost::python; - - class_("V", no_init); - class_("B", init()); - -} diff --git a/test/bienstman3.py b/test/bienstman3.py deleted file mode 100644 index 90efdd53..00000000 --- a/test/bienstman3.py +++ /dev/null @@ -1,25 +0,0 @@ -''' ->>> from bienstman3_ext import * - ->>> try: -... V() -... except RuntimeError, x: -... print x -... else: -... print 'expected an exception' -... -This class cannot be instantiated from Python - -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp deleted file mode 100644 index 124d76a5..00000000 --- a/test/bienstman4.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include - -struct Type1 {}; - -struct Term {Term(Type1 const&) {} }; - -struct Expression {void add(Term const&) {} }; - -BOOST_PYTHON_MODULE(bienstman4_ext) -{ - using namespace boost::python; - using boost::mpl::list; - - implicitly_convertible(); - - class_("Expression") - .def("add", &Expression::add) - ; - - class_("T1") - ; - - class_("Term", init()) - ; - - Type1 t1; - Expression e; - e.add(t1); -} - diff --git a/test/bienstman4.py b/test/bienstman4.py deleted file mode 100644 index 2fede1fc..00000000 --- a/test/bienstman4.py +++ /dev/null @@ -1,18 +0,0 @@ -''' ->>> from bienstman4_ext import * ->>> t1 = T1() ->>> e = Expression() ->>> e.add(t1) -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp deleted file mode 100644 index 72875663..00000000 --- a/test/bienstman5.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include - -#include - -struct M {M(const std::complex&) {} }; - -BOOST_PYTHON_MODULE(bienstman5_ext) -{ - using namespace boost::python; - - class_("M", init const&>()) - ; -} - - diff --git a/test/bienstman5.py b/test/bienstman5.py deleted file mode 100644 index 10c35ff4..00000000 --- a/test/bienstman5.py +++ /dev/null @@ -1,16 +0,0 @@ -''' ->>> from bienstman5_ext import * ->>> m = M(1j) -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/borrowed.cpp b/test/borrowed.cpp deleted file mode 100755 index 0f8d3112..00000000 --- a/test/borrowed.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -using namespace boost::python; - -template -void assert_borrowed_ptr(T const& x) -{ - BOOST_STATIC_ASSERT(boost::python::detail::is_borrowed_ptr::value); -} - -template -void assert_not_borrowed_ptr(T const& x) -{ - BOOST_STATIC_ASSERT(!boost::python::detail::is_borrowed_ptr::value); -} - -int main() -{ - assert_borrowed_ptr(borrowed((PyObject*)0)); - assert_borrowed_ptr(borrowed((PyTypeObject*)0)); - assert_borrowed_ptr((detail::borrowed const*)0); - assert_borrowed_ptr((detail::borrowed volatile*)0); - assert_borrowed_ptr((detail::borrowed const volatile*)0); - assert_not_borrowed_ptr((PyObject*)0); - assert_not_borrowed_ptr(0); - return 0; -} diff --git a/test/callbacks.cpp b/test/callbacks.cpp deleted file mode 100644 index 1cfe2914..00000000 --- a/test/callbacks.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::python; -BOOST_STATIC_ASSERT(converter::is_object_manager >::value); - -int apply_int_int(PyObject* f, int x) -{ - return call(f, x); -} - -void apply_void_int(PyObject* f, int x) -{ - call(f, x); -} - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; - -X apply_X_X(PyObject* f, X x) -{ - return call(f, x); -} - -void apply_void_X_ref(PyObject* f, X& x) -{ - call(f, boost::ref(x)); -} - -X& apply_X_ref_handle(PyObject* f, handle<> obj) -{ - return call(f, obj); -} - -X* apply_X_ptr_handle_cref(PyObject* f, handle<> const& obj) -{ - return call(f, obj); -} - -void apply_void_X_cref(PyObject* f, X const& x) -{ - call(f, boost::cref(x)); -} - -void apply_void_X_ptr(PyObject* f, X* x) -{ - call(f, ptr(x)); -} - -void apply_void_X_deep_ptr(PyObject* f, X* x) -{ - call(f, x); -} - -char const* apply_cstring_cstring(PyObject* f, char const* s) -{ - return call(f, s); -} - -char const* apply_cstring_pyobject(PyObject* f, PyObject* s) -{ - return call(f, borrowed(s)); -} - -char apply_char_char(PyObject* f, char c) -{ - return call(f, c); -} - -char const* apply_to_string_literal(PyObject* f) -{ - return call(f, "hello, world"); -} - -handle<> apply_to_own_type(handle<> x) -{ - // Tests that we can return handle<> from a callback and that we - // can pass arbitrary handle. - return call >(x.get(), type_handle(borrowed(x->ob_type))); -} - -object apply_object_object(PyObject* f, object x) -{ - return call(f, x); -} - -int X::counter; - -BOOST_PYTHON_MODULE(callbacks_ext) -{ - def("apply_object_object", apply_object_object); - def("apply_to_own_type", apply_to_own_type); - def("apply_int_int", apply_int_int); - def("apply_void_int", apply_void_int); - def("apply_X_X", apply_X_X); - def("apply_void_X_ref", apply_void_X_ref); - def("apply_void_X_cref", apply_void_X_cref); - def("apply_void_X_ptr", apply_void_X_ptr); - def("apply_void_X_deep_ptr", apply_void_X_deep_ptr); - - def("apply_X_ptr_handle_cref", apply_X_ptr_handle_cref - , return_value_policy()); - - def("apply_X_ref_handle", apply_X_ref_handle - , return_value_policy()); - - def("apply_cstring_cstring", apply_cstring_cstring); - def("apply_cstring_pyobject", apply_cstring_pyobject); - def("apply_char_char", apply_char_char); - def("apply_to_string_literal", apply_to_string_literal); - - - class_("X", init()) - .def(init()) - .def("value", &X::value) - .def("set", &X::set) - ; - - def("x_count", &X::count); -} - -#include "module_tail.cpp" diff --git a/test/callbacks.py b/test/callbacks.py deleted file mode 100644 index 937961fd..00000000 --- a/test/callbacks.py +++ /dev/null @@ -1,133 +0,0 @@ -''' ->>> from callbacks_ext import * - ->>> def double(x): -... return x + x -... ->>> apply_int_int(double, 42) -84 ->>> apply_void_int(double, 42) - ->>> def identity(x): -... return x - -Once we have array conversion support, this test will fail. Er, -succeed: - ->>> try: apply_to_string_literal(identity) -... except: pass # expected -... else: print 'expected an exception!' - ->>> x = apply_X_X(identity, X(42)) ->>> x.value() -42 ->>> x_count() -1 ->>> del x ->>> x_count() -0 - ->>> def increment(x): -... x.set(x.value() + 1) -... ->>> x = X(42) ->>> apply_void_X_ref(increment, x) ->>> x.value() -43 - ->>> apply_void_X_cref(increment, x) ->>> x.value() # const-ness is not respected, sorry! -44 - ->>> last_x = 1 ->>> def decrement(x): -... global last_x -... last_x = x -... if x is not None: -... x.set(x.value() - 1) - ->>> apply_void_X_ptr(decrement, x) ->>> x.value() -43 ->>> last_x.value() -43 ->>> increment(last_x) ->>> x.value() -44 ->>> last_x.value() -44 - ->>> apply_void_X_ptr(decrement, None) ->>> assert last_x is None ->>> x.value() -44 - ->>> last_x = 1 ->>> apply_void_X_deep_ptr(decrement, None) ->>> assert last_x is None ->>> x.value() -44 - ->>> apply_void_X_deep_ptr(decrement, x) ->>> x.value() -44 ->>> last_x.value() -43 - ->>> y = apply_X_ref_handle(identity, x) ->>> assert y.value() == x.value() ->>> increment(x) ->>> assert y.value() == x.value() - ->>> y = apply_X_ptr_handle_cref(identity, x) ->>> assert y.value() == x.value() ->>> increment(x) ->>> assert y.value() == x.value() - ->>> y = apply_X_ptr_handle_cref(identity, None) ->>> y - ->>> def new_x(ignored): -... return X(666) -... ->>> try: apply_X_ref_handle(new_x, 1) -... except ReferenceError: pass -... else: print 'no error' - ->>> try: apply_X_ptr_handle_cref(new_x, 1) -... except ReferenceError: pass -... else: print 'no error' - ->>> try: apply_cstring_cstring(identity, 'hello') -... except ReferenceError: pass -... else: print 'no error' - ->>> apply_char_char(identity, 'x') -'x' - ->>> apply_cstring_pyobject(identity, 'hello') -'hello' - ->>> apply_cstring_pyobject(identity, None) - - ->>> apply_char_char(identity, 'x') -'x' - ->>> assert apply_to_own_type(identity) is type(identity) - ->>> assert apply_object_object(identity, identity) is identity -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/cltree.cpp b/test/cltree.cpp deleted file mode 100755 index 099d5cb7..00000000 --- a/test/cltree.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include - -/* Non-modifiable definitions */ - -class basic { -public: - basic() { name = "cltree.basic"; } - std::string repr() { return name+"()"; } -protected: - std::string name; -}; - -class constant: public basic { -public: - constant() { name = "cltree.constant"; } -}; - -class symbol: public basic { -public: - symbol() { name = "cltree.symbol"; } -}; - -class variable: public basic { -public: - variable() { name = "cltree.variable"; } -}; - -/* EOF: Non-modifiable definitions */ - -class symbol_wrapper: public symbol { -public: - symbol_wrapper(PyObject* self): symbol() { - name = "cltree.wrapped_symbol"; - } -}; - -class variable_wrapper: public variable { -public: - variable_wrapper(PyObject* self): variable() { - name = "cltree.wrapped_variable"; - } - - // This constructor is introduced only because cannot use - // boost::noncopyable, see below. - variable_wrapper(PyObject* self,variable v): variable(v) {} - -}; - -BOOST_PYTHON_MODULE(cltree) -{ - boost::python::class_("basic") - .def("__repr__",&basic::repr) - ; - - boost::python::class_, boost::noncopyable>("constant") - ; - - - boost::python::class_("symbol") - ; - - boost::python::class_, variable_wrapper>("variable") - ; -} - -#include "module_tail.cpp" - diff --git a/test/complicated.hpp b/test/complicated.hpp deleted file mode 100644 index 123c53fe..00000000 --- a/test/complicated.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef COMPLICATED_DWA20011215_HPP -# define COMPLICATED_DWA20011215_HPP -# include - -# include "simple_type.hpp" - -struct complicated -{ - complicated(simple const&, int = 0); - ~complicated(); - - int get_n() const; - - char* s; - int n; -}; - -inline complicated::complicated(simple const&s, int n) - : s(s.s), n(n) -{ - std::cout << "constructing complicated: " << this->s << ", " << n << std::endl; -} - -inline complicated::~complicated() -{ - std::cout << "destroying complicated: " << this->s << ", " << n << std::endl; -} - -inline int complicated::get_n() const -{ - return n; -} - -#endif // COMPLICATED_DWA20011215_HPP diff --git a/test/copy_ctor_mutates_rhs.cpp b/test/copy_ctor_mutates_rhs.cpp deleted file mode 100755 index 7244ab0e..00000000 --- a/test/copy_ctor_mutates_rhs.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright David Abrahams 2003. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include - -struct foo -{ - operator std::auto_ptr&() const; -}; - -int main() -{ - using namespace boost::python::detail; - BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value); - BOOST_STATIC_ASSERT(copy_ctor_mutates_rhs >::value); - BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value); - BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value); - return 0; -} diff --git a/test/data_members.cpp b/test/data_members.cpp deleted file mode 100644 index 13c46b0d..00000000 --- a/test/data_members.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include "test_class.hpp" - -#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -# include // works around a KCC intermediate code generation bug -#endif - - -using namespace boost::python; - -typedef test_class<> X; - -typedef test_class<1> Y; - -double get_fair_value(X const& x) { return x.value(); } - - -struct VarBase -{ - VarBase(std::string name_) : name(name_) {} - - std::string const name; - std::string get_name1() const { return name; } -}; - -struct Var : VarBase -{ - Var(std::string name_) : VarBase(name_), value(), name2(name.c_str()), y(6) {} - std::string const& get_name2() const { return name; } - float value; - char const* name2; - Y y; -}; - -BOOST_PYTHON_MODULE(data_members_ext) -{ - class_("X", init()) - .def("value", &X::value) - .def("set", &X::set) - .def_readonly("x", &X::x) - .add_property("fair_value", get_fair_value) - ; - - class_("Y", init()) - .def("value", &Y::value) - .def("set", &Y::set) - .def_readwrite("x", &Y::x) - ; - - class_("Var", init()) - .def_readonly("name", &Var::name) - .def_readonly("name2", -#if __MWERKS__ <= 0x2407 // Old MWerks mis-deduces the type here as `char* Var::*' - (char const* Var::*) -#endif - &Var::name2 - ) - .def_readwrite("value", &Var::value) - .def_readonly("y", &Var::y) - - // Test return_by_value for plain values and for - // pointers... return_by_value was implemented as a - // side-effect of implementing data member support, so it made - // sense to add the test here. - .def("get_name1", &Var::get_name1, return_value_policy()) - .def("get_name2", &Var::get_name2, return_value_policy()) - - .add_property("name3", &Var::get_name1) - ; -} - -#include "module_tail.cpp" diff --git a/test/data_members.py b/test/data_members.py deleted file mode 100644 index 989c3c32..00000000 --- a/test/data_members.py +++ /dev/null @@ -1,55 +0,0 @@ -''' ->>> from data_members_ext import * - ->>> x = X(42) ->>> x.x -42 ->>> try: x.x = 77 -... except AttributeError: pass -... else: print 'no error' - ->>> x.fair_value -42.0 ->>> y = Y(69) ->>> y.x -69 ->>> y.x = 77 ->>> y.x -77 - ->>> v = Var("pi") ->>> v.value = 3.14 ->>> v.name -'pi' ->>> v.name2 -'pi' - ->>> v.get_name1() -'pi' - ->>> v.get_name2() -'pi' - ->>> v.y.x -6 ->>> v.y.x = -7 ->>> v.y.x --7 - ->>> v.name3 -'pi' - -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/defaults.cpp b/test/defaults.cpp deleted file mode 100644 index 1c173a79..00000000 --- a/test/defaults.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include -#include - -#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -# include // works around a KCC intermediate code generation bug -#endif - -using namespace boost::python; - -char const* const format = "int(%s); char(%s); string(%s); double(%s); "; - -/////////////////////////////////////////////////////////////////////////////// -// -// Overloaded functions -// -/////////////////////////////////////////////////////////////////////////////// -object -bar(int a, char b, std::string c, double d) -{ - return format % make_tuple(a, b, c, d); -} - -object -bar(int a, char b, std::string c) -{ - return format % make_tuple(a, b, c, 0.0); -} - -object -bar(int a, char b) -{ - return format % make_tuple(a, b, "default", 0.0); -} - -object -bar(int a) -{ - return format % make_tuple(a, 'D', "default", 0.0); -} - -BOOST_PYTHON_FUNCTION_OVERLOADS(bar_stubs, bar, 1, 4) - -/////////////////////////////////////////////////////////////////////////////// -// -// Functions with default arguments -// -/////////////////////////////////////////////////////////////////////////////// -object -foo(int a, char b = 'D', std::string c = "default", double d = 0.0) -{ - return format % make_tuple(a, b, c, d); -} - -BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) - -/////////////////////////////////////////////////////////////////////////////// -// -// Overloaded member functions with default arguments -// -/////////////////////////////////////////////////////////////////////////////// -struct Y { - - Y() {} - - object - get_state() const - { - return format % make_tuple(a, b, c, d); - } - - int a; char b; std::string c; double d; -}; - - -struct X { - - X() {} - - X(int a, char b = 'D', std::string c = "constructor", double d = 0.0) - : state(format % make_tuple(a, b, c, d)) - {} - - X(std::string s, bool b) - : state("Got exactly two arguments from constructor: string(%s); bool(%s); " % make_tuple(s, b)) - {} - - object - bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const - { - return format % make_tuple(a, b, c, d); - } - - Y const& - bar2(int a = 0, char b = 'D', std::string c = "default", double d = 0.0) - { - // tests zero arg member function and return_internal_reference policy - y.a = a; - y.b = b; - y.c = c; - y.d = d; - return y; - } - - object - foo(int a, bool b=false) const - { - return "int(%s); bool(%s); " % make_tuple(a, b); - } - - object - foo(std::string a, bool b=false) const - { - return "string(%s); bool(%s); " % make_tuple(a, b); - } - - object - foo(list a, list b, bool c=false) const - { - return "list(%s); list(%s); bool(%s); " % make_tuple(a, b, c); - } - - object - get_state() const - { - return state; - } - - Y y; - object state; -}; - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs, bar, 1, 4) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs2, bar2, 0, 4) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) - -/////////////////////////////////////////////////////////////////////////////// - -BOOST_PYTHON_MODULE(defaults_ext) -{ - def("foo", foo, foo_stubs()); - def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()); - - class_("Y", init<>("doc of Y init")) // this should work - .def("get_state", &Y::get_state) - ; - - class_("X") - - .def(init >("doc of init")) - .def(init()[default_call_policies()]) // what's a good policy here? - .def("get_state", &X::get_state) - .def("bar", &X::bar, X_bar_stubs()) - .def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()]) - .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) - .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) - .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) - ; -} - -#include "module_tail.cpp" - diff --git a/test/defaults.py b/test/defaults.py deleted file mode 100644 index 168c5de3..00000000 --- a/test/defaults.py +++ /dev/null @@ -1,174 +0,0 @@ -""" ->>> False = 0 # Python 2.2 needs these ->>> True = 1 - ->>> from defaults_ext import * ->>> bar(1) -'int(1); char(D); string(default); double(0.0); ' - ->>> bar(2, 'X') -'int(2); char(X); string(default); double(0.0); ' - ->>> bar(3, 'Y', "Hello World") -'int(3); char(Y); string(Hello World); double(0.0); ' - ->>> bar(4, 'Z', "Hi There", 3.3) -'int(4); char(Z); string(Hi There); double(3.3); ' - ->>> foo(1) -'int(1); char(D); string(default); double(0.0); ' - ->>> foo(2, 'X') -'int(2); char(X); string(default); double(0.0); ' - ->>> foo(3, 'Y', "Hello World") -'int(3); char(Y); string(Hello World); double(0.0); ' - ->>> foo(4, 'Z', "Hi There", 3.3) -'int(4); char(Z); string(Hi There); double(3.3); ' - ->>> x = X() ->>> x.bar(1) -'int(1); char(D); string(default); double(0.0); ' - ->>> x.bar(2, 'X') -'int(2); char(X); string(default); double(0.0); ' - ->>> x.bar(3, 'Y', "Hello World") -'int(3); char(Y); string(Hello World); double(0.0); ' - ->>> x.bar(4, 'Z', "Hi There", 3.3) -'int(4); char(Z); string(Hi There); double(3.3); ' - ->>> x.foo(5) -'int(5); bool(0); ' - ->>> x.foo(6, 0) -'int(6); bool(0); ' - ->>> x.foo(7, 1) -'int(7); bool(1); ' - ->>> x.foo("A") -'string(A); bool(0); ' - ->>> x.foo("B", False) -'string(B); bool(0); ' - ->>> x.foo("C", True) -'string(C); bool(1); ' - ->>> x.foo([0,1,2], [2,3,4]) -'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' - ->>> x.foo([0,1,2], [2,3,4], False) -'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' - ->>> x.foo([0,1,2], [2,3,4], True) -'list([0, 1, 2]); list([2, 3, 4]); bool(1); ' - ->>> x = X(1) ->>> x.get_state() -'int(1); char(D); string(constructor); double(0.0); ' - ->>> x = X(1, 'X') ->>> x.get_state() -'int(1); char(X); string(constructor); double(0.0); ' - ->>> x = X(1, 'X', "Yabadabadoo") ->>> x.get_state() -'int(1); char(X); string(Yabadabadoo); double(0.0); ' - ->>> x = X(1, 'X', "Phoenix", 3.65) ->>> x.get_state() -'int(1); char(X); string(Phoenix); double(3.65); ' - ->>> x.bar2().get_state() -'int(0); char(D); string(default); double(0.0); ' - ->>> x.bar2(1).get_state() -'int(1); char(D); string(default); double(0.0); ' - ->>> x.bar2(1, 'K').get_state() -'int(1); char(K); string(default); double(0.0); ' - ->>> x.bar2(1, 'K', "Kim").get_state() -'int(1); char(K); string(Kim); double(0.0); ' - ->>> x.bar2(1, 'K', "Kim", 9.9).get_state() -'int(1); char(K); string(Kim); double(9.9); ' - ->>> x = X("Phoenix", 1) ->>> x.get_state() -'Got exactly two arguments from constructor: string(Phoenix); bool(1); ' - ->>> def printdoc(x): -... print x.__doc__ - ->>> printdoc(X.__init__) -doc of init - ->>> printdoc(Y.__init__) -doc of Y init - ->>> printdoc(X.bar2) -doc of X::bar2 - -""" -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/destroy_test.cpp b/test/destroy_test.cpp deleted file mode 100644 index 38d5d1d5..00000000 --- a/test/destroy_test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include - -struct bar; - -namespace boost -{ - // lie to the library about bar so we can show that its destructor is optimized away. - template <> - struct has_trivial_destructor - { - BOOST_STATIC_CONSTANT(bool, value=true); - }; -} - - -int count; -int marks[] = { - -1 - , -1, -1 - , -1, -1, -1, -1 - , -1 -}; -int* kills = marks; - -struct foo -{ - foo() : n(count++) {} - ~foo() - { - *kills++ = n; - } - int n; -}; - -struct bar : foo {}; - -void assert_destructions(int n) -{ - for (int i = 0; i < n; ++i) - assert(marks[i] == i); - assert(marks[n] == -1); -} - -int main() -{ - assert_destructions(0); - typedef int a[2]; - - foo* f1 = new foo; - boost::python::detail::destroy_referent(f1); - assert_destructions(1); - - foo* f2 = new foo[2]; - typedef foo x[2]; - - boost::python::detail::destroy_referent(f2); - assert_destructions(3); - - typedef foo y[2][2]; - x* f3 = new y; - boost::python::detail::destroy_referent(f3); - assert_destructions(7); - - bar* b1 = new bar; - boost::python::detail::destroy_referent(b1); - assert_destructions(7); - - bar* b2 = new bar[2]; - typedef bar xb[2]; - - boost::python::detail::destroy_referent(b2); - assert_destructions(7); - - typedef bar yb[2][2]; - xb* b3 = new yb; - boost::python::detail::destroy_referent(b3); - assert_destructions(7); - - return 0; -} diff --git a/test/dict.cpp b/test/dict.cpp deleted file mode 100644 index de6d4a86..00000000 --- a/test/dict.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -object new_dict() -{ - return dict(); -} - -object data_dict() -{ - dict tmp1; - tmp1["key1"] = "value1"; - - dict tmp2; - tmp2["key2"] = "value2"; - tmp1[1] = tmp2; - return tmp1; -} - -object dict_from_sequence(object sequence) -{ - return dict(sequence); -} - -object dict_keys(dict data) -{ - return data.keys(); -} - -object dict_values(dict data) -{ - return data.values(); -} - -object dict_items(dict data) -{ - return data.items(); -} - -void work_with_dict(dict data1, dict data2) -{ - if (!data1.has_key("k1")) { - throw std::runtime_error("dict does not have key 'k1'"); - } - data1.update(data2); -} - -void test_templates(object print) -{ - std::string key = "key"; - - dict tmp; - tmp[1] = "a test string"; - print(tmp.get(1)); - //print(tmp[1]); - tmp[1.5] = 13; - print(tmp.get(1.5)); - print(tmp.get(44)); - print(tmp); - print(tmp.get(2,"default")); - print(tmp.has_key(key)); - print(tmp.setdefault(3,"default")); - //print(tmp[3]); -} - -BOOST_PYTHON_MODULE(dict_ext) -{ - def("new_dict", new_dict); - def("data_dict", data_dict); - def("dict_keys", dict_keys); - def("dict_values", dict_values); - def("dict_items", dict_items); - def("dict_from_sequence", dict_from_sequence); - def("work_with_dict", work_with_dict); - def("test_templates", test_templates); -} diff --git a/test/dict.py b/test/dict.py deleted file mode 100644 index c99d2e9b..00000000 --- a/test/dict.py +++ /dev/null @@ -1,41 +0,0 @@ -""" ->>> from dict_ext import * ->>> def printer(*args): -... for x in args: print x, -... print -... ->>> print new_dict() -{} ->>> print data_dict() -{1: {'key2': 'value2'}, 'key1': 'value1'} ->>> tmp = data_dict() ->>> print dict_keys(tmp) -[1, 'key1'] ->>> print dict_values(tmp) -[{'key2': 'value2'}, 'value1'] ->>> print dict_items(tmp) -[(1, {'key2': 'value2'}), ('key1', 'value1')] ->>> print dict_from_sequence([(1,1),(2,2),(3,3)]) -{1: 1, 2: 2, 3: 3} ->>> test_templates(printer) -a test string -13 -None -{1.5: 13, 1: 'a test string'} -default -0 -default -""" - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/docstring.cpp b/test/docstring.cpp deleted file mode 100644 index 65893d02..00000000 --- a/test/docstring.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include "test_class.hpp" - -// Just use math.h here; trying to use std::pow() causes too much -// trouble for non-conforming compilers and libraries. -#include - -using namespace boost::python; - -typedef test_class<> X; - -X* create(int x) -{ - return new X(x); -} - -unsigned long fact(unsigned long n) -{ - return n <= 1 ? n : n * fact(n - 1); -} - -BOOST_PYTHON_MODULE(docstring_ext) -{ - scope().attr("__doc__") = - "A simple test module for documentation strings\n" - "Exercised by docstring.py" - ; - - class_("X", - "A simple class wrapper around a C++ int\n" - "includes some error-checking" - - , init( - "this is the __init__ function\n" - "its documentation has two lines." - ) - - ) - .def("value", &X::value, - "gets the value of the object") - ; - - def("create", create, return_value_policy(), - "creates a new X object"); - - def("fact", fact, "compute the factorial"); -} - -#include "module_tail.cpp" diff --git a/test/docstring.py b/test/docstring.py deleted file mode 100644 index 15cfdaf1..00000000 --- a/test/docstring.py +++ /dev/null @@ -1,54 +0,0 @@ -''' ->>> from docstring_ext import * - ->>> def printdoc(x): -... print x.__doc__ - ->>> printdoc(X) -A simple class wrapper around a C++ int -includes some error-checking - ->>> printdoc(X.__init__) -this is the __init__ function -its documentation has two lines. - ->>> printdoc(X.value) -gets the value of the object - ->>> printdoc(create) -creates a new X object - ->>> printdoc(fact) -compute the factorial -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - - import docstring_ext - - result = doctest.testmod(sys.modules.get(__name__)) - - import pydoc - import re - docmodule = lambda m: re.sub(".\10", "", pydoc.text.docmodule(m)) - try: - print 'printing module help:' - print docmodule(docstring_ext) - except object, x: - print '********* failed **********' - print x - result = list(result) - result[0] += 1 - return tuple(result) - - return result - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/embedding.cpp b/test/embedding.cpp deleted file mode 100644 index 5a86f2cf..00000000 --- a/test/embedding.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// embedded_hello -- A simple Boost.Python embedding example -- by -// Dirk Gerrits - -#include -#include -#include -#include - -namespace python = boost::python; - -// An abstract base class -class Base : public boost::noncopyable -{ -public: - virtual ~Base() {}; - - virtual std::string hello() = 0; -}; - -// C++ derived class -class CppDerived : public Base -{ -public: - virtual ~CppDerived() {} - - std::string hello() - { - return "Hello from C++!"; - } -}; - -// Familiar Boost.Python wrapper class for Base -struct BaseWrap : public Base -{ - BaseWrap(PyObject* self_) - : self(self_) {} - - std::string hello() { return python::call_method(self, "hello"); } - - PyObject* self; -}; - -// Pack the Base class wrapper into a module -BOOST_PYTHON_MODULE(embedded_hello) -{ - python::class_("Base") - ; - -} - - -void test() -{ -//- INITIALIZATION -----------------------------------------------------------// - - // Register the module with the interpreter - if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1) - throw std::runtime_error("Failed to add embedded_hello to the interpreter's " - "builtin modules"); - - // Initialize the interpreter - Py_Initialize(); - - // Retrieve the main module - python::handle<> main_module( - python::borrowed(PyImport_AddModule("__main__")) ); - - // Retrieve the main modules namespace - python::handle<> main_namespace( - python::borrowed(PyModule_GetDict(main_module.get())) ); - - // Define the derived class in Python. - // (You'll normally want to put this in a .py file.) - python::handle<> result( - PyRun_String( - "from embedded_hello import * \n" - "class PythonDerived(Base): \n" - " def hello(self): \n" - " return 'Hello from Python!' \n", - Py_file_input, main_namespace.get(), main_namespace.get()) - ); - // Result is not needed - result.reset(); - - // Extract the raw Python object representing the just defined derived class - python::handle<> class_ptr( - PyRun_String("PythonDerived\n", Py_eval_input, - main_namespace.get(), main_namespace.get()) ); - - // Wrap the raw Python object in a Boost.Python object - python::object PythonDerived(class_ptr); - -//- MAIN PROGRAM -------------------------------------------------------------// - - // Creating and using instances of the C++ class is as easy as always. - CppDerived cpp; - std::cout << cpp.hello() << std::endl; - - // But now creating and using instances of the Python class is almost - // as easy! - python::object py_base = PythonDerived(); - Base& py = python::extract(py_base)(); - std::cout << py.hello() << std::endl; -} - -int main() -{ - if (python::handle_exception(test)) - { - if (PyErr_Occurred()) - PyErr_Print(); - return 1; - } - return 0; -} -#include "module_tail.cpp" diff --git a/test/enum.cpp b/test/enum.cpp deleted file mode 100644 index 1a4f178b..00000000 --- a/test/enum.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) -# include -# include -#endif -using namespace boost::python; - -enum color { red = 1, green = 2, blue = 4 }; - -#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) -namespace boost // Pro7 has a hard time detecting enums -{ - template <> struct is_enum : boost::mpl::true_ {}; -} -#endif - -color identity_(color x) { return x; } - -struct colorized { - colorized() : x(red) {} - color x; -}; - -BOOST_PYTHON_MODULE(enum_ext) -{ - enum_("color") - .value("red", red) - .value("green", green) - .value("blue", blue) - .export_values() - ; - - def("identity", identity_); - - class_("colorized") - .def_readwrite("x", &colorized::x) - ; -} - -#include "module_tail.cpp" diff --git a/test/enum.py b/test/enum.py deleted file mode 100644 index e99e401e..00000000 --- a/test/enum.py +++ /dev/null @@ -1,59 +0,0 @@ -''' ->>> from enum_ext import * - ->>> identity(color.red) -enum_ext.color.red - ->>> identity(color.green) -enum_ext.color.green - ->>> identity(color.blue) -enum_ext.color.blue - ->>> identity(color(1)) -enum_ext.color.red - ->>> identity(color(2)) -enum_ext.color.green - ->>> identity(color(3)) -enum_ext.color(3) - ->>> identity(color(4)) -enum_ext.color.blue - - --- check export to scope --- - ->>> identity(red) -enum_ext.color.red - ->>> identity(green) -enum_ext.color.green - ->>> identity(blue) -enum_ext.color.blue - ->>> try: identity(1) -... except TypeError: pass -... else: print 'expected a TypeError' - ->>> c = colorized() ->>> c.x -enum_ext.color.red ->>> c.x = green ->>> c.x -enum_ext.color.green -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/exception_translator.cpp b/test/exception_translator.cpp deleted file mode 100644 index f9c38ab9..00000000 --- a/test/exception_translator.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -struct error {}; - -void translate(error const& e) -{ - PyErr_SetString(PyExc_RuntimeError, "!!!error!!!"); -} - -void throw_error() -{ - throw error(); - -} - -BOOST_PYTHON_MODULE(exception_translator_ext) -{ - using namespace boost::python; - register_exception_translator(&translate); - - def("throw_error", throw_error); -} - diff --git a/test/exception_translator.py b/test/exception_translator.py deleted file mode 100644 index 78fe3507..00000000 --- a/test/exception_translator.py +++ /dev/null @@ -1,22 +0,0 @@ -''' ->>> from exception_translator_ext import * ->>> try: -... throw_error(); -... except RuntimeError, x: -... print x -... else: -... print 'Expected a RuntimeError!' -!!!error!!! -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/extract.cpp b/test/extract.cpp deleted file mode 100644 index a7749043..00000000 --- a/test/extract.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include "test_class.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -typedef test_class<> X; - -bool extract_bool(object x) { return extract(x); } - -boost::python::list extract_list(object x) -{ - extract get_list((x)); - - // Make sure we always have the right idea about whether it's a list - bool is_list_1 = get_list.check(); - bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type); - assert(is_list_1 == is_list_2); - - return get_list(); -} - -char const* extract_cstring(object x) -{ - return extract(x); -} - -std::string extract_string(object x) -{ - std::string s = extract(x); - return s; -} - -std::string const& extract_string_cref(object x) -{ -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 -# pragma warning(push) -# pragma warning(disable:4172) // msvc lies about returning a reference to temporary -#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 700 -# pragma warning(push) -# pragma warning(disable:473) // intel/win32 does too -#endif - - return extract(x); - -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 700 -# pragma warning(pop) -#endif -} - -X extract_X(object x) -{ - return extract(x); -} - -X* extract_X_ptr(object x) { return extract(x); } - -X& extract_X_ref(object x) -{ - extract get_x(x); - return get_x; -} - -int double_X(object n) -{ - extract x(n); - return x().value() + x().value(); -} - -bool check_bool(object x) { return extract(x).check(); } -bool check_list(object x) { return extract(x).check(); } -bool check_cstring(object x) { return extract(x).check(); } -bool check_string(object x) { return extract(x).check(); } -bool check_string_cref(object x) { return extract(x).check(); } -bool check_X(object x) { return extract(x).check(); } -bool check_X_ptr(object x) { return extract(x).check(); } -bool check_X_ref(object x) { return extract(x).check(); } - -std::string x_rep(X const& x) -{ - return "X(" + boost::lexical_cast(x.value()) + ")"; -} - -BOOST_PYTHON_MODULE(extract_ext) -{ - implicitly_convertible(); - - def("extract_bool", extract_bool); - def("extract_list", extract_list); - def("extract_cstring", extract_cstring); - def("extract_string", extract_string); - def("extract_string_cref", extract_string_cref, return_value_policy()); - def("extract_X", extract_X); - def("extract_X_ptr", extract_X_ptr, return_value_policy()); - def("extract_X_ref", extract_X_ref, return_value_policy()); - - def("check_bool", check_bool); - def("check_list", check_list); - def("check_cstring", check_cstring); - def("check_string", check_string); - def("check_string_cref", check_string_cref); - def("check_X", check_X); - def("check_X_ptr", check_X_ptr); - def("check_X_ref", check_X_ref); - - def("double_X", double_X); - - def("count_Xs", &X::count); - ; - - object x_class( - class_("X", init()) - .def( "__repr__", x_rep)); - - // Instantiate an X object through the Python interface - object x_obj = x_class(3); - - // Get the C++ object out of the Python object - X const& x = extract(x_obj); - assert(x.value() == 3); -} - - -#include "module_tail.cpp" - diff --git a/test/extract.py b/test/extract.py deleted file mode 100644 index 328049dd..00000000 --- a/test/extract.py +++ /dev/null @@ -1,102 +0,0 @@ -''' - >>> from extract_ext import * - -Just about anything has a truth value in Python - - >>> assert check_bool(None) - >>> extract_bool(None) - 0 - - >>> assert check_bool(2) - >>> extract_bool(2) - 1 - - >>> assert not check_bool('') - -Check that object manager types work properly. These are a different -case because they wrap Python objects instead of being wrapped by them. - - >>> assert not check_list(2) - >>> try: x = extract_list(2) - ... except TypeError, x: - ... if str(x) != 'Expecting an object of type list; got an object of type int instead': - ... print x - ... else: - ... print 'expected an exception, got', x, 'instead' - -Can't extract a list from a tuple. Use list(x) to convert a sequence -to a list: - - >>> assert not check_list((1, 2, 3)) - >>> assert check_list([1, 2, 3]) - >>> extract_list([1, 2, 3]) - [1, 2, 3] - -Can get a char const* from a Python string: - - >>> assert check_cstring('hello') - >>> extract_cstring('hello') - 'hello' - -Can't get a char const* from a Python int: - - >>> assert not check_cstring(1) - >>> try: x = extract_cstring(1) - ... except TypeError: pass - ... else: - ... print 'expected an exception, got', x, 'instead' - -Extract an std::string (class) rvalue from a native Python type - - >>> assert check_string('hello') - >>> extract_string('hello') - 'hello' - -Constant references are not treated as rvalues for the purposes of -extract: - - >>> assert not check_string_cref('hello') - -We can extract lvalues where appropriate: - - >>> x = X(42) - >>> check_X(x) - 1 - >>> extract_X(x) - X(42) - - >>> check_X_ptr(x) - 1 - >>> extract_X_ptr(x) - X(42) - >>> extract_X_ref(x) - X(42) - -Demonstrate that double-extraction of an rvalue works, and all created -copies of the object are destroyed: - - >>> n = count_Xs() - >>> double_X(333) - 666 - >>> count_Xs() - n - 0 - -General check for cleanliness: - - >>> del x - >>> count_Xs() - 0 -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/if_else.cpp b/test/if_else.cpp deleted file mode 100644 index e2b50f28..00000000 --- a/test/if_else.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - - typedef char c1; - typedef char c2[2]; - typedef char c3[3]; - typedef char c4[4]; - -template -struct choose -{ - typedef typename boost::python::detail::if_< - (sizeof(c1) == size) - >::template then< - c1 - >::template elif< - (sizeof(c2) == size) - >::template then< - c2 - >::template elif< - (sizeof(c3) == size) - >::template then< - c3 - >::template elif< - (sizeof(c4) == size) - >::template then< - c4 - >::template else_::type type; -}; - -int main() -{ - BOOST_STATIC_ASSERT((boost::is_same::type,c1>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,c2>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,c3>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,c4>::value)); - BOOST_STATIC_ASSERT((boost::is_same::type,void*>::value)); - return 0; -} diff --git a/test/implicit.cpp b/test/implicit.cpp deleted file mode 100644 index c4728548..00000000 --- a/test/implicit.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include "test_class.hpp" - -using namespace boost::python; - -typedef test_class<> X; - -int x_value(X const& x) -{ - return x.value(); -} - -X make_x(int n) { return X(n); } - - -// foo/bar -- a regression for a vc7 bug workaround -struct bar {}; -struct foo -{ - virtual void f() = 0; - operator bar() const { return bar(); } -}; - -BOOST_PYTHON_MODULE(implicit_ext) -{ - implicitly_convertible(); - implicitly_convertible(); - - def("x_value", x_value); - def("make_x", make_x); - - class_("X", init()) - .def("value", &X::value) - .def("set", &X::set) - ; - - implicitly_convertible(); -} - -#include "module_tail.cpp" diff --git a/test/implicit.py b/test/implicit.py deleted file mode 100644 index e0d8c067..00000000 --- a/test/implicit.py +++ /dev/null @@ -1,26 +0,0 @@ -''' ->>> from implicit_ext import * ->>> x_value(X(42)) -42 ->>> x_value(42) -42 ->>> x = make_x(X(42)) ->>> x.value() -42 ->>> try: make_x('fool') -... except TypeError: pass -... else: print 'no error' -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp deleted file mode 100644 index 26c6e895..00000000 --- a/test/indirect_traits_test.cpp +++ /dev/null @@ -1,105 +0,0 @@ -//#include -#include -#include - -//#define print(expr) printf("%s ==> %s\n", #expr, expr) - -// not all the compilers can handle an incomplete class type here. -struct X {}; - -int main() -{ - using namespace boost::python::detail; - - typedef void (X::*pmf)(); - - assert(is_reference_to_function::value); - assert(!is_reference_to_function::value); - assert(!is_reference_to_function::value); - assert(!is_reference_to_function::value); - - assert(!is_pointer_to_function::value); - assert(is_pointer_to_function::value); - assert(!is_pointer_to_function::value); - assert(!is_pointer_to_function::value); - assert(!is_pointer_to_function::value); - - assert(!is_reference_to_function_pointer::value); - assert(!is_reference_to_function_pointer::value); - assert(!is_reference_to_function_pointer::value); - assert(is_reference_to_function_pointer::value); - assert(is_reference_to_function_pointer::value); - assert(!is_reference_to_function_pointer::value); - - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(is_reference_to_pointer::value); - assert(!is_reference_to_pointer::value); - - assert(!is_reference_to_pointer::value); - assert(!is_reference_to_pointer::value); - assert(!is_reference_to_pointer::value); - - assert(!is_reference_to_const::value); - assert(is_reference_to_const::value); - assert(!is_reference_to_const::value); - assert(is_reference_to_const::value); - - assert(!is_reference_to_const::value); - assert(!is_reference_to_const::value); - assert(!is_reference_to_const::value); - - assert(is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - assert(is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - - assert(!is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - assert(!is_reference_to_non_const::value); - - assert(!is_reference_to_volatile::value); - assert(!is_reference_to_volatile::value); - assert(is_reference_to_volatile::value); - assert(is_reference_to_volatile::value); - - assert(!is_reference_to_volatile::value); - assert(!is_reference_to_volatile::value); - assert(!is_reference_to_volatile::value); - - assert(!is_reference_to_class::value); - assert(!is_reference_to_class::value); - assert(!is_reference_to_class::value); - - assert(!is_reference_to_class::value); - assert(is_reference_to_class::value); - assert(is_reference_to_class::value); - assert(is_reference_to_class::value); - assert(is_reference_to_class::value); - - assert(!is_pointer_to_class::value); - assert(!is_pointer_to_class::value); - assert(!is_pointer_to_class::value); - - assert(!is_pointer_to_class::value); - assert(!is_pointer_to_class::value); - assert(is_pointer_to_class::value); - assert(is_pointer_to_class::value); - assert(is_pointer_to_class::value); - assert(is_pointer_to_class::value); - - assert(is_reference_to_member_function_pointer::value); - assert(is_reference_to_member_function_pointer::value); - assert(is_reference_to_member_function_pointer::value); - assert(is_reference_to_member_function_pointer::value); - assert(!is_reference_to_member_function_pointer::value); - assert(!is_reference_to_member_function_pointer::value); - assert(!is_reference_to_member_function_pointer::value); - - return 0; -} diff --git a/test/input_iterator.cpp b/test/input_iterator.cpp deleted file mode 100644 index eacae455..00000000 --- a/test/input_iterator.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -typedef std::list list_int; - -// Prove that we can handle InputIterators which return rvalues. -struct doubler -{ - typedef int result_type; - int operator()(int x) const { return x * 2; } -}; - -typedef boost::transform_iterator_generator::type doubling_iterator; -typedef std::pair list_range2; - -list_range2 range2(list_int& x) -{ - return list_range2( - boost::make_transform_iterator(x.begin(), doubler()) - , boost::make_transform_iterator(x.end(), doubler())); -} - -// We do this in a separate module from iterators_ext (iterators.cpp) -// to work around an MSVC6 linker bug, which causes it to complain -// about a "duplicate comdat" if the input iterator is instantiated in -// the same module with the others. -BOOST_PYTHON_MODULE(input_iterator) -{ - def("range2", &::range2); - - class_("list_range2") - // We can wrap InputIterators which return by-value - .def("__iter__" - , range(&list_range2::first, &list_range2::second)) - ; -} - -#include "module_tail.cpp" diff --git a/test/iterator.cpp b/test/iterator.cpp deleted file mode 100644 index a52e0710..00000000 --- a/test/iterator.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -typedef std::list list_int; -typedef std::list list_list; - - -void push_back(list_int& x, int y) -{ - x.push_back(y); -} - -void push_list_back(list_list& x, list_int const& y) -{ - x.push_back(y); -} - -int back(list_int& x) -{ - return x.back(); -} - -typedef std::pair list_range; - -struct list_range2 : list_range -{ - list_int::iterator& begin() { return this->first; } - list_int::iterator& end() { return this->second; } -}; - -list_range range(list_int& x) -{ - return list_range(x.begin(), x.end()); -} - -struct two_lists -{ - two_lists() - { - int primes[] = { 2, 3, 5, 7, 11, 13 }; - std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one)); - int evens[] = { 2, 4, 6, 8, 10, 12 }; - std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two)); - } - - struct two_start - { - typedef list_int::iterator result_type; - result_type operator()(two_lists& ll) const { return ll.two.begin(); } - }; - friend struct two_start; - - list_int::iterator one_begin() { return one.begin(); } - list_int::iterator two_begin() { return two.begin(); } - - list_int::iterator one_end() { return one.end(); } - list_int::iterator two_end() { return two.end(); } - -private: - list_int one; - list_int two; -}; - -BOOST_PYTHON_MODULE(iterator_ext) -{ - using boost::python::iterator; // gcc 2.96 bug workaround - def("range", &::range); - - class_("list_int") - .def("push_back", push_back) - .def("back", back) - .def("__iter__", iterator()) - ; - - class_("list_range") - - // We can specify data members - .def("__iter__" - , range(&list_range::first, &list_range::second)) - ; - - // No runtime tests for this one yet - class_("list_range2") - - // We can specify member functions returning a non-const reference - .def("__iter__", range(&list_range2::begin, &list_range2::end)) - ; - - class_("two_lists") - - // We can spcify member functions - .add_property( - "primes" - , range(&two_lists::one_begin, &two_lists::one_end)) - - // Prove that we can explicitly specify call policies - .add_property( - "evens" - , range >( - &two_lists::two_begin, &two_lists::two_end)) - - // Prove that we can specify call policies and target - .add_property( - "twosies" - , range, two_lists>( - // And we can use adaptable function objects when - // partial specialization is available. -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - two_lists::two_start() -# else - &two_lists::two_begin -# endif - , &two_lists::two_end)) - ; - - class_("list_list") - .def("push_back", push_list_back) - .def("__iter__", iterator >()) - ; -} - -#include "module_tail.cpp" diff --git a/test/iterator.py b/test/iterator.py deleted file mode 100644 index 2f2f8e02..00000000 --- a/test/iterator.py +++ /dev/null @@ -1,72 +0,0 @@ -''' ->>> from iterator_ext import * ->>> from input_iterator import * ->>> x = list_int() ->>> x.push_back(1) ->>> x.back() -1 ->>> x.push_back(3) ->>> x.push_back(5) ->>> for y in x: -... print y -1 -3 -5 ->>> z = range(x) ->>> for y in z: -... print y -1 -3 -5 - - Range2 wraps a transform_iterator which doubles the elements it - traverses. This proves we can wrap input iterators - ->>> z2 = range2(x) ->>> for y in z2: -... print y -2 -6 -10 - ->>> l2 = two_lists() ->>> for y in l2.primes: -... print y -2 -3 -5 -7 -11 -13 ->>> for y in l2.evens: -... print y -2 -4 -6 -8 -10 -12 ->>> ll = list_list() ->>> ll.push_back(x) ->>> x.push_back(7) ->>> ll.push_back(x) ->>> for a in ll: -... for b in a: -... print b, -... print -... -1 3 5 -1 3 5 7 -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/list.cpp b/test/list.cpp deleted file mode 100644 index 15871e6a..00000000 --- a/test/list.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include -#include "test_class.hpp" - -using namespace boost::python; - -object new_list() -{ - return list(); -} - -list listify(object x) -{ - return list(x); -} - -object listify_string(char const* s) -{ - return list(s); -} - -std::string x_rep(test_class<> const& x) -{ - return "X(" + boost::lexical_cast(x.value()) + ")"; -} - -object apply_object_list(object f, list x) -{ - return f(x); -} - -list apply_list_list(object f, list x) -{ - return call(f.ptr(), x); -} - -void append_object(list& x, object y) -{ - x.append(y); -} - -void append_list(list& x, list const& y) -{ - x.append(y); -} - -typedef test_class<> X; - -int notcmp(object const& x, object const& y) -{ - return y < x ? -1 : y > x ? 1 : 0; -} - -void exercise(list x, object y, object print) -{ - x.append(y); - x.append(5); - x.append(X(3)); - - print("after append:"); - print(x); - - print("number of", y, "instances:", x.count(y)); - - print("number of 5s:", x.count(5)); - - x.extend("xyz"); - print("after extend:"); - print(x); - print("index of", y, "is:", x.index(y)); - print("index of 'l' is:", x.index("l")); - - x.insert(4, 666); - print("after inserting 666:"); - print(x); - print("inserting with object as index:"); - x.insert(x[x.index(5)], "---"); - print(x); - - print("popping..."); - x.pop(); - print(x); - x.pop(x[x.index(5)]); - print(x); - x.pop(x.index(5)); - print(x); - - print("removing", y); - x.remove(y); - print(x); - print("removing", 666); - x.remove(666); - print(x); - - print("reversing..."); - x.reverse(); - print(x); - - print("sorted:"); - x.pop(2); // make sorting predictable - x.sort(); - print(x); - - print("reverse sorted:"); - x.sort(¬cmp); - print(x); - - list w; - w.append(5); - w.append(6); - w += "hi"; - assert(w[0] == 5); - assert(w[1] == 6); - assert(w[2] == 'h'); - assert(w[3] == 'i'); -} - -BOOST_PYTHON_MODULE(list_ext) -{ - def("new_list", new_list); - def("listify", listify); - def("listify_string", listify_string); - def("apply_object_list", apply_object_list); - def("apply_list_list", apply_list_list); - - def("append_object", append_object); - def("append_list", append_list); - - def("exercise", exercise); - - class_("X", init()) - .def( "__repr__", x_rep) - ; -} - diff --git a/test/list.py b/test/list.py deleted file mode 100644 index 0357b9a2..00000000 --- a/test/list.py +++ /dev/null @@ -1,113 +0,0 @@ -''' ->>> from list_ext import * - ->>> new_list() -[] - ->>> listify((1,2,3)) -[1, 2, 3] - ->>> letters = listify_string('hello') ->>> letters -['h', 'e', 'l', 'l', 'o'] - ->>> X(22) -X(22) - ->>> def identity(x): -... return x ->>> assert apply_object_list(identity, letters) is letters - - 5 is not convertible to a list - ->>> try: result = apply_object_list(identity, 5) -... except TypeError: pass -... else: print 'expected an exception, got', result, 'instead' - ->>> assert apply_list_list(identity, letters) is letters - - 5 is not convertible to a list as a return value - ->>> try: result = apply_list_list(len, letters) -... except TypeError: pass -... else: print 'expected an exception, got', result, 'instead' - ->>> append_object(letters, '.') ->>> letters -['h', 'e', 'l', 'l', 'o', '.'] - - tuples do not automatically convert to lists when passed as arguments - ->>> try: append_list(letters, (1,2)) -... except TypeError: pass -... else: print 'expected an exception' - ->>> append_list(letters, [1,2]) ->>> letters -['h', 'e', 'l', 'l', 'o', '.', [1, 2]] - - Check that subclass functions are properly called - ->>> class mylist(list): -... def append(self, o): -... list.append(self, o) -... if not hasattr(self, 'nappends'): -... self.nappends = 1 -... else: -... self.nappends += 1 -... ->>> l2 = mylist() ->>> append_object(l2, 'hello') ->>> append_object(l2, 'world') ->>> l2 -['hello', 'world'] ->>> l2.nappends -2 - ->>> def printer(*args): -... for x in args: print x, -... print -... - ->>> y = X(42) ->>> exercise(letters, y, printer) -after append: -['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3)] -number of X(42) instances: 1 -number of 5s: 1 -after extend: -['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] -index of X(42) is: 7 -index of 'l' is: 2 -after inserting 666: -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] -inserting with object as index: -['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] -popping... -['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y'] -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y'] -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), X(3), 'x', 'y'] -removing X(42) -['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(3), 'x', 'y'] -removing 666 -['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(3), 'x', 'y'] -reversing... -['y', 'x', X(3), [1, 2], '.', 'o', 'l', 'l', 'e', 'h'] -sorted: -[[1, 2], '.', 'e', 'h', 'l', 'l', 'o', 'x', 'y'] -reverse sorted: -['y', 'x', 'o', 'l', 'l', 'h', 'e', '.', [1, 2]] -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/long.cpp b/test/long.cpp deleted file mode 100644 index cc619987..00000000 --- a/test/long.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include - -using namespace boost::python; - -object new_long() -{ - return long_(); -} - -long_ longify(object x) -{ - return long_(x); -} - -object longify_string(char const* s) -{ - return long_(s); -} - -char const* is_long1(long_& x) -{ - long_ y = x; - x += 50; - assert(x == y + 50); - return "yes"; -} - -int is_long2(char const*) -{ - return 0; -} - -BOOST_PYTHON_MODULE(long_ext) -{ - def("new_long", new_long); - def("longify", longify); - def("longify_string", longify_string); - def("is_long", is_long1); - def("is_long", is_long2); - ; -} - diff --git a/test/long.py b/test/long.py deleted file mode 100644 index 7d08e9b7..00000000 --- a/test/long.py +++ /dev/null @@ -1,26 +0,0 @@ -''' ->>> from long_ext import * ->>> new_long() -0L ->>> longify(42) -42L ->>> longify_string('300') -300L ->>> is_long(20L) -'yes' ->>> is_long('20') -0 -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/m1.cpp b/test/m1.cpp deleted file mode 100644 index 8811bac4..00000000 --- a/test/m1.cpp +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - - -#include "simple_type.hpp" -#include "complicated.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Declare some straightforward extension types -extern "C" void -dealloc(PyObject* self) -{ - PyObject_Del(self); -} - -// Noddy is a type we got from one of the Python sample files -struct NoddyObject : PyObject -{ - int x; -}; - -PyTypeObject NoddyType = { - PyObject_HEAD_INIT(NULL) - 0, - "Noddy", - sizeof(NoddyObject), - 0, - dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -// Create a Noddy containing 42 -PyObject* new_noddy() -{ - NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType); - noddy->x = 42; - return (PyObject*)noddy; -} - -// Simple is a wrapper around a struct simple, which just contains a char* -struct SimpleObject -{ - PyObject_HEAD - simple x; -}; - -struct extract_simple_object -{ - static simple& execute(SimpleObject& o) { return o.x; } -}; - -PyTypeObject SimpleType = { - PyObject_HEAD_INIT(NULL) - 0, - "Simple", - sizeof(SimpleObject), - 0, - dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -// Create a Simple containing "hello, world" -PyObject* new_simple() -{ - SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType); - simple->x.s = "hello, world"; - return (PyObject*)simple; -} - -// -// Declare some wrappers/unwrappers to test the low-level conversion -// mechanism. -// -using boost::python::to_python_converter; - -// Wrap a simple by copying it into a Simple -struct simple_to_python - : to_python_converter -{ - static PyObject* convert(simple const& x) - { - SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); - p->x = x; - return (PyObject*)p; - } -}; - -struct int_from_noddy -{ - static int& execute(NoddyObject& p) - { - return p.x; - } -}; - -// -// Some C++ functions to expose to Python -// - -// Returns the length of s's held string -int f(simple const& s) -{ - return strlen(s.s); -} - -int f_mutable_ref(simple& s) -{ - return strlen(s.s); -} - -int f_mutable_ptr(simple* s) -{ - return strlen(s->s); -} - -int f_const_ptr(simple const* s) -{ - return strlen(s->s); -} - -int f2(SimpleObject const& s) -{ - return strlen(s.x.s); -} - -// A trivial passthru function for simple objects -simple const& g(simple const& x) -{ - return x; -} - -struct A -{ - A() : x(0) {} - virtual ~A() {} - char const* name() { return "A"; } - int x; -}; - -struct B : A -{ - B() : x(1) {} - static char const* name(B*) { return "B"; } - int x; -}; - -struct C : A -{ - C() : x(2) {} - char const* name() { return "C"; } - virtual ~C() {} - int x; -}; - -struct D : B, C -{ - D() : x(3) {} - char const* name() { return "D"; } - int x; -}; - -A take_a(A const& a) { return a; } -B take_b(B& b) { return b; } -C take_c(C* c) { return *c; } -D take_d(D* const& d) { return *d; } - -D take_d_shared_ptr(boost::shared_ptr d) { return *d; } - -boost::shared_ptr d_factory() { return boost::shared_ptr(new D); } - -struct Unregistered {}; -Unregistered make_unregistered(int) { return Unregistered(); } - -Unregistered* make_unregistered2(int) { return new Unregistered; } - -BOOST_PYTHON_MODULE(m1) -{ - using namespace boost::python; - using boost::shared_ptr; - - simple_to_python(); - - lvalue_from_pytype(); - - lvalue_from_pytype< -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters - extract_member -#else - extract_simple_object -#endif - , &SimpleType - >(); - - lvalue_from_pytype,&SimpleType>(); - - def("new_noddy", new_noddy); - def("new_simple", new_simple); - - def("make_unregistered", make_unregistered); - def("make_unregistered2", make_unregistered2, return_value_policy()); - - // Expose f() in all its variations - def("f", f); - def("f_mutable_ref", f_mutable_ref); - def("f_mutable_ptr", f_mutable_ptr); - def("f_const_ptr", f_const_ptr); - - def("f2", f2); - - // Expose g() - def("g", g , return_value_policy() - ); - - def("take_a", take_a); - def("take_b", take_b); - def("take_c", take_c); - def("take_d", take_d); - - - def("take_d_shared_ptr", take_d_shared_ptr); - def("d_factory", d_factory); - - class_ >("A") - .def("name", &A::name) - ; - - // sequence points don't ensure that "A" is constructed before "B" - // or "C" below if we make them part of the same chain - class_ >("B") - .def("name", &B::name) - ; - - class_ >("C") - .def("name", &C::name) - ; - - class_ >("D") - .def("name", &D::name) - ; - - class_("complicated", - init()) - .def(init()) - .def("get_n", &complicated::get_n) - ; -} - -#include "module_tail.cpp" diff --git a/test/m2.cpp b/test/m2.cpp deleted file mode 100644 index 3108b2de..00000000 --- a/test/m2.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// This module exercises the converters exposed in m1 at a low level -// by exposing raw Python extension functions that use wrap<> and -// unwrap<> objects. -#include -#include -#include -#include -#include -#include "simple_type.hpp" - -// Get a simple (by value) from the argument, and return the -// string it holds. -PyObject* unwrap_simple(simple x) -{ - return PyString_FromString(x.s); -} - -// Likewise, but demands that its possible to get a non-const -// reference to the simple. -PyObject* unwrap_simple_ref(simple& x) -{ - return PyString_FromString(x.s); -} - -// Likewise, with a const reference to the simple object. -PyObject* unwrap_simple_const_ref(simple const& x) -{ - return PyString_FromString(x.s); -} - -// Get an int (by value) from the argument, and convert it to a -// Python Int. -PyObject* unwrap_int(int x) -{ - return PyInt_FromLong(x); -} - -// Get a non-const reference to an int from the argument -PyObject* unwrap_int_ref(int& x) -{ - return PyInt_FromLong(x); -} - -// Get a const reference to an int from the argument. -PyObject* unwrap_int_const_ref(int const& x) -{ - return PyInt_FromLong(x); -} - -// rewrap extracts a T from the argument, then converts the T back -// to a PyObject* and returns it. -template -struct rewrap -{ - static T f(T x) { return x; } -}; - -BOOST_PYTHON_MODULE(m2) -{ - using boost::python::return_value_policy; - using boost::python::copy_const_reference; - using boost::python::copy_non_const_reference; - using boost::python::def; - - def("unwrap_int", unwrap_int); - def("unwrap_int_ref", unwrap_int_ref); - def("unwrap_int_const_ref", unwrap_int_const_ref); - def("unwrap_simple", unwrap_simple); - def("unwrap_simple_ref", unwrap_simple_ref); - def("unwrap_simple_const_ref", unwrap_simple_const_ref); - - def("wrap_int", &rewrap::f); - - def("wrap_int_ref", &rewrap::f - , return_value_policy() - ); - - def("wrap_int_const_ref", &rewrap::f - , return_value_policy() - ); - - def("wrap_simple", &rewrap::f); - - def("wrap_simple_ref", &rewrap::f - , return_value_policy() - ); - - def("wrap_simple_const_ref", &rewrap::f - , return_value_policy() - ); -} - -#include "module_tail.cpp" diff --git a/test/member_function_cast.cpp b/test/member_function_cast.cpp deleted file mode 100644 index a754fd36..00000000 --- a/test/member_function_cast.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include - -using namespace boost; - -template -void assert_same(S, type* = 0) -{ - BOOST_STATIC_ASSERT((is_same::value)); -} - -template -void assert_mf_cast(F f, type* = 0, type* = 0) -{ - assert_same( - python::detail::member_function_cast::stage1(f).stage2((Target*)0).stage3(f) - ); -} - -struct X -{ - int f() const { return 0; } - void g(char*) {} -}; - -struct Y : X -{ - -}; - -struct Z : Y -{ - int f() const { return 0; } - void g(char*) {} -}; - -int main() -{ - assert_mf_cast(&X::f); - assert_mf_cast(&X::g); - - assert_mf_cast(&Z::f); - assert_mf_cast(&Z::g); - - assert_mf_cast(3); - assert_mf_cast(X()); - return 0; -} diff --git a/test/minimal.cpp b/test/minimal.cpp deleted file mode 100644 index ac6fb4ae..00000000 --- a/test/minimal.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include - -#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 -# include // works around a KCC intermediate code generation bug -#endif - -BOOST_PYTHON_MODULE(minimal_ext) -{ -} - -#include "module_tail.cpp" diff --git a/test/minimal.py b/test/minimal.py deleted file mode 100644 index fde9840a..00000000 --- a/test/minimal.py +++ /dev/null @@ -1,4 +0,0 @@ -print "IMPORTING minimal_ext" -import minimal_ext -print "DONE IMPORTING minimal_ext" - diff --git a/test/module_tail.cpp b/test/module_tail.cpp deleted file mode 100644 index 763e7dff..00000000 --- a/test/module_tail.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#if defined(_WIN32) -# ifdef __MWERKS__ -# pragma ANSI_strict off -# endif -# include -# ifdef __MWERKS__ -# pragma ANSI_strict reset -# endif - -extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable:4297) -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -# pragma warning(pop) -# endif - -BOOL WINAPI DllMain( - HINSTANCE, //hDllInst - DWORD fdwReason, - LPVOID // lpvReserved - ) -{ -# ifdef BOOST_MSVC - _set_se_translator(structured_exception_translator); -# endif - (void)fdwReason; // warning suppression. - - return 1; -} -#endif // _WIN32 - diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp deleted file mode 100644 index 8c3e8846..00000000 --- a/test/multi_arg_constructor.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -struct A -{ - A(const double, const double, const double, const double, const double - , const double, const double - , const double, const double - ) {} -}; - -BOOST_PYTHON_MODULE(multi_arg_constructor_ext) -{ - using namespace boost::python; - - class_( - "A" - , init() - ) - ; - -} - diff --git a/test/multi_arg_constructor.py b/test/multi_arg_constructor.py deleted file mode 100644 index fb062e8a..00000000 --- a/test/multi_arg_constructor.py +++ /dev/null @@ -1,16 +0,0 @@ -''' ->>> from multi_arg_constructor_ext import * ->>> a = A(1.0, 2, 3, 4, 5, 6, 7.0, 8.1, 9.3) -''' -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/nested.cpp b/test/nested.cpp deleted file mode 100644 index 2ccea6f2..00000000 --- a/test/nested.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include "test_class.hpp" -#if __GNUC__ != 2 -# include -#else -# include -#endif - -typedef test_class<> X; -typedef test_class<1> Y; - -std::ostream& operator<<(std::ostream& s, X const& x) -{ - return s << x.value(); -} - -std::ostream& operator<<(std::ostream& s, Y const& x) -{ - return s << x.value(); -} - - -BOOST_PYTHON_MODULE(nested_ext) -{ - using namespace boost::python; - - // Establish X as the current scope. - scope x_class - = class_("X", init()) - .def(str(self)) - ; - - - // Y will now be defined in the current scope - class_("Y", init()) - .def(str(self)) - ; -} - - -#include "module_tail.cpp" - - - diff --git a/test/nested.py b/test/nested.py deleted file mode 100644 index 97ac2a33..00000000 --- a/test/nested.py +++ /dev/null @@ -1,35 +0,0 @@ -''' - >>> from nested_ext import * - - >>> X - - - >>> X.__module__ - 'nested_ext' - - >>> X.__name__ - 'X' - - >>> X.Y - - - >>> X.Y.__module__ - 'nested_ext' - - >>> X.Y.__name__ - 'Y' - -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/newtest.py b/test/newtest.py deleted file mode 100644 index da877151..00000000 --- a/test/newtest.py +++ /dev/null @@ -1,199 +0,0 @@ -""" ->>> from m1 import * - ->>> from m2 import * - - Prove that we get an appropriate error from trying to return a type - for which we have no registered to_python converter - ->>> def check_unregistered(f, msgprefix): -... try: -... f(1) -... except TypeError, x: -... if not str(x).startswith(msgprefix): -... print str(x) -... else: -... print 'expected a TypeError' -... ->>> check_unregistered(make_unregistered, 'No to_python (by-value) converter found for C++ type') ->>> check_unregistered(make_unregistered2, 'No Python class registered for C++ class') - ->>> n = new_noddy() ->>> s = new_simple() ->>> unwrap_int(n) -42 ->>> unwrap_int_ref(n) -42 ->>> unwrap_int_const_ref(n) -42 ->>> unwrap_simple(s) -'hello, world' ->>> unwrap_simple_ref(s) -'hello, world' ->>> unwrap_simple_const_ref(s) -'hello, world' ->>> unwrap_int(5) -5 - -Can't get a non-const reference to a built-in integer object ->>> try: -... unwrap_int_ref(7) -... except: pass -... else: print 'no exception' - ->>> unwrap_int_const_ref(9) -9 - ->>> wrap_int(n) -42 - -try: wrap_int_ref(n) -... except: pass -... else: print 'no exception' - ->>> wrap_int_const_ref(n) -42 - ->>> unwrap_simple_ref(wrap_simple(s)) -'hello, world' - ->>> unwrap_simple_ref(wrap_simple_ref(s)) -'hello, world' - ->>> unwrap_simple_ref(wrap_simple_const_ref(s)) -'hello, world' - ->>> f(s) -12 - ->>> unwrap_simple(g(s)) -'hello, world' - ->>> f(g(s)) -12 - ->>> f_mutable_ref(g(s)) -12 - ->>> f_const_ptr(g(s)) -12 - ->>> f_mutable_ptr(g(s)) -12 - ->>> f2(g(s)) -12 - -Create an extension class which wraps "complicated" (init1 and get_n) -are a complicated constructor and member function, respectively. - ->>> c1 = complicated(s, 99) ->>> c1.get_n() -99 ->>> c2 = complicated(s) ->>> c2.get_n() -0 - - a quick regression test for a bug where None could be converted - to the target of any member function. To see it, we need to - access the __dict__ directly, to bypass the type check supplied - by the Method property which wraps the method when accessed as an - attribute. - ->>> try: A.__dict__['name'](None) -... except TypeError: pass -... else: print 'expected an exception!' - - ->>> a = A() ->>> b = B() ->>> c = C() ->>> d = D() - - ->>> take_a(a).name() -'A' - ->>> try: -... take_b(a) -... except: pass -... else: print 'no exception' - ->>> try: -... take_c(a) -... except: pass -... else: print 'no exception' - ->>> try: -... take_d(a) -... except: pass -... else: print 'no exception' - ------- ->>> take_a(b).name() -'A' - ->>> take_b(b).name() -'B' - ->>> try: -... take_c(b) -... except: pass -... else: print 'no exception' - ->>> try: -... take_d(b) -... except: pass -... else: print 'no exception' - -------- ->>> take_a(c).name() -'A' - ->>> try: -... take_b(c) -... except: pass -... else: print 'no exception' - ->>> take_c(c).name() -'C' - ->>> try: -... take_d(c) -... except: pass -... else: print 'no exception' - -------- ->>> take_a(d).name() -'A' ->>> take_b(d).name() -'B' ->>> take_c(d).name() -'C' ->>> take_d(d).name() -'D' - ->>> take_d_shared_ptr(d).name() -'D' - ->>> d_as_a = d_factory() ->>> dd = take_d(d_as_a) ->>> dd.name() -'D' - -""" - -def run(args = None): - - import sys - import doctest - - if args is not None: - sys.argv = args - - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/numpy.cpp b/test/numpy.cpp deleted file mode 100644 index 8a02f6ee..00000000 --- a/test/numpy.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include - -using namespace boost::python; - -// See if we can invoke array() from C++ -object new_array() -{ - return numeric::array( - make_tuple( - make_tuple(1,2,3) - , make_tuple(4,5,6) - , make_tuple(7,8,9) - ) - ); -} - -// test argument conversion -void take_array(numeric::array x) -{ -} - -// A separate function to invoke the info() member. Must happen -// outside any doctests since this prints directly to stdout and the -// result text includes the address of the 'self' array. -void info(numeric::array const& z) -{ - z.info(); -} - -// Tests which work on both Numeric and numarray array objects. Of -// course all of the operators "just work" since numeric::array -// inherits that behavior from object. -void exercise(numeric::array& y, object check) -{ - y[make_tuple(2,1)] = 3; - check(y); - check(y.astype('D')); - check(y.copy()); - check(y.typecode()); -} - -// numarray-specific tests. check is a callable object which we can -// use to record intermediate results, which are later compared with -// the results of corresponding python operations. -void exercise_numarray(numeric::array& y, object check) -{ - check(y.astype()); - - check(y.argmax()); - check(y.argmax(0)); - - check(y.argmin()); - check(y.argmin(0)); - - check(y.argsort()); - check(y.argsort(1)); - - y.byteswap(); - check(y); - - check(y.diagonal()); - check(y.diagonal(1)); - check(y.diagonal(0, 1)); - check(y.diagonal(0, 1, 0)); - - check(y.is_c_array()); - check(y.isbyteswapped()); - - check(y.trace()); - check(y.trace(1)); - check(y.trace(0, 1)); - check(y.trace(0, 1, 0)); - - check(y.new_('D')); - y.sort(); - check(y); - check(y.type()); - - check(y.factory(make_tuple(1.2, 3.4))); - check(y.factory(make_tuple(1.2, 3.4), "Double")); - check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(1,2,1))); - check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2,1,1), false)); - check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2), true, true)); -} - -BOOST_PYTHON_MODULE(numpy_ext) -{ - def("new_array", new_array); - def("take_array", take_array); - def("exercise", exercise); - def("exercise_numarray", exercise_numarray); - def("set_module_and_type", &numeric::array::set_module_and_type); - def("info", info); -} - -#include "module_tail.cpp" diff --git a/test/numpy.py b/test/numpy.py deleted file mode 100644 index b4c3ec62..00000000 --- a/test/numpy.py +++ /dev/null @@ -1,175 +0,0 @@ -def numeric_tests(): - ''' - >>> from numpy_ext import * - >>> x = new_array() - >>> x[1,1] = 0.0 - - >>> try: take_array(3) - ... except TypeError: pass - ... else: print 'expected a TypeError' - - >>> take_array(x) - - >>> print x - [[1 2 3] - [4 0 6] - [7 8 9]] - - >>> y = x.copy() - - - >>> p = _printer() - >>> check = p.check - >>> exercise(x, p) - >>> y[2,1] = 3 - >>> check(y); - - >>> check(y.astype('D')); - - >>> check(y.copy()); - - >>> check(y.typecode()); - - >>> p.results - [] - >>> del p - ''' - pass - -def _numarray_tests(): - ''' - >>> from numpy_ext import * - >>> x = new_array() - >>> y = x.copy() - >>> p = _printer() - >>> check = p.check - >>> exercise_numarray(x, p) - - >>> check(y.astype()); - - >>> check(y.argmax()); - >>> check(y.argmax(0)); - - >>> check(y.argmin()); - >>> check(y.argmin(0)); - - >>> check(y.argsort()); - >>> check(y.argsort(1)); - - >>> y.byteswap(); - >>> check(y); - - >>> check(y.diagonal()); - >>> check(y.diagonal(1)); - >>> check(y.diagonal(0, 1)); - >>> check(y.diagonal(0, 1, 0)); - - >>> check(y.is_c_array()); - >>> check(y.isbyteswapped()); - - >>> check(y.trace()); - >>> check(y.trace(1)); - >>> check(y.trace(0, 1)); - >>> check(y.trace(0, 1, 0)); - - >>> check(y.new('D')); - >>> y.sort(); - >>> check(y); - >>> check(y.type()); - - >>> check(y.array((1.2, 3.4))); - >>> check(y.array((1.2, 3.4), "Double")); - >>> check(y.array((1.2, 3.4), "Double", (1,2,1))); - >>> check(y.array((1.2, 3.4), "Double", (2,1,1), false)); - >>> check(y.array((1.2, 3.4), "Double", (2,), true, true)); - - >>> p.results - [] - >>> del p - ''' - pass - -false = 0; -true = 1; -class _printer(object): - def __init__(self): - self.results = []; - def __call__(self, *stuff): - self.results += [ str(x) for x in stuff ] - def check(self, x): - if self.results[0] == str(x): - del self.results[0] - else: - print ' Expected:\n %s\n but got:\n %s' % (x, self.results[0]) - -def _run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - - # See which of the numeric modules are installed - has_numeric = 0 - try: - import Numeric - m = Numeric - has_numeric = 1 - except ImportError: pass - - has_numarray = 0 - try: - import numarray - m = numarray - has_numarray = 1 - except ImportError: pass - - # Bail if neither one is installed - if not (has_numeric or has_numarray): - return 0 - - # test the info routine outside the doctest. See numpy.cpp for an - # explanation - import numpy_ext - if (has_numarray): - numpy_ext.info(m.array((1,2,3))) - - failures = 0 - - # - # Run tests 4 different ways if both modules are installed, just - # to show that set_module_and_type() is working properly - # - - # run all the tests with default module search - print 'testing default extension module' - failures += doctest.testmod(sys.modules.get(__name__))[0] - - # test against Numeric if installed - if has_numeric: - print 'testing Numeric module explicitly' - numpy_ext.set_module_and_type('Numeric', 'ArrayType') - failures += doctest.testmod(sys.modules.get(__name__))[0] - - global __test__ - if has_numarray: - # Add the _numarray_tests to the list of things to test in - # this case. - __test__ = { 'numarray_tests':_numarray_tests, - 'numeric_tests': numeric_tests } - print 'testing numarray module explicitly' - numpy_ext.set_module_and_type('numarray', 'NDArray') - failures += doctest.testmod(sys.modules.get(__name__))[0] - del __test__ - - # see that we can go back to the default - print 'testing default module again' - numpy_ext.set_module_and_type('', '') - failures += doctest.testmod(sys.modules.get(__name__))[0] - - return failures - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(_run()) diff --git a/test/object.cpp b/test/object.cpp deleted file mode 100755 index bf702099..00000000 --- a/test/object.cpp +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -using namespace boost::python; - -object call_object_3(object f) -{ - return f(3); -} - -object message() -{ - return object("hello, world!"); -} - -object number() -{ - return object(42); -} - -object obj_getattr(object x, char const* name) -{ - return x.attr(name); -} - -object obj_const_getattr(object const& x, char const* name) -{ - return x.attr(name); -} - -void obj_setattr(object x, char const* name, object value) -{ - x.attr(name) = value; -} - -void obj_setattr42(object x, char const* name) -{ - x.attr(name) = 42; -} - -void obj_moveattr(object& x, char const* src, char const* dst) -{ - x.attr(dst) = x.attr(src); -} - -object obj_getitem(object x, object key) -{ - return x[key]; -} - -object obj_getitem3(object x) -{ - return x[3]; -} - -object obj_const_getitem(object const& x, object key) -{ - return x[key]; -} - -void obj_setitem(object x, object key, object value) -{ - x[key] = value; -} - -void obj_setitem42(object x, object key) -{ - x[key] = 42; -} - -void obj_moveitem(object& x, object src, object dst) -{ - x[dst] = x[src]; -} - -void obj_moveitem2(object const& x_src, object k_src, object& x_dst, object k_dst) -{ - x_dst[k_dst] = x_src[k_src]; -} - -bool test(object y) -{ - return y; -} - -bool test_not(object y) -{ - return !y; -} - -bool test_attr(object y, char* name) -{ - return y.attr(name); -} - -bool test_not_attr(object y, char* name) -{ - return !y.attr(name); -} - -bool test_item(object y, object key) -{ - return y[key]; -} - -bool test_not_item(object y, object key) -{ - return !y[key]; -} - -bool check_string_slice() -{ - object s("hello, world"); - - if (s.slice(_,-3) != "hello, wo") - return false; - - if (s.slice(-3,_) != "rld") - return false; - - if (", " != s.slice(5,7)) - return false; - - return s.slice(2,-1).slice(1,-1) == "lo, wor"; -} - -bool check_binary_operators() -{ - int y; - - object x(3); - -#define TEST_BINARY(op) \ - for (y = 1; y < 6; ++y) \ - { \ - if ((x op y) != (3 op y)) \ - return false; \ - } \ - for (y = 1; y < 6; ++y) \ - { \ - if ((y op x) != (y op 3)) \ - return false; \ - } \ - for (y = 1; y < 6; ++y) \ - { \ - object oy(y); \ - if ((oy op x) != (oy op 3)) \ - return false; \ - } - TEST_BINARY(>) - TEST_BINARY(>=) - TEST_BINARY(<) - TEST_BINARY(<=) - TEST_BINARY(==) - TEST_BINARY(!=) - - TEST_BINARY(+) - TEST_BINARY(-) - TEST_BINARY(*) - TEST_BINARY(/) - TEST_BINARY(%) - TEST_BINARY(<<) - TEST_BINARY(>>) - TEST_BINARY(&) - TEST_BINARY(^) - TEST_BINARY(|) - return true; -} - -bool check_inplace(object l, object o) -{ - int y; -#define TEST_INPLACE(op) \ - for (y = 1; y < 6; ++y) \ - { \ - object x(666); \ - x op##= y; \ - if (x != (666 op y)) \ - return false; \ - } \ - for (y = 1; y < 6; ++y) \ - { \ - object x(666); \ - x op##= object(y); \ - if (!(x == (666 op y))) \ - return false; \ - } - TEST_INPLACE(+) - TEST_INPLACE(-) - TEST_INPLACE(*) - TEST_INPLACE(/) - TEST_INPLACE(%) - TEST_INPLACE(<<) - TEST_INPLACE(>>) - TEST_INPLACE(&) - TEST_INPLACE(^) - TEST_INPLACE(|) - - l += l; - for (y = 0; y < 6; ++y) - { - if (l[y] != y % 3) - return false; - } - -#define TEST_ITEM_INPLACE(index, op, n, r1, r2) \ - l[index] op##= n; \ - if (l[index] != r1) \ - return false; \ - l[index] op##= object(n); \ - if (!(l[index] == r2)) \ - return false; - - TEST_ITEM_INPLACE(0,+,7,7,14) - TEST_ITEM_INPLACE(1,-,2,-1,-3) - TEST_ITEM_INPLACE(2,*,3,6,18) - TEST_ITEM_INPLACE(2,/,2,9,4) - TEST_ITEM_INPLACE(0,%,4,2,2) - l[0] += 1; - TEST_ITEM_INPLACE(0,<<,2,12,48) - TEST_ITEM_INPLACE(0,>>,1,24,12) - l[4] = 15; - TEST_ITEM_INPLACE(4,&,(16+4+1),5,5) - TEST_ITEM_INPLACE(0,^,1,13,12) - TEST_ITEM_INPLACE(0,|,1,13,13) - - o.attr("x0") = 0; - o.attr("x1") = 1; - o.attr("x2") = 2; - o.attr("x3") = 0; - o.attr("x4") = 1; - -#define TEST_ATTR_INPLACE(index, op, n, r1, r2) \ - o.attr("x" #index) op##= n; \ - if (o.attr("x" #index) != r1) \ - return false; \ - o.attr("x" #index) op##= object(n); \ - if (o.attr("x" #index) != r2) \ - return false; - - TEST_ATTR_INPLACE(0,+,7,7,14) - TEST_ATTR_INPLACE(1,-,2,-1,-3) - TEST_ATTR_INPLACE(2,*,3,6,18) - TEST_ATTR_INPLACE(2,/,2,9,4) - TEST_ATTR_INPLACE(0,%,4,2,2) - o.attr("x0") += 1; - TEST_ATTR_INPLACE(0,<<,2,12,48) - TEST_ATTR_INPLACE(0,>>,1,24,12) - o.attr("x4") = 15; - TEST_ATTR_INPLACE(4,&,(16+4+1),5,5) - TEST_ATTR_INPLACE(0,^,1,13,12) - TEST_ATTR_INPLACE(0,|,1,13,13) - - if (l[0] != o.attr("x0")) - return false; - if (l[1] != o.attr("x1")) - return false; - if (l[2] != o.attr("x2")) - return false; - if (l[3] != o.attr("x3")) - return false; - if (l[4] != o.attr("x4")) - return false; - - // set item 5 to be a list, by calling l.__class__ - l[5] = l.attr("__class__")(); - // append an element - l[5].attr("append")(2); - // Check its value - if (l[5][0] != 2) - return false; - - return true; -} - -BOOST_PYTHON_MODULE(object_ext) -{ - def("call_object_3", call_object_3); - def("message", message); - def("number", number); - - def("obj_getattr", obj_getattr); - def("obj_const_getattr", obj_const_getattr); - def("obj_setattr", obj_setattr); - def("obj_setattr42", obj_setattr42); - def("obj_moveattr", obj_moveattr); - - - def("obj_getitem", obj_getitem); - def("obj_getitem3", obj_getitem); - def("obj_const_getitem", obj_const_getitem); - def("obj_setitem", obj_setitem); - def("obj_setitem42", obj_setitem42); - def("obj_moveitem", obj_moveitem); - def("obj_moveitem2", obj_moveitem2); - - def("test", test); - def("test_not", test_not); - - def("test_attr", test_attr); - def("test_not_attr", test_not_attr); - - def("test_item", test_item); - def("test_not_item", test_not_item); - - def("check_binary_operators", check_binary_operators); - def("check_inplace", check_inplace); - def("check_string_slice", check_string_slice); - ; -} - -#include "module_tail.cpp" diff --git a/test/object.py b/test/object.py deleted file mode 100644 index 02da5ce8..00000000 --- a/test/object.py +++ /dev/null @@ -1,126 +0,0 @@ -''' ->>> from object_ext import * ->>> def print1(x): -... print x ->>> call_object_3(print1) -3 ->>> message() -'hello, world!' ->>> number() -42 - ->>> test('hi') -1 ->>> test(None) -0 ->>> test_not('hi') -0 ->>> test_not(0) -1 - - Attributes - ->>> class X: pass -... ->>> x = X() - ->>> try: obj_getattr(x, 'foo') -... except AttributeError: pass -... else: print 'expected an exception' - ->>> obj_setattr(x, 'foo', 1) ->>> x.foo -1 ->>> obj_getattr(x, 'foo') -1 ->>> obj_const_getattr(x, 'foo') -1 ->>> obj_setattr42(x, 'foo') ->>> x.foo -42 ->>> obj_moveattr(x, 'foo', 'bar') ->>> x.bar -42 ->>> test_attr(x, 'foo') -1 ->>> test_not_attr(x, 'foo') -0 ->>> x.foo = None ->>> test_attr(x, 'foo') -0 ->>> test_not_attr(x, 'foo') -1 - - Items - ->>> d = {} ->>> obj_setitem(d, 'foo', 1) ->>> d['foo'] -1 ->>> obj_getitem(d, 'foo') -1 ->>> obj_const_getitem(d, 'foo') -1 ->>> obj_setitem42(d, 'foo') ->>> obj_getitem(d, 'foo') -42 ->>> d['foo'] -42 ->>> obj_moveitem(d, 'foo', 'bar') ->>> d['bar'] -42 ->>> obj_moveitem2(d, 'bar', d, 'baz') ->>> d['baz'] -42 ->>> test_item(d, 'foo') -1 ->>> test_not_item(d, 'foo') -0 ->>> d['foo'] = None ->>> test_item(d, 'foo') -0 ->>> test_not_item(d, 'foo') -1 - - Slices - ->>> assert check_string_slice() - - Operators - - ->>> assert check_binary_operators() - ->>> class X: pass -... ->>> assert check_inplace(range(3), X()) - - - Now make sure that object is actually managing reference counts - ->>> import weakref ->>> class Z: pass -... ->>> z = Z() ->>> def death(r): print 'death' -... ->>> r = weakref.ref(z, death) ->>> z.foo = 1 ->>> obj_getattr(z, 'foo') -1 ->>> del z -death -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/object_fail1.cpp b/test/object_fail1.cpp deleted file mode 100755 index 3b09e71d..00000000 --- a/test/object_fail1.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include - -int f(boost::python::object const& x) -{ - x._("hello") = 1; - return 0; -} diff --git a/test/object_manager.cpp b/test/object_manager.cpp deleted file mode 100755 index 44005aeb..00000000 --- a/test/object_manager.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include - -using namespace boost::python; -using namespace boost::python::converter; - -struct X {}; - -int main() -{ - BOOST_STATIC_ASSERT(is_object_manager >::value); - BOOST_STATIC_ASSERT(!is_object_manager::value); - BOOST_STATIC_ASSERT(!is_object_manager::value); - - BOOST_STATIC_ASSERT(is_reference_to_object_manager&>::value); - BOOST_STATIC_ASSERT(is_reference_to_object_manager const&>::value); - BOOST_STATIC_ASSERT(is_reference_to_object_manager volatile&>::value); - BOOST_STATIC_ASSERT(is_reference_to_object_manager const volatile&>::value); - - BOOST_STATIC_ASSERT(!is_reference_to_object_manager >::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); - - return 0; -} - diff --git a/test/operators.cpp b/test/operators.cpp deleted file mode 100755 index 9096cb68..00000000 --- a/test/operators.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include "test_class.hpp" -#if __GNUC__ != 2 -# include -#else -# include -#endif - -// Just use math.h here; trying to use std::pow() causes too much -// trouble for non-conforming compilers and libraries. -#include - -using namespace boost::python; - -struct X : test_class<> -{ - typedef test_class<> base_t; - - X(int x) : base_t(x) {} - X const operator+(X const& r) const { return X(value() + r.value()); } -}; - -X operator-(X const& l, X const& r) { return X(l.value() - r.value()); } -X operator-(int l, X const& r) { return X(l - r.value()); } -X operator-(X const& l, int r) { return X(l.value() - r); } - -X operator-(X const& x) { return X(-x.value()); } - -X& operator-=(X& l, X const& r) { l.set(l.value() - r.value()); return l; } - -bool operator<(X const& x, X const& y) { return x.value() < y.value(); } -bool operator<(X const& x, int y) { return x.value() < y; } -bool operator<(int x, X const& y) { return x < y.value(); } - -X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); } - -X pow(X x, int y) -{ - return X(int(pow(double(x.value()), double(y)))); -} - -X pow(X x, X y) -{ - return X(int(pow(double(x.value()), double(y.value())))); -} - -int pow(int x, X y) -{ - return int(pow(double(x), double(y.value()))); -} - -std::ostream& operator<<(std::ostream& s, X const& x) -{ - return s << x.value(); -} - -BOOST_PYTHON_MODULE(operators_ext) -{ - class_("X", init()) - .def("value", &X::value) - .def(self + self) - .def(self - self) - .def(self - int()) - .def(other() - self) - .def(-self) - .def(self < other()) - .def(self < self) - .def(1 < self) - .def(self -= self) - .def(abs(self)) - .def(str(self)) - - .def(pow(self,self)) - .def(pow(self,int())) - .def(pow(int(),self)) - ; - - class_ >("Z", init()) - .def(int_(self)) - .def(float_(self)) - .def(complex_(self)) - ; -} - -#include "module_tail.cpp" diff --git a/test/operators.py b/test/operators.py deleted file mode 100644 index b18d4d2d..00000000 --- a/test/operators.py +++ /dev/null @@ -1,89 +0,0 @@ -''' ->>> from operators_ext import * ->>> x = X(42) ->>> x.value() -42 ->>> y = x - X(5) ->>> y.value() -37 ->>> y = x - 4 ->>> y.value() -38 ->>> y = 3 - x ->>> y.value() --39 ->>> (-y).value() -39 - ->>> (x + y).value() -3 - ->>> abs(y).value() -39 - ->>> x < 10 -0 ->>> x < 43 -1 - ->>> 10 < x -1 ->>> 43 < x -0 - ->>> x < y -0 ->>> y < x -1 - - ------ ->>> x > 10 -1 ->>> x > 43 -0 - ->>> 10 > x -0 ->>> 43 > x -1 - ->>> x > y -1 ->>> y > x -0 - ->>> y = x - 5 ->>> x -= y ->>> x.value() -5 ->>> str(x) -'5' - ->>> z = Z(10) ->>> int(z) -10 ->>> float(z) -10.0 ->>> complex(z) -(10+0j) - ->>> pow(2,x) -32 ->>> pow(x,2).value() -25 ->>> pow(X(2),x).value() -32 -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/pickle1.cpp b/test/pickle1.cpp deleted file mode 100644 index 794799f8..00000000 --- a/test/pickle1.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below can be fully restored by passing the - appropriate argument to the constructor. Therefore it is sufficient - to define the pickle interface method __getinitargs__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include -#include -#include -#include - -#include - -namespace { - - // A friendly class. - class world - { - private: - std::string country; - public: - world(const std::string& country) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - }; - - struct world_pickle_suite : boost::python::pickle_suite - { - static - boost::python::tuple - getinitargs(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_country()); - } - }; - -} - -BOOST_PYTHON_MODULE(pickle1_ext) -{ - using namespace boost::python; - class_("world", init()) - .def("greet", &world::greet) - .def_pickle(world_pickle_suite()) - ; -} diff --git a/test/pickle1.py b/test/pickle1.py deleted file mode 100644 index d333919d..00000000 --- a/test/pickle1.py +++ /dev/null @@ -1,31 +0,0 @@ -r'''>>> import pickle1_ext - >>> import pickle - >>> pickle1_ext.world.__module__ - 'pickle1_ext' - >>> pickle1_ext.world.__safe_for_unpickling__ - 1 - >>> pickle1_ext.world.__name__ - 'world' - >>> pickle1_ext.world('Hello').__reduce__() - (, ('Hello',)) - >>> wd = pickle1_ext.world('California') - >>> pstr = pickle.dumps(wd) - >>> wl = pickle.loads(pstr) - >>> print wd.greet() - Hello from California! - >>> print wl.greet() - Hello from California! -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/pickle2.cpp b/test/pickle2.cpp deleted file mode 100644 index 99401973..00000000 --- a/test/pickle2.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - For simplicity, the __dict__ is not included in the result of - __getstate__. This is not generally recommended, but a valid - approach if it is anticipated that the object's __dict__ will - always be empty. Note that safety guards are provided to catch - the cases where this assumption is not true. - - pickle3.cpp shows how to include the object's __dict__ in the - result of __getstate__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -#include -#include -#include -#include -#include - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - struct world_pickle_suite : boost::python::pickle_suite - { - static - boost::python::tuple - getinitargs(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_country()); - } - - static - boost::python::tuple - getstate(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_secret_number()); - } - - static - void - setstate(world& w, boost::python::tuple state) - { - using namespace boost::python; - if (len(state) != 1) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 1-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - long number = extract(state[0]); - if (number != 42) - w.set_secret_number(number); - } - }; - -} - -BOOST_PYTHON_MODULE(pickle2_ext) -{ - boost::python::class_( - "world", boost::python::init()) - .def("greet", &world::greet) - .def("get_secret_number", &world::get_secret_number) - .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_suite()) - ; -} diff --git a/test/pickle2.py b/test/pickle2.py deleted file mode 100644 index ec141bc9..00000000 --- a/test/pickle2.py +++ /dev/null @@ -1,45 +0,0 @@ -r'''>>> import pickle2_ext - >>> import pickle - >>> pickle2_ext.world.__module__ - 'pickle2_ext' - >>> pickle2_ext.world.__safe_for_unpickling__ - 1 - >>> pickle2_ext.world.__name__ - 'world' - >>> pickle2_ext.world('Hello').__reduce__() - (, ('Hello',), (0,)) - >>> for number in (24, 42): - ... wd = pickle2_ext.world('California') - ... wd.set_secret_number(number) - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number() - ... print wl.greet(), wl.get_secret_number() - Hello from California! 24 - Hello from California! 24 - Hello from California! 42 - Hello from California! 0 - -# Now show that the __dict__ is not taken care of. - >>> wd = pickle2_ext.world('California') - >>> wd.x = 1 - >>> wd.__dict__ - {'x': 1} - >>> try: pstr = pickle.dumps(wd) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__getstate_manages_dict__ not set) -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/pickle3.cpp b/test/pickle3.cpp deleted file mode 100644 index 8f243d39..00000000 --- a/test/pickle3.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - The object's __dict__ is included in the result of __getstate__. - This requires more code (compare with pickle2.cpp), but is - unavoidable if the object's __dict__ is not always empty. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - struct world_pickle_suite : boost::python::pickle_suite - { - static - boost::python::tuple - getinitargs(const world& w) - { - using namespace boost::python; - return make_tuple(w.get_country()); - } - - static - boost::python::tuple - getstate(boost::python::object w_obj) - { - using namespace boost::python; - world const& w = extract(w_obj)(); - - return make_tuple(w_obj.attr("__dict__"), w.get_secret_number()); - } - - static - void - setstate(boost::python::object w_obj, boost::python::tuple state) - { - using namespace boost::python; - world& w = extract(w_obj)(); - - if (len(state) != 2) - { - PyErr_SetObject(PyExc_ValueError, - ("expected 2-item tuple in call to __setstate__; got %s" - % state).ptr() - ); - throw_error_already_set(); - } - - // restore the object's __dict__ - dict d = extract(w_obj.attr("__dict__"))(); - d.update(state[0]); - - // restore the internal state of the C++ object - long number = extract(state[1]); - if (number != 42) - w.set_secret_number(number); - } - - static bool getstate_manages_dict() { return true; } - }; - -} - -BOOST_PYTHON_MODULE(pickle3_ext) -{ - boost::python::class_( - "world", boost::python::init()) - .def("greet", &world::greet) - .def("get_secret_number", &world::get_secret_number) - .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_suite()) - ; -} diff --git a/test/pickle3.py b/test/pickle3.py deleted file mode 100644 index b700c1b0..00000000 --- a/test/pickle3.py +++ /dev/null @@ -1,40 +0,0 @@ -r'''>>> import pickle3_ext - >>> import pickle - >>> pickle3_ext.world.__module__ - 'pickle3_ext' - >>> pickle3_ext.world.__safe_for_unpickling__ - 1 - >>> pickle3_ext.world.__getstate_manages_dict__ - 1 - >>> pickle3_ext.world.__name__ - 'world' - >>> pickle3_ext.world('Hello').__reduce__() - (, ('Hello',), ({}, 0)) - >>> for number in (24, 42): - ... wd = pickle3_ext.world('California') - ... wd.set_secret_number(number) - ... wd.x = 2 * number - ... wd.y = 'y' * number - ... wd.z = 3. * number - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z - ... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z - Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 - Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 - Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 - Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/pointee.cpp b/test/pointee.cpp deleted file mode 100644 index 44836b05..00000000 --- a/test/pointee.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include - -struct A; - -int main() -{ - BOOST_STATIC_ASSERT( - (boost::is_same< - boost::python::pointee >::type - , char** - >::value)); - - BOOST_STATIC_ASSERT( - (boost::is_same< - boost::python::pointee >::type - , A>::value)); - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - BOOST_STATIC_ASSERT( - (boost::is_same< - boost::python::pointee::type - , char - >::value)); -#endif - return 0; -} diff --git a/test/pointer_type_id_test.cpp b/test/pointer_type_id_test.cpp deleted file mode 100644 index e3314e0b..00000000 --- a/test/pointer_type_id_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include - -int main() -{ - using namespace boost::python::converter; - - boost::python::type_info x - = boost::python::type_id(); - - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - assert(pointer_type_id() == x); - - return 0; -} diff --git a/test/polymorphism.cpp b/test/polymorphism.cpp deleted file mode 100644 index 02ec7b57..00000000 --- a/test/polymorphism.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -struct Callback -{ - Callback(PyObject* o) : mSelf(o) {} - PyObject* mSelf; -}; - -struct A -{ - virtual ~A(){} - virtual std::string f() { return "A::f()"; } -}; - -struct ACallback : A, Callback -{ - ACallback (PyObject* self) : Callback(self) {} - - - std::string f() - { - return call_method(mSelf, "f"); - } - - std::string default_f() - { - return A::f(); - } -}; - -struct B : A -{ - virtual std::string f() { return "B::f()"; } -}; - -struct C : A -{ - virtual std::string f() { return "C::f()"; } -}; - -A& getBCppObj () -{ - static B b; - return b; -} - -std::string call_f(A& a) { return a.f(); } - -A* factory(unsigned choice) -{ - switch (choice % 3) - { - case 0: return new A; - break; - case 1: return new B; - break; - default: return new C; - break; - } -} - -C& getCCppObj () -{ - static C c; - return c; -} - -BOOST_PYTHON_MODULE_INIT(polymorphism_ext) -{ - class_("A") - .def("f", &A::f, &ACallback::default_f) - ; - - def("getBCppObj", getBCppObj, return_value_policy()); - - class_,boost::noncopyable>("C") - .def("f", &C::f) - ; - - def("getCCppObj", getCCppObj, return_value_policy()); - - def("factory", factory, return_value_policy()); - - def("call_f", call_f); -} - -//#include "module_tail.cpp" diff --git a/test/polymorphism.py b/test/polymorphism.py deleted file mode 100644 index a305bbea..00000000 --- a/test/polymorphism.py +++ /dev/null @@ -1,52 +0,0 @@ -import unittest -from polymorphism_ext import * - -class PolymorphTest(unittest.TestCase): - - def testReturnCpp(self): - - # Python Created Object With Same Id As - # Cpp Created B Object - # b = B(872) - - # Get Reference To Cpp Created B Object - a = getBCppObj() - - # Python Created B Object and Cpp B Object - # Should have same result by calling f() - self.failUnlessEqual ('B::f()', a.f()) - self.failUnlessEqual ('B::f()', call_f(a)) - self.failUnlessEqual ('A::f()', call_f(A())) - - def test_references(self): - # B is not exposed to Python - a = getBCppObj() - self.failUnlessEqual(type(a), A) - - # C is exposed to Python - c = getCCppObj() - self.failUnlessEqual(type(c), C) - - def test_factory(self): - self.failUnlessEqual(type(factory(0)), A) - self.failUnlessEqual(type(factory(1)), A) - self.failUnlessEqual(type(factory(2)), C) - - def testReturnPy(self): - - class D(A): - def f(self): - return 'D.f' - - d = D() - - self.failUnlessEqual ('D.f', d.f()) - self.failUnlessEqual ('D.f', call_f(d)) - -if __name__ == "__main__": - - # remove the option which upsets unittest - import sys - sys.argv = [ x for x in sys.argv if x != '--broken-auto-ptr' ] - - unittest.main() diff --git a/test/raw_pyobject_fail1.cpp b/test/raw_pyobject_fail1.cpp deleted file mode 100755 index 8fe73d68..00000000 --- a/test/raw_pyobject_fail1.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include - -int main() -{ - boost::python::converter::arg_to_python x(0); - return 0; -} diff --git a/test/raw_pyobject_fail2.cpp b/test/raw_pyobject_fail2.cpp deleted file mode 100755 index 7a0e79d9..00000000 --- a/test/raw_pyobject_fail2.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include - -struct X : PyObject {}; - -int main() -{ - boost::python::converter::arg_to_python x(0); - return 0; -} diff --git a/test/result.cpp b/test/result.cpp deleted file mode 100755 index 19b1cf41..00000000 --- a/test/result.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -using boost::python::detail::result; -using boost::type; - -void expect_int(type*) {} -void expect_string(type*) {} - -struct X {}; - -int main() -{ - // Test the usage which works for functions, member functions, and data members - expect_int( - result((int(*)())0) - ); - - expect_int( - result((int(*)(char))0) - ); - - expect_int( - result((int(X::*)())0) - ); - - expect_int( - result((int(X::*)(char))0) - ); - - expect_int( - result((int(X::*))0) - ); - - expect_string( - result((char*(*)())0) - ); - - expect_string( - result((char*(*)(char))0) - ); - - expect_string( - result((char*(X::*)())0) - ); - - expect_string( - result((char*(X::*)(char))0) - ); - - expect_string( - result((char*(X::*))0) - ); - - // Show that we can use the general version that works for - // AdaptableFunctions - expect_int( - result((int(*)())0,0) - ); - - expect_int( - result((int(*)(char))0,0) - ); - - expect_int( - result((int(X::*)())0,0) - ); - - expect_int( - result((int(X::*)(char))0,0) - ); - - expect_int( - result((int(X::*))0,0) - ); - - expect_int( - result(std::plus(),0) - ); - - expect_string( - result((char*(*)())0,0) - ); - - expect_string( - result((char*(*)(char))0,0) - ); - - expect_string( - result((char*(X::*)())0,0) - ); - - expect_string( - result((char*(X::*)(char))0,0) - ); - - expect_string( - result((char*(X::*))0,0) - ); - - expect_string( - result(std::plus(),0) - ); - - return 0; -} diff --git a/test/select_arg_to_python_test.cpp b/test/select_arg_to_python_test.cpp deleted file mode 100644 index df925a54..00000000 --- a/test/select_arg_to_python_test.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include -#include - -// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition -#if ((defined(__GNUC__) && __GNUC__ < 3)) \ - || (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) -namespace boost { namespace python { -BOOST_PYTHON_DECL bool handle_exception_impl(function0) -{ - return true; -} -}} -#endif - -int result; - -#define ASSERT_SAME(T1,T2) \ - if (!is_same< T1, T2 >::value) { \ - std::cout << "*********************\n"; \ - std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \ - std::cout << "*********************\n"; \ - result = 1; \ - } - -int main() -{ - using namespace boost::python::converter::detail; - using namespace boost::python::converter; - using namespace boost::python; - using namespace boost; - - - ASSERT_SAME( - select_arg_to_python::type, value_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python >::type, reference_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python >::type, pointer_shallow_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python::type, pointer_deep_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python >::type, object_manager_arg_to_python > - ); - - ASSERT_SAME( - select_arg_to_python::type, object_manager_arg_to_python - ); - - ASSERT_SAME( - select_arg_to_python::type, arg_to_python - ); - - return result; -} diff --git a/test/select_from_python_test.cpp b/test/select_from_python_test.cpp deleted file mode 100644 index 34018781..00000000 --- a/test/select_from_python_test.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include -#include -#include - -// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition -#if ((defined(__GNUC__) && __GNUC__ < 3)) \ - || (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) -namespace boost { namespace python { -BOOST_PYTHON_DECL bool handle_exception_impl(function0) -{ - return true; -} -}} -#endif - -int result; - -#define ASSERT_SAME(T1,T2) \ - if (!is_same< T1, T2 >::value) { \ - std::cout << "*********************\n"; \ - std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \ - std::cout << "*********************\n"; \ - result = 1; \ - } - -int main() -{ - using namespace boost::python::converter; - using namespace boost; - - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_arg_from_python - ); - - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, arg_rvalue_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, pointer_cref_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - - ASSERT_SAME( - select_arg_from_python::type, reference_arg_from_python - ); - return result; -} diff --git a/test/select_holder.cpp b/test/select_holder.cpp deleted file mode 100644 index c373af0a..00000000 --- a/test/select_holder.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include - -#define BOOST_INCLUDE_MAIN -#include - -struct BR {}; - -struct Base {}; -struct Derived : Base {}; - -namespace boost { namespace python -{ - // specialization - template <> - struct has_back_reference
- { - BOOST_STATIC_CONSTANT(bool, value = true); - }; -}} // namespace boost::python - -template -void assert_same(U* = 0, T* = 0) -{ - BOOST_TEST((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - -} - -template -void assert_holder(T* = 0, Held* = 0, Holder* = 0) -{ - assert_same( -#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - boost::python::objects::select_holder::execute((Held*)0).get() -#else - boost::python::objects::select_holder::type::get() -#endif - ); -} - -int test_main(int, char * []) -{ - using namespace boost::python::detail; - using namespace boost::python::objects; - - assert_holder >(); - - assert_holder >(); - assert_holder >(); - assert_holder >(); - - assert_holder >(); - - assert_holder - ,pointer_holder,Base> >(); - - assert_holder - ,pointer_holder_back_reference,Base> >(); - - assert_holder - ,pointer_holder_back_reference,BR> > (); - - return 0; -} - -#if !defined(_WIN32) || defined(__GNUC__) -// This definition is needed for MinGW 2.95.2 and KCC on OSF for some -// reason, but will break other Win32 compilers. -namespace boost { namespace python -{ - bool handle_exception_impl(boost::function0) { return false; } -}} -#endif diff --git a/test/shared_ptr.cpp b/test/shared_ptr.cpp deleted file mode 100644 index 39da8652..00000000 --- a/test/shared_ptr.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include -#include "test_class.hpp" - -#include - -using namespace boost::python; -using boost::shared_ptr; - -typedef test_class<> X; -typedef test_class<1> Y; - -template -struct functions -{ - static int look(shared_ptr const& x) - { - return (x.get()) ? x->value() : -1; - } - - static void store(shared_ptr x) - { - storage = x; - } - - static void release_store() - { - store(shared_ptr()); - } - - static void modify(shared_ptr& x) - { - x.reset(); - } - - static shared_ptr get() { return storage; } - - static int look_store() - { - return look(get()); - } - - static void expose() - { - def("look", &look); - def("store", &store); - def("modify", &modify); - def("look_store", &look_store); - } - - static shared_ptr storage; -}; - -template shared_ptr functions::storage; - -struct Z : test_class<2> -{ - Z(int x) : test_class<2>(x) {} - virtual int v() { return this->value(); } -}; - -struct ZWrap : Z -{ - ZWrap(PyObject* self, int x) - : Z(x), m_self(self) {} - - - virtual int v() { return call_method(m_self, "v"); } - int default_v() { return Z::v(); } - - - PyObject* m_self; -}; - -struct YY : Y -{ - YY(int n) : Y(n) {} -}; - -shared_ptr factory(int n) -{ - return shared_ptr(n < 42 ? new Y(n) : new YY(n)); -} - -static int stored_v() { return functions::get()->v(); } -static shared_ptr stored_z() { return functions::get(); } - -BOOST_PYTHON_MODULE(shared_ptr_ext) -{ - class_("X", init()) - .def("value", &X::value) - ; - - def("factory", factory); - - functions::expose(); - def("x_count", &X::count); - def("x_release", &functions::release_store); - def("x_look_store", &functions::look_store); - - class_ >("Y", init()) - .def("value", &Y::value) - ; - - class_, boost::noncopyable>("YY", init()) - ; - - functions::expose(); - def("y_count", &Y::count); - def("y_release", &functions::release_store); - def("y_look_store", &functions::look_store); - - class_("Z", init()) - .def("value", &Z::value) - .def("v", &Z::v, &ZWrap::default_v) - ; - - functions::expose(); - def("z_count", &Z::count); - def("z_release", &functions::release_store); - def("z_look_store", &functions::look_store); - def("stored_z", &stored_z); - def("stored_v", &stored_v); -} - -#include "module_tail.cpp" - diff --git a/test/shared_ptr.py b/test/shared_ptr.py deleted file mode 100644 index e86da6df..00000000 --- a/test/shared_ptr.py +++ /dev/null @@ -1,109 +0,0 @@ -''' ->>> from shared_ptr_ext import * - ->>> type(factory(3)) - ->>> type(factory(42)) - - ->>> class P(Z): -... def v(self): -... return -Z.v(self); -... def __del__(self): -... print 'bye' -... ->>> p = P(12) ->>> p.value() -12 ->>> p.v() --12 ->>> look(p) -12 ->>> try: modify(p) -... except TypeError: pass -... else: 'print expected a TypeError' ->>> look(None) --1 ->>> store(p) ->>> del p ->>> stored_v() --12 ->>> z_count() -1 ->>> z_look_store() -12 ->>> z_release() -bye ->>> z_count() -0 - ->>> z = Z(13) ->>> z.value() -13 ->>> z.v() -13 ->>> try: modify(z) -... except TypeError: pass -... else: 'print expected a TypeError' ->>> store(z) ->>> assert stored_z() is z # show that deleter introspection works ->>> del z ->>> stored_v() -13 ->>> z_count() -1 ->>> z_look_store() -13 ->>> z_release() ->>> z_count() -0 - ->>> x = X(17) ->>> x.value() -17 ->>> look(x) -17 ->>> try: modify(x) -... except TypeError: pass -... else: 'print expected a TypeError' ->>> look(None) --1 ->>> store(x) ->>> del x ->>> x_count() -1 ->>> x_look_store() -17 ->>> x_release() ->>> x_count() -0 - - ->>> y = Y(19) ->>> y.value() -19 ->>> modify(y) ->>> look(y) --1 ->>> store(Y(23)) ->>> y_count() -1 ->>> y_look_store() -23 ->>> y_release() ->>> y_count() -0 -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/simple_type.hpp b/test/simple_type.hpp deleted file mode 100644 index 2df97cfd..00000000 --- a/test/simple_type.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SIMPLE_TYPE_DWA2001128_HPP -# define SIMPLE_TYPE_DWA2001128_HPP - -struct simple -{ - char* s; -}; - -#endif // SIMPLE_TYPE_DWA2001128_HPP diff --git a/test/staticmethod.cpp b/test/staticmethod.cpp deleted file mode 100644 index a62f6275..00000000 --- a/test/staticmethod.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; -int X::counter; -int getXmagic(){return 7654321;} - -BOOST_PYTHON_MODULE(staticmethod_ext) -{ - class_("X", init()) - .def("value", &X::value) - .def("set", &X::set) - .def("count", &X::count) - .staticmethod("count") - .def("magic", &getXmagic) - .staticmethod("magic") - ; -} - -#include "module_tail.cpp" diff --git a/test/staticmethod.py b/test/staticmethod.py deleted file mode 100644 index 7fcaae60..00000000 --- a/test/staticmethod.py +++ /dev/null @@ -1,52 +0,0 @@ -''' ->>> from staticmethod_ext import * - ->>> class X1(X): -... pass - - ->>> x = X(16) ->>> x1 = X1(17) - - - ->>> x1.count() -2 - ->>> x.count() -2 - ->>> X1.count() -2 - ->>> X.count() -2 - - ->>> x1.magic() -7654321 - ->>> x.magic() -7654321 - ->>> X1.magic() -7654321 - ->>> X.magic() -7654321 - - -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/str.cpp b/test/str.cpp deleted file mode 100644 index e0252a17..00000000 --- a/test/str.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include - -using namespace boost::python; - -object convert_to_string(object data) -{ - return str(data); -} - -void work_with_string(object print) -{ - str data("this is a demo string"); - print(data.split(" ")); - print(data.split(" ",3)); - print(str("<->").join(data.split(" "))); - print(data.capitalize()); - print('[' + data.center(30) + ']'); - print(data.count("t")); - print(data.encode("utf-8")); - print(data.decode("utf-8")); - print(data.endswith("xx")); - print(data.startswith("test")); - print(data.splitlines()); - print(data.strip()); - print(data.swapcase()); - print(data.title()); - - print("find"); - print(data.find("demo")); - print(data.find("demo"),3,5); - print(data.find(std::string("demo"))); - print(data.find(std::string("demo"),9)); - - print("expandtabs"); - str tabstr("\t\ttab\tdemo\t!"); - print(tabstr.expandtabs()); - print(tabstr.expandtabs(4)); - print(tabstr.expandtabs(7.9)); - - print("operators"); - print( str("part1") + str("part2") ); -// print( str("a test string").slice(3,_) ); -// print( str("another test")[5] ); - - print(data.replace("demo",std::string("blabla"))); - print(data.rfind("i",5)); - print(data.rindex("i",5)); - print(data.startswith("asdf")); - print(data.endswith("asdf")); - print(data.translate(str('a')*256)); - - - bool tmp = data.isalnum() || data.isalpha() || data.isdigit() || data.islower() || - data.isspace() || data.istitle() || data.isupper(); - (void)tmp; // ignored. -} - - -BOOST_PYTHON_MODULE(str_ext) -{ - def("convert_to_string",convert_to_string); - def("work_with_string",work_with_string); -} - diff --git a/test/str.py b/test/str.py deleted file mode 100644 index 666096b1..00000000 --- a/test/str.py +++ /dev/null @@ -1,52 +0,0 @@ -""" ->>> from str_ext import * ->>> def printer(*args): -... for x in args: print x, -... print -... ->>> work_with_string(printer) -['this', 'is', 'a', 'demo', 'string'] -['this', 'is', 'a', 'demo string'] -this<->is<->a<->demo<->string -This is a demo string -[ this is a demo string ] -2 -this is a demo string -this is a demo string -0 -0 -['this is a demo string'] -this is a demo string -THIS IS A DEMO STRING -This Is A Demo String -find -10 -10 3 5 -10 -10 -expandtabs - tab demo ! - tab demo ! - tab demo ! -operators -part1part2 -this is a blabla string -18 -18 -0 -0 -aaaaaaaaaaaaaaaaaaaaa -""" - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/string_literal.cpp b/test/string_literal.cpp deleted file mode 100644 index 882fbd4e..00000000 --- a/test/string_literal.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//#include -#include -#include -#include - -using namespace boost::python::detail; - - -template -void expect_string_literal(T const&) -{ - BOOST_STATIC_ASSERT(is_string_literal::value); -} - -int main() -{ - expect_string_literal("hello"); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(is_string_literal::value); - BOOST_STATIC_ASSERT(is_string_literal::value); - - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - BOOST_STATIC_ASSERT(!is_string_literal::value); - return 0; -} diff --git a/test/submod_subclass_api.cpp b/test/submod_subclass_api.cpp deleted file mode 100644 index e716aaf0..00000000 --- a/test/submod_subclass_api.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright David Hawkes 2002. -// Permission is hereby granted to copy, use and modify this software -// for any purpose, including commercial distribution, provided this -// copyright notice is not removed. No warranty WHATSOEVER is provided with this -// software. Any user(s) accepts this software "as is" and as such they will not -// bind the author(s) to any claim of suitabilty for any purpose. - -// embed_test.cpp : substantial test of embedding python in c++ using boost - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost; -using namespace boost::python; - - -// The following macros are for our convenience and coding expediency... -// There is no particular recomendation that they be used elsewhere -// as they are not feature complete and are just sufficient to suport -// the code here - - -#define DEF(fn) def(#fn, fn) -#define DEF_C(c, fn) def(#fn, &c::fn) -#define DEF_C_CB(c, fn) def(#fn, &c##_callback::base_##fn) - -#define CLASS(c) class_ >(#c) -#define CLASS_CB(c) class_, noncopyable >(#c) - -#define START_CALLBACK_CLASS(c) \ -class c##_callback : public c \ -{ \ - typedef c __base__; \ -public: \ - c##_callback(PyObject* self) : m_self(self) {} \ -private: \ - PyObject* m_self; \ -public: - -#define END_CALLBACK_CLASS }; - - -#define CALLBACK_MEMBER0(fn, rtn) \ -rtn fn() { return call_method(m_self, #fn); } \ -rtn base_##fn() { return __base__::fn(); } - - -#define CALLBACK_MEMBER0C(fn, rtn) \ -rtn fn() const { return call_method(m_self, #fn); } \ -rtn base_##fn() const { return __base__::fn(); } -// End of convenience macros - -// useful support classes -template -struct class_object : public object -{ - typedef object base; - class_object() : m_class_ptr(NULL) {} - class_object(object const& o) : base(o) { init(); } - class_object& operator=(object const& o) - { - base::operator=(o); - init(); - return *this; - } - T* operator->() const { return m_class_ptr; } - T& operator*() const { return *m_class_ptr; } -private: - void init() - { - m_class_ptr = arg_from_python(ptr())(ptr()); - } - T* m_class_ptr; -}; - -template -struct item_object : public object -{ - typedef object base; - item_object() {} - item_object(object const& o) : base(o), m_class(arg_from_python(ptr())(ptr())) {} - item_object& operator=(object const& o) - { - base::operator=(o); - init(); - return *this; - } - operator T() { return m_class; } -private: - void init() - { - m_class = arg_from_python(ptr())(ptr()); - } - T m_class; -}; -// end of useful support classes - -// pass our args in this struct -struct main_args { - main_args(int _argc, char* _argv[]) : argc(_argc), argv(_argv) {} - int argc; - char** argv; -}; -int python_main(main_args const &ma); - -// python module init -BOOST_PYTHON_MODULE(python_main) -{ - DEF(python_main); - CLASS(main_args); -} - -// sub module tests -namespace sm { - -int test_func() { return 7; } - -BOOST_PYTHON_MODULE(sm_test) -{ - // define a submodule - boost::python::module(".sm"); - // define a 2nd submodule - boost::python::module(".sm.sm2"); - // define a test function to appear in 2nd submodule - DEF(test_func); -} - -// sub-module tests -int test() -{ - api::run_simple_string("import sm_test"); - if(api::call_statement("_0 = bpl_test('sub modules', sm_test.sm.sm2.test_func, _1)", test_func())) - return 1; - return 0; -} - -} - -// sub class tests -namespace sc { - -class c1 { -public: - c1() {} - class c2 { - public: - c2() : n(2) {} - int n; - }; - c2 t; -}; - -c1::c2 test_func() { - return c1().t; -} - -BOOST_PYTHON_MODULE(sc_test) -{ - class_("c1.c2") - .def_init() - .def_readwrite("n", &c1::c2::n); - CLASS(c1) - .def_init() - .def_readwrite("t", &c1::t); - DEF(test_func); -} - -// sub-class tests -int test() -{ - api::run_simple_string("import sc_test"); - if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1.c2().n, _1.n)", test_func())) - return 1; - if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1().t.n, _1.n)", test_func())) - return 1; - return 0; -} - -} - -// new main that will have a python execution frame -int main(int argc, char* argv[]) -{ - // default return value; - int rtn = 0; - // define all the built-in modules used - PyImport_AppendInittab("python_main", initpython_main); - PyImport_AppendInittab("sm_test", sm::initsm_test); - PyImport_AppendInittab("sc_test", sc::initsc_test); - // initialize python - Py_Initialize(); - // start a new block so that any objects are released prior to finalizing - { - // import our main module - this will also initialise boost - api::run_simple_string("import python_main"); - // We call back here so we have a proper python execution frame to work with - item_object o_rtn(api::call_statement("_0 = python_main.python_main(_1)", main_args(argc, argv))); - rtn = o_rtn; - } - // clean up - Py_Finalize(); - return rtn; -} - -char *bpl_test = -"def bpl_test(name, func, result):\n" -" print 'testing %s...' % name\n" -" if func() != result:\n" -" print 'failed'\n" -" return 1\n" -" else:\n" -" print 'OK'\n" -" return 0\n"; - - -int python_main(main_args const &ma) -{ - api::print("running...\n"); - api::call_statement(bpl_test); - if(sm::test()) - return 1; - if(sc::test()) - return 1; - return 0; -} diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp deleted file mode 100644 index 4f08c534..00000000 --- a/test/test_builtin_converters.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include -#include -#include - -template -struct by_value -{ - static T rewrap(T x) - { - return x; - } -}; - -template -struct by_const_reference -{ - static T rewrap(T const& x) - { - return x; - } -}; - -template -struct by_reference -{ - static T rewrap(T& x) - { - return x; - } -}; - -using boost::python::def; -using boost::python::handle; -using boost::python::object; -using boost::python::borrowed; - -// Used to test that arbitrary handle<>s can be returned -handle get_type(handle<> x) -{ - return handle(borrowed(x->ob_type)); -} - -handle<> return_null_handle() -{ - return handle<>(); -} - -char const* rewrap_value_mutable_cstring(char* x) { return x; } - -BOOST_PYTHON_MODULE(builtin_converters) -{ - def("get_type", get_type); - def("return_null_handle", return_null_handle); - - def("rewrap_value_bool", by_value::rewrap); - def("rewrap_value_char", by_value::rewrap); - def("rewrap_value_signed_char", by_value::rewrap); - def("rewrap_value_unsigned_char", by_value::rewrap); - def("rewrap_value_int", by_value::rewrap); - def("rewrap_value_unsigned_int", by_value::rewrap); - def("rewrap_value_short", by_value::rewrap); - def("rewrap_value_unsigned_short", by_value::rewrap); - def("rewrap_value_long", by_value::rewrap); - def("rewrap_value_unsigned_long", by_value::rewrap); -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -#ifdef HAVE_LONG_LONG - def("rewrap_value_long_long", by_value::rewrap); - def("rewrap_value_unsigned_long_long", by_value::rewrap); -# endif - def("rewrap_value_float", by_value::rewrap); - def("rewrap_value_double", by_value::rewrap); - def("rewrap_value_long_double", by_value::rewrap); - def("rewrap_value_complex_float", by_value >::rewrap); - def("rewrap_value_complex_double", by_value >::rewrap); - def("rewrap_value_complex_long_double", by_value >::rewrap); - def("rewrap_value_string", by_value::rewrap); - def("rewrap_value_cstring", by_value::rewrap); - def("rewrap_value_handle", by_value >::rewrap); - def("rewrap_value_object", by_value::rewrap); - - // Expose this to illustrate our failings ;-). See test_builtin_converters.py - def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring); - - - def("rewrap_const_reference_bool", by_const_reference::rewrap); - def("rewrap_const_reference_char", by_const_reference::rewrap); - def("rewrap_const_reference_signed_char", by_const_reference::rewrap); - def("rewrap_const_reference_unsigned_char", by_const_reference::rewrap); - def("rewrap_const_reference_int", by_const_reference::rewrap); - def("rewrap_const_reference_unsigned_int", by_const_reference::rewrap); - def("rewrap_const_reference_short", by_const_reference::rewrap); - def("rewrap_const_reference_unsigned_short", by_const_reference::rewrap); - def("rewrap_const_reference_long", by_const_reference::rewrap); - def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap); -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. -# ifdef HAVE_LONG_LONG - def("rewrap_const_reference_long_long", by_const_reference::rewrap); - def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap); -# endif - def("rewrap_const_reference_float", by_const_reference::rewrap); - def("rewrap_const_reference_double", by_const_reference::rewrap); - def("rewrap_const_reference_long_double", by_const_reference::rewrap); - def("rewrap_const_reference_complex_float", by_const_reference >::rewrap); - def("rewrap_const_reference_complex_double", by_const_reference >::rewrap); - def("rewrap_const_reference_complex_long_double", by_const_reference >::rewrap); - def("rewrap_const_reference_string", by_const_reference::rewrap); - def("rewrap_const_reference_cstring", by_const_reference::rewrap); - def("rewrap_const_reference_handle", by_const_reference >::rewrap); - def("rewrap_const_reference_object", by_const_reference::rewrap); - def("rewrap_reference_object", by_reference::rewrap); -} - diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py deleted file mode 100644 index 0b3bc645..00000000 --- a/test/test_builtin_converters.py +++ /dev/null @@ -1,238 +0,0 @@ -r""" ->>> from builtin_converters import * - -# Synthesize idendity functions in case long long not supported ->>> if not 'rewrap_value_long_long' in dir(): -... def rewrap_value_long_long(x): return long(x) -... def rewrap_value_unsigned_long_long(x): return long(x) -... def rewrap_const_reference_long_long(x): return long(x) -... def rewrap_const_reference_unsigned_long_long(x): return long(x) - ->>> rewrap_value_bool(None) -0 ->>> rewrap_value_bool(0) -0 ->>> rewrap_value_bool(33) -1 ->>> rewrap_value_char('x') -'x' - - Note that there's currently silent truncation of strings passed to - char arguments. - ->>> rewrap_value_char('xy') -'x' ->>> rewrap_value_signed_char(42) -42 ->>> rewrap_value_unsigned_char(42) -42 ->>> rewrap_value_int(42) -42 ->>> rewrap_value_unsigned_int(42) -42 ->>> rewrap_value_short(42) -42 ->>> rewrap_value_unsigned_short(42) -42 ->>> rewrap_value_long(42) -42 ->>> rewrap_value_unsigned_long(42) -42 - - test unsigned long values which don't fit in a signed long. - strip any 'L' characters in case the platform has > 32 bit longs - ->>> hex(rewrap_value_unsigned_long(0x80000001L)).replace('L','') -'0x80000001' - ->>> rewrap_value_long_long(42) -42L ->>> rewrap_value_unsigned_long_long(42) -42L - - show that we have range checking. - ->>> try: rewrap_value_unsigned_short(-42) -... except OverflowError: pass -... else: print 'expected an OverflowError!' - ->>> try: rewrap_value_int(sys.maxint * 2) -... except OverflowError: pass -... else: print 'expected an OverflowError!' - - ->>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001 ->>> rewrap_value_double(4.2) - 4.2 -0.0 ->>> rewrap_value_long_double(4.2) - 4.2 -0.0 - ->>> assert abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001 - ->>> rewrap_value_cstring('hello, world') -'hello, world' ->>> rewrap_value_string('yo, wassup?') -'yo, wassup?' - - wrap strings with embedded nulls: - ->>> rewrap_value_string('yo,\0wassup?') -'yo,\x00wassup?' - ->>> rewrap_value_handle(1) -1 ->>> x = 'hi' ->>> assert rewrap_value_handle(x) is x ->>> assert rewrap_value_object(x) is x - - Note that we can currently get a mutable pointer into an immutable - Python string: - ->>> rewrap_value_mutable_cstring('hello, world') -'hello, world' - ->>> rewrap_const_reference_bool(None) -0 ->>> rewrap_const_reference_bool(0) -0 - ->>> try: rewrap_const_reference_bool('yes') -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> rewrap_const_reference_char('x') -'x' - - Note that there's currently silent truncation of strings passed to - char arguments. - ->>> rewrap_const_reference_char('xy') -'x' ->>> rewrap_const_reference_signed_char(42) -42 ->>> rewrap_const_reference_unsigned_char(42) -42 ->>> rewrap_const_reference_int(42) -42 ->>> rewrap_const_reference_unsigned_int(42) -42 ->>> rewrap_const_reference_short(42) -42 ->>> rewrap_const_reference_unsigned_short(42) -42 ->>> rewrap_const_reference_long(42) -42 ->>> rewrap_const_reference_unsigned_long(42) -42 ->>> rewrap_const_reference_long_long(42) -42L ->>> rewrap_const_reference_unsigned_long_long(42) -42L - - ->>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 ->>> rewrap_const_reference_double(4.2) - 4.2 -0.0 ->>> rewrap_const_reference_long_double(4.2) - 4.2 -0.0 - ->>> assert abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001 ->>> assert abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001 - ->>> rewrap_const_reference_cstring('hello, world') -'hello, world' ->>> rewrap_const_reference_string('yo, wassup?') -'yo, wassup?' - ->>> rewrap_const_reference_handle(1) -1 ->>> x = 'hi' ->>> assert rewrap_const_reference_handle(x) is x ->>> assert rewrap_const_reference_object(x) is x ->>> assert rewrap_reference_object(x) is x - - -Check that None <==> NULL - ->>> rewrap_const_reference_cstring(None) - -But None cannot be converted to a string object: - ->>> try: rewrap_const_reference_string(None) -... except TypeError: pass -... else: print 'expected a TypeError exception' - -Now check implicit conversions between floating/integer types - ->>> rewrap_const_reference_float(42) -42.0 - ->>> rewrap_const_reference_float(42L) -42.0 - ->>> try: rewrap_const_reference_int(42.0) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> rewrap_value_float(42) -42.0 - ->>> try: rewrap_value_int(42.0) -... except TypeError: pass -... else: print 'expected a TypeError exception' - -Check that classic classes also work - ->>> class FortyTwo: -... def __int__(self): -... return 42 -... def __float__(self): -... return 42.0 -... def __complex__(self): -... return complex(4+.2j) -... def __str__(self): -... return '42' - ->>> try: rewrap_const_reference_float(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> try: rewrap_value_int(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> try: rewrap_const_reference_string(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - ->>> try: rewrap_value_complex_double(FortyTwo()) -... except TypeError: pass -... else: print 'expected a TypeError exception' - -# show that arbitrary handle instantiations can be returned ->>> assert get_type(1) is type(1) - ->>> assert return_null_handle() is None -""" - -def run(args = None): - import sys - import doctest - import builtin_converters - - if 'rewrap_value_long_long' in dir(builtin_converters): - print 'LONG_LONG supported, testing...' - else: - print 'LONG_LONG not supported, skipping those tests...' - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/test_class.hpp b/test/test_class.hpp deleted file mode 100644 index 18164102..00000000 --- a/test/test_class.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TEST_CLASS_DWA2002326_HPP -# define TEST_CLASS_DWA2002326_HPP -# include - -template -struct test_class -{ - explicit test_class(int x) : x(x), magic(7654321 + n) { ++counter; } - test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; } - virtual ~test_class() { assert(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321 + n); this->x = x; } - int value() const { assert(magic == 7654321 + n); return x; } - operator int() const { return x; } - static int count() { return counter; } - - int x; - long magic; - static int counter; - - private: - void operator=(test_class const&); -}; - -template -int test_class::counter; - -#endif // TEST_CLASS_DWA2002326_HPP diff --git a/test/test_cltree.py b/test/test_cltree.py deleted file mode 100644 index 8408f7f2..00000000 --- a/test/test_cltree.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python - -from cltree import basic,symbol,constant,variable - -b = basic() -c = constant() -s = symbol() -v = variable() - -assert isinstance(b,basic) -assert not isinstance(b,symbol) -assert not isinstance(b,constant) -assert not isinstance(b,variable) - -assert isinstance(c,basic) -assert isinstance(c,constant) -assert not isinstance(c,symbol) -assert not isinstance(c,variable) - -assert not isinstance(s,basic) -assert isinstance(s,symbol) -assert not isinstance(s,constant) -assert not isinstance(s,variable) - -assert isinstance(v,basic) -assert not isinstance(v,symbol) -assert not isinstance(v,constant) -assert isinstance(v,variable) - -print 'b=',b -assert repr(b)=='cltree.basic()' -print 's=',s -assert repr(s)!='cltree.wrapped_symbol()' # because not isinstance(s,basic) -print 'c=',c -assert repr(c)=='cltree.constant()' -print 'v=',v -assert repr(v)=='cltree.wrapped_variable()' - - -print 'ok' diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp deleted file mode 100644 index 6631d8ea..00000000 --- a/test/test_pointer_adoption.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -int a_instances = 0; - -int num_a_instances() { return a_instances; } - -struct inner -{ - inner(std::string const& s) - : s(s) - {} - - void change(std::string const& new_s) - { - this->s = new_s; - } - - std::string s; -}; - -struct Base -{ - virtual ~Base() {} -}; - -struct A : Base -{ - A(std::string const& s) - : x(s) - { - ++a_instances; - } - - ~A() - { - --a_instances; - } - - std::string content() const - { - return x.s; - } - - inner& get_inner() - { - return x; - } - - inner x; -}; - -struct B -{ - B() : x(0) {} - B(A* x_) : x(x_) {} - - inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } - - std::string a_content() - { - return x ? x->content() : std::string("empty"); - } - - A* x; -}; - - -A* create(std::string const& s) -{ - return new A(s); -} - -A* as_A(Base* b) -{ - return dynamic_cast(b); -} - -BOOST_PYTHON_MODULE(test_pointer_adoption_ext) -{ - def("num_a_instances", num_a_instances); - - // Specify the manage_new_object return policy to take - // ownership of create's result - def("create", create, return_value_policy()); - - def("as_A", as_A, return_internal_reference<>()); - - class_("Base") - ; - - class_ >("A", no_init) - .def("content", &A::content) - .def("get_inner", &A::get_inner, return_internal_reference<>()) - ; - - class_("inner", no_init) - .def("change", &inner::change) - ; - - class_("B") - .def(init()[with_custodian_and_ward_postcall<1,2>()]) - - .def("adopt", &B::adopt - // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") - , return_internal_reference<2 - // Meanwhile, self holds a reference to the 2nd argument. - , with_custodian_and_ward<1,2> >() - ) - - .def("a_content", &B::a_content) - ; -} - -#include "module_tail.cpp" diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py deleted file mode 100644 index d811bce8..00000000 --- a/test/test_pointer_adoption.py +++ /dev/null @@ -1,88 +0,0 @@ -""" ->>> from test_pointer_adoption_ext import * - ->>> num_a_instances() -0 - ->>> a = create('dynamically allocated') ->>> num_a_instances() -1 - ->>> a.content() -'dynamically allocated' - ->>> innards = a.get_inner() ->>> innards.change('with an exposed reference') ->>> a.content() -'with an exposed reference' - -# The a instance should be kept alive... ->>> a = None ->>> num_a_instances() -1 - -# ...until we're done with its innards ->>> innards = None ->>> num_a_instances() -0 - ->>> b = B() ->>> a = create('another') ->>> b.a_content() -'empty' ->>> innards = b.adopt(a); ->>> b.a_content() -'another' ->>> num_a_instances() -1 ->>> del a # innards and b are both holding a reference ->>> num_a_instances() -1 ->>> innards.change('yet another') ->>> b.a_content() -'yet another' - ->>> del innards ->>> num_a_instances() # b still owns a reference to a -1 ->>> del b ->>> num_a_instances() -0 - -Test call policies for constructors here - ->>> a = create('second a') ->>> num_a_instances() -1 ->>> b = B(a) ->>> num_a_instances() -1 ->>> a.content() -'second a' - ->>> del a ->>> num_a_instances() -1 ->>> b.a_content() -'second a' - ->>> del b ->>> num_a_instances() -0 - ->>> assert as_A(create('dynalloc')) is not None ->>> base = Base() ->>> assert as_A(base) is None -""" -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/tuple.cpp b/test/tuple.cpp deleted file mode 100644 index fce3da85..00000000 --- a/test/tuple.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include - -using namespace boost::python; - -object convert_to_tuple(object data) -{ - return tuple(data); -} - -void test_operators(tuple t1, tuple t2, object print) -{ - print(t1 + t2); -} - -tuple mktuple0() { return make_tuple(); } -tuple mktuple1(int x) { return make_tuple(x); } -tuple mktuple2(char const* a1, int x) { return make_tuple(a1, x); } - -BOOST_PYTHON_MODULE(tuple_ext) -{ - def("convert_to_tuple",convert_to_tuple); - def("test_operators",test_operators); - def("make_tuple", mktuple0); - def("make_tuple", mktuple1); - def("make_tuple", mktuple2); -} diff --git a/test/tuple.py b/test/tuple.py deleted file mode 100644 index cd899df4..00000000 --- a/test/tuple.py +++ /dev/null @@ -1,32 +0,0 @@ -""" ->>> from tuple_ext import * ->>> def printer(*args): -... for x in args: print x, -... print -... ->>> print convert_to_tuple("this is a test string") -('t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g') ->>> t1 = convert_to_tuple("this is") ->>> t2 = (1,2,3,4) ->>> test_operators(t1,t2,printer) -('t', 'h', 'i', 's', ' ', 'i', 's', 1, 2, 3, 4) ->>> make_tuple() -() ->>> make_tuple(42) -(42,) ->>> make_tuple('hello', 42) -('hello', 42) -""" - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/test/upcast.cpp b/test/upcast.cpp deleted file mode 100755 index b02d2534..00000000 --- a/test/upcast.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include - -struct X { long x; }; -struct Y : X, PyObject {}; - -int main() -{ - PyTypeObject o; - Y y; - assert(&boost::python::upcast(&o)->ob_refcnt == &o.ob_refcnt); - assert(&boost::python::upcast(&y)->ob_refcnt == &y.ob_refcnt); - return 0; -} - diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp deleted file mode 100644 index 4fa6c7ee..00000000 --- a/test/virtual_functions.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -struct X -{ - explicit X(int x) : x(x), magic(7654321) { ++counter; } - X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } - virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } - - void set(int x) { assert(magic == 7654321); this->x = x; } - int value() const { assert(magic == 7654321); return x; } - static int count() { return counter; } - private: - void operator=(X const&); - private: - int x; - long magic; - static int counter; -}; - -struct Y : X -{ - Y(int x) : X(x) {}; -}; - -struct abstract : X -{ - abstract(int x) : X(x) {}; - int call_f(Y const& y) { return f(y); } - virtual int f(Y const& y) = 0; -}; - -struct concrete : X -{ - concrete(int x) : X(x) {}; - int call_f(Y const& y) { return f(y); } - virtual int f(Y const& y) { set(y.value()); return y.value(); } -}; - -struct abstract_callback : abstract -{ - abstract_callback(PyObject* p, int x) - : abstract(x), self(p) - {} - - int f(Y const& y) - { - return call_method(self, "f", boost::ref(y)); - } - - PyObject* self; -}; - -struct concrete_callback : concrete -{ - concrete_callback(PyObject* p, int x) - : concrete(x), self(p) - {} - - concrete_callback(PyObject* p, concrete const& x) - : concrete(x), self(p) - {} - - int f(Y const& y) - { - return call_method(self, "f", boost::ref(y)); - } - - int f_impl(Y const& y) - { - return this->concrete::f(y); - } - - PyObject* self; -}; - -int X::counter; - -BOOST_PYTHON_MODULE(virtual_functions_ext) -{ - class_("concrete", init()) - .def("value", &concrete::value) - .def("set", &concrete::set) - .def("call_f", &concrete::call_f) - .def("f", &concrete_callback::f_impl) - ; - - class_("abstract", init()) - - .def("value", &abstract::value) - .def("call_f", &abstract::call_f) - .def("set", &abstract::set) - ; - - class_("Y", init()) - .def("value", &Y::value) - .def("set", &Y::set) - ; -} - -#include "module_tail.cpp" diff --git a/test/virtual_functions.py b/test/virtual_functions.py deleted file mode 100644 index 9b074b1a..00000000 --- a/test/virtual_functions.py +++ /dev/null @@ -1,102 +0,0 @@ -''' ->>> from virtual_functions_ext import * - ->>> class C1(concrete): -... def f(self, y): -... return concrete.f(self, Y(-y.value())) - ->>> class C2(concrete): -... pass - ->>> class A1(abstract): -... def f(self, y): -... return y.value() * 2 - ->>> class A2(abstract): -... pass - - ->>> y1 = Y(16) ->>> y2 = Y(17) - - - -# -# Test abstract with f overridden -# ->>> a1 = A1(42) ->>> a1.value() -42 - -# Call f indirectly from C++ ->>> a1.call_f(y1) -32 - -# Call f directly from Python ->>> a1.f(y2) -34 - -# -# Test abstract with f not overridden -# ->>> a2 = A2(42) ->>> a2.value() -42 - -# Call f indirectly from C++ ->>> try: a2.call_f(y1) -... except AttributeError: pass -... else: print 'no exception' - -# Call f directly from Python ->>> try: a2.call_f(y2) -... except AttributeError: pass -... else: print 'no exception' - -############# Concrete Tests ############ - -# -# Test concrete with f overridden -# ->>> c1 = C1(42) ->>> c1.value() -42 - -# Call f indirectly from C++ ->>> c1.call_f(y1) --16 - -# Call f directly from Python ->>> c1.f(y2) --17 - -# -# Test concrete with f not overridden -# ->>> c2 = C2(42) ->>> c2.value() -42 - -# Call f indirectly from C++ ->>> c2.call_f(y1) -16 - -# Call f directly from Python ->>> c2.f(y2) -17 - - -''' - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print "running..." - import sys - sys.exit(run()[0]) diff --git a/todo.txt b/todo.txt deleted file mode 100644 index e6a0f2d3..00000000 --- a/todo.txt +++ /dev/null @@ -1,24 +0,0 @@ -High Priority: --------------- - -Document builtin correspondences between builtiin Python types and C++ -types - -FILE* conversions: http://aspn.activestate.com/ASPN/Mail/Message/1411366 - -Finish shared_ptr support: http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1456023 - -Medium Priority: ----------------- - -Implement type_info streaming for GCC -(http://mail.python.org/pipermail/c++-sig/2002-June/001277.html) - -Low Priority: ------------- -Write "inside the Python type system", a survey of typeobject.c in -Python source -- may go hand-in-hand with enum wrapping - -Better overload resolution - choose best match - -