From 504a8d5be76ebb95e7b2aefff42efe416f3cbb26 Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 26 Aug 2003 23:24:03 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'version_0-9-22'. [SVN r19793] --- 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.html | 1127 ---------- doc/PyConDC_2003/bpl.pdf | Bin 96642 -> 0 bytes doc/PyConDC_2003/bpl.txt | 947 -------- doc/PyConDC_2003/bpl_mods.txt | 908 -------- doc/PyConDC_2003/default.css | 188 -- doc/PyConDC_2003/python_cpp_mix.jpg | Bin 22831 -> 0 bytes doc/PyConDC_2003/python_cpp_mix.png | Bin 6293 -> 0 bytes doc/boost.css | 59 - doc/building.html | 429 ---- doc/index.html | 121 - doc/internals.html | 184 -- doc/internals.rst | 168 -- doc/new-conversions.html | 328 --- doc/new-conversions.txt | 111 - doc/news.html | 160 -- doc/polymorphism.txt | 217 -- doc/projects.html | 344 --- 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 | 1996 ----------------- 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 | 238 -- ...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/acknowledgments.html | 133 -- doc/v2/args.html | 197 -- 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 | 785 ------- 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 | 227 -- 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 | 578 ----- 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/indexing.html | 636 ------ 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/opaque_pointer_converter.html | 142 -- doc/v2/operators.html | 888 -------- doc/v2/overloads.html | 227 -- 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.html | 1021 --------- doc/v2/reference_existing_object.html | 178 -- doc/v2/register_ptr_to_python.html | 160 -- doc/v2/return_arg.html | 219 -- doc/v2/return_by_value.html | 147 -- doc/v2/return_internal_reference.html | 227 -- doc/v2/return_opaque_pointer.html | 189 -- 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 | 10 - 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.hpp | 69 - include/boost/python/arg_from_python.hpp | 85 - include/boost/python/args.hpp | 160 -- include/boost/python/args_fwd.hpp | 53 - include/boost/python/back_reference.hpp | 103 - include/boost/python/base_type_traits.hpp | 38 - include/boost/python/bases.hpp | 69 - include/boost/python/borrowed.hpp | 22 - include/boost/python/call.hpp | 77 - include/boost/python/call_method.hpp | 77 - include/boost/python/cast.hpp | 107 - include/boost/python/class.hpp | 665 ------ include/boost/python/class_fwd.hpp | 25 - .../python/converter/arg_from_python.hpp | 341 --- .../boost/python/converter/arg_to_python.hpp | 262 --- .../python/converter/arg_to_python_base.hpp | 33 - .../converter/as_to_python_function.hpp | 47 - .../python/converter/builtin_converters.hpp | 132 -- .../python/converter/constructor_function.hpp | 18 - .../python/converter/convertible_function.hpp | 15 - .../boost/python/converter/from_python.hpp | 42 - 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 | 35 - .../converter/pytype_arg_from_python.hpp | 99 - .../converter/pytype_object_mgr_traits.hpp | 43 - include/boost/python/converter/registered.hpp | 60 - .../python/converter/registered_pointee.hpp | 63 - .../boost/python/converter/registrations.hpp | 85 - include/boost/python/converter/registry.hpp | 50 - .../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 | 28 - .../converter/to_python_function_type.hpp | 20 - include/boost/python/copy_const_reference.hpp | 44 - .../boost/python/copy_non_const_reference.hpp | 44 - include/boost/python/data_members.hpp | 373 --- include/boost/python/def.hpp | 115 - include/boost/python/def_visitor.hpp | 87 - .../boost/python/default_call_policies.hpp | 79 - .../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 | 189 -- 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 | 37 - include/boost/python/detail/dealloc.hpp | 18 - .../boost/python/detail/decorated_type_id.hpp | 77 - include/boost/python/detail/decref_guard.hpp | 22 - include/boost/python/detail/def_helper.hpp | 213 -- .../boost/python/detail/def_helper_fwd.hpp | 18 - include/boost/python/detail/defaults_def.hpp | 280 --- include/boost/python/detail/defaults_gen.hpp | 389 ---- include/boost/python/detail/dependent.hpp | 28 - include/boost/python/detail/destroy.hpp | 107 - .../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 | 472 ---- 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 | 53 - 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 | 76 - include/boost/python/detail/none.hpp | 20 - include/boost/python/detail/not_specified.hpp | 15 - .../detail/nullary_function_adaptor.hpp | 47 - 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/prefix.hpp | 16 - 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 | 77 - include/boost/python/detail/result.hpp | 126 -- include/boost/python/detail/scope.hpp | 17 - include/boost/python/detail/signature.hpp | 86 - .../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 | 36 - include/boost/python/detail/void_return.hpp | 43 - include/boost/python/detail/wrap_python.hpp | 167 -- include/boost/python/dict.hpp | 153 -- include/boost/python/enum.hpp | 103 - include/boost/python/errors.hpp | 55 - include/boost/python/exception_translator.hpp | 28 - include/boost/python/extract.hpp | 248 -- include/boost/python/handle.hpp | 247 -- include/boost/python/handle_fwd.hpp | 17 - include/boost/python/has_back_reference.hpp | 25 - include/boost/python/implicit.hpp | 30 - include/boost/python/init.hpp | 424 ---- include/boost/python/instance_holder.hpp | 58 - include/boost/python/iterator.hpp | 117 - include/boost/python/list.hpp | 142 -- include/boost/python/long.hpp | 69 - include/boost/python/lvalue_from_pytype.hpp | 106 - include/boost/python/make_function.hpp | 104 - include/boost/python/manage_new_object.hpp | 42 - include/boost/python/module.hpp | 14 - include/boost/python/module_init.hpp | 60 - include/boost/python/numeric.hpp | 233 -- include/boost/python/object.hpp | 17 - .../boost/python/object/add_to_namespace.hpp | 24 - include/boost/python/object/class.hpp | 65 - .../boost/python/object/class_converters.hpp | 90 - 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 | 197 -- include/boost/python/object/function.hpp | 77 - .../boost/python/object/function_handle.hpp | 46 - .../boost/python/object/function_object.hpp | 41 - include/boost/python/object/inheritance.hpp | 133 -- .../boost/python/object/inheritance_query.hpp | 18 - include/boost/python/object/instance.hpp | 52 - include/boost/python/object/iterator.hpp | 248 -- include/boost/python/object/iterator_core.hpp | 18 - include/boost/python/object/life_support.hpp | 16 - include/boost/python/object/make_holder.hpp | 95 - include/boost/python/object/make_instance.hpp | 76 - .../boost/python/object/make_ptr_instance.hpp | 71 - .../boost/python/object/pickle_support.hpp | 125 -- .../boost/python/object/pointer_holder.hpp | 180 -- include/boost/python/object/py_function.hpp | 164 -- include/boost/python/object/select_holder.hpp | 195 -- include/boost/python/object/value_holder.hpp | 143 -- .../boost/python/object/value_holder_fwd.hpp | 17 - include/boost/python/object_attributes.hpp | 69 - include/boost/python/object_call.hpp | 24 - include/boost/python/object_core.hpp | 471 ---- include/boost/python/object_fwd.hpp | 19 - include/boost/python/object_items.hpp | 90 - include/boost/python/object_operators.hpp | 134 -- include/boost/python/object_protocol.hpp | 80 - include/boost/python/object_protocol_core.hpp | 54 - include/boost/python/object_slices.hpp | 127 -- .../boost/python/opaque_pointer_converter.hpp | 136 -- include/boost/python/operators.hpp | 356 --- include/boost/python/other.hpp | 115 - include/boost/python/overloads.hpp | 14 - include/boost/python/pointee.hpp | 44 - include/boost/python/proxy.hpp | 102 - include/boost/python/ptr.hpp | 129 -- include/boost/python/pure_virtual.hpp | 129 -- include/boost/python/raw_function.hpp | 62 - include/boost/python/refcount.hpp | 42 - .../python/reference_existing_object.hpp | 47 - .../boost/python/register_ptr_to_python.hpp | 32 - include/boost/python/return_arg.hpp | 100 - include/boost/python/return_by_value.hpp | 32 - .../python/return_internal_reference.hpp | 44 - .../boost/python/return_opaque_pointer.hpp | 53 - include/boost/python/return_value_policy.hpp | 22 - include/boost/python/scope.hpp | 79 - include/boost/python/self.hpp | 34 - include/boost/python/signature.hpp | 121 - include/boost/python/slice_nil.hpp | 43 - include/boost/python/str.hpp | 402 ---- .../python/suite/indexing/container_utils.hpp | 53 - .../indexing/detail/indexing_suite_detail.hpp | 706 ------ .../python/suite/indexing/indexing_suite.hpp | 294 --- .../suite/indexing/map_indexing_suite.hpp | 180 -- .../suite/indexing/vector_indexing_suite.hpp | 227 -- include/boost/python/tag.hpp | 19 - include/boost/python/to_python_converter.hpp | 41 - include/boost/python/to_python_indirect.hpp | 116 - include/boost/python/to_python_value.hpp | 130 -- include/boost/python/tuple.hpp | 71 - include/boost/python/type_id.hpp | 161 -- .../boost/python/with_custodian_and_ward.hpp | 80 - index.html | 9 - 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 | 292 --- src/converter/registry.cpp | 237 -- src/converter/type_id.cpp | 131 -- src/dict.cpp | 171 -- src/errors.cpp | 98 - src/list.cpp | 140 -- src/long.cpp | 40 - src/module.cpp | 55 - src/numeric.cpp | 313 --- src/object/class.cpp | 686 ------ src/object/enum.cpp | 225 -- src/object/function.cpp | 649 ------ src/object/inheritance.cpp | 496 ---- src/object/iterator.cpp | 39 - src/object/life_support.cpp | 114 - src/object/pickle_support.cpp | 63 - src/object_operators.cpp | 57 - src/object_protocol.cpp | 191 -- src/str.cpp | 316 --- src/tuple.cpp | 20 - test/Jamfile | 205 -- test/args.cpp | 94 - test/args.py | 179 -- test/as_to_python_function.cpp | 14 - test/auto_ptr.cpp | 91 - test/auto_ptr.py | 79 - test/back_reference.cpp | 112 - test/back_reference.py | 31 - test/bases.cpp | 63 - test/ben_scott1.cpp | 51 - test/ben_scott1.py | 14 - test/bienstman1.cpp | 37 - test/bienstman1.py | 20 - test/bienstman2.cpp | 25 - test/bienstman2.py | 17 - test/bienstman3.cpp | 22 - test/bienstman3.py | 27 - test/bienstman4.cpp | 40 - test/bienstman4.py | 20 - test/bienstman5.cpp | 24 - test/bienstman5.py | 18 - test/borrowed.cpp | 34 - test/callbacks.cpp | 148 -- test/callbacks.py | 144 -- test/cltree.cpp | 70 - test/complicated.hpp | 39 - test/copy_ctor_mutates_rhs.cpp | 24 - test/crossmod_exception.py | 22 - test/crossmod_exception_a.cpp | 20 - test/crossmod_exception_b.cpp | 20 - test/data_members.cpp | 135 -- test/data_members.py | 203 -- test/defaults.cpp | 173 -- test/defaults.py | 176 -- test/destroy_test.cpp | 51 - test/dict.cpp | 82 - test/dict.py | 43 - test/docstring.cpp | 59 - test/docstring.py | 56 - test/embedding.cpp | 122 - test/enum.cpp | 55 - test/enum.py | 61 - test/exception_translator.cpp | 25 - test/exception_translator.py | 24 - test/extract.cpp | 140 -- test/extract.py | 104 - test/if_else.cpp | 45 - test/implicit.cpp | 48 - test/implicit.py | 28 - test/indirect_traits_test.cpp | 105 - test/input_iterator.cpp | 49 - test/iterator.cpp | 138 -- test/iterator.py | 74 - test/keywords.cpp | 114 - test/keywords_test.py | 96 - test/list.cpp | 145 -- test/list.py | 115 - test/long.cpp | 62 - test/long.py | 30 - test/m1.cpp | 276 --- test/m2.cpp | 99 - test/map_indexing_suite.cpp | 48 - test/map_indexing_suite.py | 209 -- 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 | 18 - test/nested.cpp | 52 - test/nested.py | 37 - test/newtest.py | 201 -- test/numpy.cpp | 105 - test/numpy.py | 177 -- test/object.cpp | 318 --- test/object.py | 128 -- test/object_fail1.cpp | 12 - test/object_manager.cpp | 34 - test/opaque.cpp | 77 - test/opaque.py | 83 - test/operators.cpp | 93 - test/operators.py | 91 - test/pickle1.cpp | 55 - test/pickle1.py | 33 - test/pickle2.cpp | 97 - test/pickle2.py | 47 - test/pickle3.cpp | 105 - test/pickle3.py | 42 - test/pointee.cpp | 35 - test/pointer_type_id_test.cpp | 39 - test/polymorphism.cpp | 161 -- test/polymorphism.py | 71 - test/properties.cpp | 60 - test/properties.py | 90 - test/raw_pyobject_fail1.cpp | 12 - test/raw_pyobject_fail2.cpp | 14 - test/register_ptr.cpp | 52 - test/register_ptr_test.py | 22 - test/result.cpp | 112 - test/return_arg.cpp | 68 - test/return_arg.py | 24 - test/select_arg_to_python_test.cpp | 65 - test/select_from_python_test.cpp | 157 -- test/select_holder.cpp | 86 - test/shared_ptr.cpp | 200 -- test/shared_ptr.py | 127 -- test/simple_type.hpp | 14 - test/staticmethod.cpp | 46 - test/staticmethod.py | 54 - test/str.cpp | 67 - test/str.py | 54 - test/string_literal.cpp | 38 - test/submod_subclass_api.cpp | 231 -- test/test_builtin_converters.cpp | 123 - test/test_builtin_converters.py | 240 -- test/test_class.hpp | 33 - test/test_cltree.py | 40 - test/test_pointer_adoption.cpp | 126 -- test/test_pointer_adoption.py | 90 - test/tuple.cpp | 29 - test/tuple.py | 34 - test/upcast.cpp | 19 - test/vector_indexing_suite.cpp | 53 - test/vector_indexing_suite.py | 346 --- test/virtual_functions.cpp | 122 - test/virtual_functions.py | 107 - todo.html | 186 -- todo.txt | 154 -- 504 files changed, 63934 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 100755 doc/PyConDC_2003/bpl.html delete mode 100755 doc/PyConDC_2003/bpl.pdf 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.jpg 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 100755 doc/internals.html delete mode 100755 doc/internals.rst 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/acknowledgments.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/indexing.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 100644 doc/v2/opaque_pointer_converter.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.html delete mode 100644 doc/v2/reference_existing_object.html delete mode 100644 doc/v2/register_ptr_to_python.html delete mode 100755 doc/v2/return_arg.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_opaque_pointer.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 100644 include/boost/python.hpp 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 100755 include/boost/python/def_visitor.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 100644 include/boost/python/detail/dealloc.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 100755 include/boost/python/detail/def_helper_fwd.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/nullary_function_adaptor.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 100755 include/boost/python/detail/prefix.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/signature.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 100755 include/boost/python/object/inheritance_query.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/opaque_pointer_converter.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/pure_virtual.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/register_ptr_to_python.hpp delete mode 100755 include/boost/python/return_arg.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_opaque_pointer.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/suite/indexing/container_utils.hpp delete mode 100644 include/boost/python/suite/indexing/detail/indexing_suite_detail.hpp delete mode 100644 include/boost/python/suite/indexing/indexing_suite.hpp delete mode 100644 include/boost/python/suite/indexing/map_indexing_suite.hpp delete mode 100644 include/boost/python/suite/indexing/vector_indexing_suite.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 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/Jamfile 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/crossmod_exception.py delete mode 100755 test/crossmod_exception_a.cpp delete mode 100755 test/crossmod_exception_b.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 100755 test/keywords.cpp delete mode 100644 test/keywords_test.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/map_indexing_suite.cpp delete mode 100644 test/map_indexing_suite.py 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 100644 test/opaque.cpp delete mode 100644 test/opaque.py 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/properties.cpp delete mode 100644 test/properties.py delete mode 100755 test/raw_pyobject_fail1.cpp delete mode 100755 test/raw_pyobject_fail2.cpp delete mode 100644 test/register_ptr.cpp delete mode 100644 test/register_ptr_test.py delete mode 100755 test/result.cpp delete mode 100755 test/return_arg.cpp delete mode 100644 test/return_arg.py 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/vector_indexing_suite.cpp delete mode 100644 test/vector_indexing_suite.py delete mode 100644 test/virtual_functions.cpp delete mode 100644 test/virtual_functions.py delete mode 100755 todo.html 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 zcmWIWW@h1H00EyaS6vVd!)y!;3`zO<#U=U(H8!DMC~A1&Y6>b#GV=3~lq#&TLs2S% zt~4dJBr!7wtOF#+!BEXUNn7=3(LQz#1_md61_mV@I*K#X^Abx+i&BgAG71W=MrG&U zJ|X&7PT_yz25ys}gC{=S4vW#>^Kp^%g4pHTZY`PLB4{~j*}^uR_9@B||K8h{w@IBc z@{Bfny2G)h=fuqF^OoQ5Rcb~@_iVM>cJsK#JoO?Q&zqL>Pd3cu6}EdAe70=Y-Msc% zv6CTLy2?i{b^LtsW}^>xzwcs)z7MY51}QPD`S)`UCMlH8I*~YyYntDZG%Km4*KGuO z-WDDT)nXD;7nE6;SoP!F{;r^x+{YeAd~k`b4l?BX{X(Vn-G+aweA8d6ulx8{y-fGA z=ai*BHT}X1O}mBEmKSQc@(D0=vNbSoe#yK44FAqKMl%@PXC87@3$~lG(C2v$i*U@@ z$T_NoOI+LEL`47PypZ-`y1@33o=paGjNjDDI=W~YTJk4+Q9-p+B%{4VE;%{VMh=SXjSC`}eTfF}N`P25*2Y*iA{I2f%j@z<- z>>SwJt_O9#lDp!rWq*e0pkG_ylFPcU^R)#ur$3w~zjC5Xxmsb3*Iv>2T(ZS3H%ijX z*Hlbm-n;Ym`CAK@3q0s~DWX`duPYx^HshqhQufUrY?VbW4R4B%wi%q-x=g40hDLB* zm&i4}z-Y-A>TlkM|Nr%3N!mxif_nNn^-Jf_>8mULF5dh79BoI)o(Uxk2wpL zDP=nQKB;-O{LS_5?$!SueBS?ifBYXqi~nyQ-{;xDxZ+-2#qVd+P6!GfZJE_+&?K6$ z{aml_$^$)0+?qvvjT}#XR1R!Xn7e%8TK*>@ulyTiHnAxyec@I1V>R?z^zy)~TUpku zMN>b7a|%Y3YFz9wo#!&)XvZhN%>tc1dPWZKmYMk8DPI0tQ~uVyE&CtvKwaenNPO^MC*4YquTWH-SfkUv9<^NpBUu zi`|Qy0@+M19llvAXc(H4+8ED#|Gd+@h@(ZVU8fdlvGEl-i5dzft`V&B;J=jCq+q@} zOXtV)P)C6e|;ICNa()lDzgBg_BH z-XQ!gX6Ya6UpJQUHC+p0@cVUJ?sbWk$F^;AlQf^MkT}scx9Q~hAOT+XVD3Ck8mRh-dIJEXXEmg_?wk#k*|KAgTUqeL3Ly|p)Z zKCR|tefsHIU-sKw*XCuv-F>YwTXxsAiP^Hdua#{-Vad+weeG;kRvwpU=kLeUKkv(^ zW#w7v6je4o#Ny{G$@x!u|4d-t_V!K8yYWXY2)>T)#u32U|oE75zKKt?ppPkJ`PNl2f zPG1qWHezbC`s&a{7w;9DY6YkLxBFlf`YkMEW!RE4A7*7u$=LAQg!j~p_jg$%j#rg; zmYO~eZSGHsK2(@4+n0K#j9Z~}O<7Uc)t+g*S2t+hRkmqM#X+(RK^orGj`aBj} zRv*wZU$<1+X2-h5OKa~aD1;` za_3lQ+w=3`eJmDh9`!6fn|dcH<>R#elRs+XV%<;i?L54)#qWCI&eVeaRaQEaKj+N; z+j`eFL650^Tkzkk?Z2+ZeO>+cRXF?A^?a-2WkdH{t*dJdzW8eQB9m!+^Pa`TRbSY* zg>lA517r8IEwj6)+$%ED&6Bh^w@!GXfsD)L01@$sXI0JWC-1~K?6htW^IP$(d+&h< zhcnb}$$sNx*lds>oY%MX{o9Lkcipt+v)Xzqd&f+VXWx!xs??T$J!SWF`E8BG+>igv znxexu@yWsmogT09opLVm@;rB}b1!+E@ZFa?@`vK}gee`5+C1-Xui-qcs^+if|GpwC zcGI=_w@V&BxU{b(< zSG*SV2&s#YzhhObWKOHyG*1B+d|{k)EBSyLCz`HQc+oZi|etH$gXuo>((qM1fw4d(I zy2~1#H-3|f`ZS+m&y3yk{10Yl{Hzz_y&jb;AK-o>J45?|fadk6Wd9EWw(A$>IzASO z&F=ksF!@9kZ?2%3$Bqqqj>SFPcxSKac5Yt1-`~uhw(I|!-4M9sfbe#P*{q>Yo*J7m z>9cOsn46x*9w%22_?kC|t4`%l(yFYC>r>5zE6K9H?_*^Wr^;EOC?B^S$aq z_#D6S`(++uT4OxP!>sz)s|oSa%S4+tiB0`HS1vPPk-mzPedCvy&kITy?x~4Cp#1Tc z3D1xFR$t_Lm{;Yx{)kz?(q^=zU}fd`X?r%T61l1%bV+&Rl8lZ}KhZ+&r5+l0n{wxv z%BdedSn#3ID>i|1|D*M%bN0U$|E|goPY5YiTMu^}?j4@A3T1X@5N5KYoAn)9FXjD!Ft19~EsbvfLQF z?(7-48KsRqNj;Nh@0$AU=&CPz3ySJ{kL2)(&eWQc`j}}CZ~ulJTP332U$t-gaVKO> zYjfoJSNE42Ee?4XSiP^M=+69hQOCJc7b|bOJ9pl<-^q5#7gsJYm+Q4Y>ii@#K|uDr zpJ4l)j^OF*e_RyYb>!Mbx17!@6W*ZebMJhg`&IAteZL^=zd`ls2IrmUTjz3isK#D< zn6UkJqtE-Bb6f(=Wdg7G9;q`5JY6q&;yv$O;Q()D7DU2fd&C^<#>~KA$Iif@j3ePB zB^IZ~=O<;QCYONHO>gM^{L2Ocb@R9Uf5@V*`|4H$3%{h#ty@ZMEVCm7`zKD0xzv1Q zTTZ&F&(r+pGUbs`TMlk%zp?N4yM6ELO3aug&K@@i-(?!IPFClL?$d&KQX9p#wuT3a z_&${K^}RM}(gTr{9Gk{tk65y%1|MYa4rO(EcHG_A?aWCl=gh|fcV_8Cgzo4y;P?|O zr6~JsLGL4nKNllYYHL=?q;fcAiyULKnWP{wzn9~!NLc#}+iS*&KmYKUJ-N23u)%(- zW45E@f~fG8-7GgRESJq3kq-LU$em|_s-oqA+|-+|Hu=voZ$10?b#BRS z&m5G#FPxicox+-}R_8QHrn9R~vFF=sJ3BioyDGodGaDPaKhI7rD*ae!8L!%%|NP?X z>G_K^eoolH`oY?>=Fk!8iDy=+xmV2AO1&^AI@_H_K z?)Y_E@w2b`X=C}|E~&L*cRXZy?i@Vq`{Dj>t`7yzV1oYa-P-qH2L-U zB6MfV!RxmTmNx949%-||!tT+X#{V@c@tfP1KM?j%|M&CC<}cgkJW0LJXr}UVrlih= z1u3ycS3S&Ii{oU9(Z&&}?Hv78IRa0h@uqkh9*Pmf{@V3_QT$%62-S)L- zel>c%zo>nS|K$cZ(`zfIubnvabMfo#0q&tc7Pmh5lJfMs@eBD!KkP%^-F~zoN?+mX zhjr10%MU(!^y*dG)HC^E-70;Sx!rkFUU9nYxwF$Y#L()9M1T3Z>$>Y_{ha>v_r(o+ z9;WW-vbl31>9uS1B@~6A2-gw_OPgi|QL>cEwlOa&jEFOY5v%$`w`#b*@(Y(cbl>d24=jm!XFS^qDK-bZNO-h09 z+*Z>^K~V;QLJA84Em}St+UO#3D0B*Q)5)$a=24M$+!nlHTNtDJE7UTIZN9q(3VOd^ zdP}V4EF(Mj>#bqOCZ2kEX@jXyWpw0mZ|kMnGtVu%aN~fZ_p@Nd>%K|bPTf(yQShPt zMC!5PsMtGhAD`YA?>?_SU%dNAc8~6%wh4Rk_1|opS05Xn{QFt@m#@F7|2$TCqmUK# zqvvwuqA8`tv5xI?((f1sp4r~^a!2H>+%0zRKL^Zm-eRWo|YP<~?_t8oQ@pH-G3= zxoWe+j`tI{1@T!f4zga>_-y|!*?Bh?X8X^SeYVTfq$KWXNvqw=lm2~XZyMPz?UqZN zd;P`1`+4?)i15*X1XE-k(seD{;u}@i)D)uN-SG z-+jBR;Js65BhU7QpSTL|Z+rPvsJ#36kEYb7N1rxvOg45ZjhZ6E#__rJb;2uyg?>{G zehHWDv_HR+r*+ncGL6(JAqNi3i0zZg7kPZ|m+IsG$(}Q6OkeNyuvokE_uhTCo+Y#2 zncV4_zUrb&z~|F^mTwm5&TTWXl`UOvW_|Wa)-%oNKQ0TeiSr40Q#RZ7@DF)J<(bLa zr=$Area;m*28Jg~85qeqMZXPGT{51m~@7?Bv^KlisiU zRPV4UblZ{(vo;DJ|8^#2mD;w=g|SJ$jfyt?KC(z95k- z*$R`H_Qj_<#++E`v6;oHN&iYx(y#u>N^?8}m#pO3H0NXMMh*sh6RuP{k;PVi&96@@ zwC~?9VxDN|Kdp6w{3V}fJ3Wj9^)6{l>2hFjF={ASFf+<|f07XELnj6RZ>eUc`v_51O>-T#Q|tj@>nOev|3GnzFw&6zR%>$5-2{(mb=l~Sed@17q&HvX_oIAY%-&yc8a?6h{FF~53o0-K3S z;lYQ$GADMvR)}KqPmkOrklb0*Bp7#k&4uFZT7ece^(uvHmpn@4*?(^@5c7ZPv**w8 z7f)ZG4$qJKeZGFzjy+%E|CAN}kvQ`2#{Y}$VNADLHr~0wBi;5J_5?Tf#=1$xfT&8YTQzypmKq=PlSN=*g8O=6{~` zwaEY8Ri#;n3vW-%6g?UFQ2WAG-jgg*y6^8z{8+T`>`Z&#yholB#O?Z4{agH_BuduK z|G-`A*Y4U^P8^UqAt8F7-_eoz!qedE&cANUvs>Di@wD#GQ2A%mxy-28{8~)y^#&!~ zcy?|vcW3k8ES-_;)iY0dS~MSBVAcEaN_#5Ll*McfnK+NUdj9LYIzD0_y*VRz}h%v`fK9;y>sFxz+S-s8}hlpW->}d>@-)*o+Ytuxv%Ax0;>XEoj~pAZ&F{j zb$nr%GviRX*Xn6kuJm@d7*2lC_w&isW8rMK=Ciq8DE_jnhxfxRQxX4@BAzO`UOSfE zy}hq~OGJIZ^`1FTH*Hs6$MZ%_Lq_6)D?|MhRHw7BrRk}^uPsRZ zBN6lR9*6p*FvAwE^hMLV-tQAWUb{9kiCOeXl27&GeeWVy8b#gl*VtKVRmXDmYBtx( zja!wRvQujd{xDyZ-tgOV^P;;lbI#TEOKmu&VSFz|X_lrb^9dQ_Gq>JPi?0gwAq ze0jd-?pdr7-o-piXyS>3Ti9E>6is%#>%4TV{>A)v4D4~qoQ;#iBDbtRye5Keq7?TA zOK!E+NoDfpbGiz?I~>_6)y43*Bv9~fUXg8H`)NhvgtmDi z4X%DyAEZZWIEr0=G54X7U5jY-JfG^c$MwrtzsGz~-m7Oib!nfoGoP8$wFhf2w3+3x zg)cT1;Emvss?BqJc2#e}sT-DIX8(=_Pd%y4GjXj(a-DmF*#eX3qHTgE9q}y_}Sp>^$QWJBG&KY*?4P*hUo>-sjo~+ z&mT(6`1gM4nXn@d-e%sr8!>0wq4!COe$s4(Yjt+H1m zH!GalD!nQCeNM}QgL}0EoeiQBzD9d)6wH1$VSlV+hDK0EcFK3JzIlpTGxT`we0j(% z=$@@RbH4xltlu$Q=jP5SaC!G+N$Tz2e^2kq(}bKi z7M#j6FY;8DWEdWvXRP^QfwCV*qO9Hb1)txqlAgNxVr6AUf#M>S%Kr)-hrYk*lA5;A ze5R^rVMwpj^+(@ZSR4}m)a+?Evx2QiV(pU)|C!mYy34WfJ)65NL+td)&#_nP-tr$^ zJ<~Qd&2P@-ww#B_9W2Y!7}v}(I)3(wVAIB)Nz&(M`MW(`{qHr~xmSsD25d84Y<%)~ zoj|{`+6Ie9Q(U!=zWDY)&8IK;hQHsdVzr*x3tnWapLuA>FtvXAgI!0f{ysCF!uiKw znoV^{g}a7>O81kFh@-VDlTA&}vn4kK{k3c1Y|v!8(dol|Z(+BgeolCx5uZ}>CX*!x z8|Gh%H^02%&6$q1KD=$uP78(bYlgQw+H`x`L?``VsySxE|6_`7gQEIr4iDF*J2{J; zdpstG=s5buFP3Ns>n%un{G0WQO0w*q#Rrc)ElU3tb}E0v-4;QMM?pcab(n7khjb+L z9Pi^0U_GGpK+>%9(CPx2$SZ5EozaoVEsi-PaLV+)hOqR9Yb^riPZWx~e#-l<+1Asa z^Xj~X+_vVGOEnng=^RTi?42up+LIw?$>o??2UMaT@PzqxE^o^gP^yV|&^LqE>RqF< z$(x4dAukGzVmDegtW2D$<#a2My&|lq&E+BYjai46sd{-dP0>7~osiO=A=n}OrRB2d zk9n7pH5V5?QFW`>=W(%Uvk8Mv!X(BwDS0ZhxIDEv=H1DP6ZxzY8FyBf)#yf#;!Bsw zCg)#CnTkwT+_iAocB2mt?XS$(3u8?=8h@;eX>k2kvB5H%IbsIG-PF!?wJpqHXSz+_ z-{>+A;rx@>`TT!y<{MEX@u-F8#9!DJA7k85xkMz1S@_1`(4yF`Qr~~4*JgK@mL2JI zF#VLu;wQd?u~jGeoZ6NS`Ml2$?iAh&G&|(~^~>T`uICFqcm?Z{Dlcz4BO&r_<*l11 zs>|;sN8Jqn(onj!ae{0>Zb-@2m0z~)>tl0b&#TQA-QM(RgIQ&%(@hcH9$hU@2hMBH zXDhI8D>b{L&Mey_4**|QvpXe z+?|lnDLJ8-OT;hy!T-ne1eXZoopqa)iOpMpZR84r*2&~nzFFXE8jN4-{f4nOv{6+%EzylsLc%jvUiVB2=mDf?>cM5jm=jyu`=V}Gun9C7W*A~%`3lqGvFM=3A=8RPE1^T&?>m`WFIoOtU0E3rT=@2Rhzca z{gR!${ic`phc(+@&I)+;U-T5=__s!-gyO;Pru*^b4U+7MoWX+sX zAD0zwGhTTw?EKhe#(kwe=hqLW-^UXfDl_Jv^pGfddSaQ-u8BJ;S$laebkBcbtajtZ z3P$-fu9NKcXL#1d=4WL^s=8b_#guYoiqm@Av&*L)$*whNfV@hzWAllCs?Jy*VDIpez}=bwJh=?sYYwaj!~>zBhC;?f%F&p#Kes=UXaQq4W- zwxm;Q&Gny-%wG;yS$Un{?~@ZLe9F7*?#;(8g)35aO~{+`JX-3EJGE$i)%B@Ip=2#5w1-oSU@JdU5gN$Thb-XMFy0*Z;XAQ`^+epqC+6rES;8Z&~J%TP?k* z>BH6YHLfQfyva?GZl8I_yt!lCdrj>GRT7AdQxn4iq+|%srYR`{m&sLsMkDL+IAGW&cP^z1yuHB`=RiT?C zm47n&OxyWyM!8PVg>ou5AtLS9N438)yXzT(=Bj;#>Qd zS%}3xHrm=Rd3)B~S>9`Im&J6liY&vV=lhoFUKGy`EmkNs-ojonHw_Is{v|_-a z<(oKK&nc+f3fZJka_RZ{e=zF zo&3b1x$Kl`_k>`v`#aa{n|tN@yuIPZlXa#a^UB?_H2uQa-Nolqf?q!3+oLn<>4OtR zF{dVGs0Pg4S+rgDnc#G3nVsioZ4gpU!JGa+>l+YJy=XXYfg< z>p2D+S1Q`Q``RAj&^#;bQ%}=Pp3oLs#<1zL_AR`UBE(%&(8)13xOM-_h`8JzTf0yC zF4C0e-lC`0m9=H<;*$z@=5O0p+VTJI_H2!1;ZtARTwLsF;q%W5xxUV8*Uv2Kb z+T?wZ8nCT+^>{!niaE+EEPdgbrNx}zt$iVy8sR-xwQckAfk&y$5Gyx4dB+JlSB*y8iE zKAc^~)^Be5qb#^teYTX%-761nE@LxT+bi}fdD&YD=G14&?k#6oiu88QQ152(P2P0o zw3STLFQ>IK>I=?aoFja8vt??A5ti?T~wnwUE%Jo%2$i7OaGbQ zo4?fN_{_GJ*h$OW)<%`wa@xbZbZVHQXs^_TS=GIj%_`C>RM)%t&u(e0x_ji{oVgvp zBYr&H*Iu9g#r$gd&o`T%&-{01zEsIljXz}}pseH^XG_F#e*1%O zUccY3uu9jI`Qd@TtG}J&aM`wdm%y&xT}_L2&0eIy@+l-GTAS;j$NVm(Pl~Tc^o?lP{TY>OsR^qr9z-*N#01)OYF6tG=s0ZNum5kDMobU#|F7 zFh%?G?t@L`M;b*pWOs%AJ!QJ-rqLsZEP>=DhdhjhIM4mLu%IIJPW!yYHi3=tH?o&< zZV5ap{_&Hz-)5->Qyn?S&KK14iy;N)4b)FS7 zUa!{9nLJfGrYgk-4QWwlU0Y*rusdd zaZGK>{p1;X%3IZ1H|?6CHfjB-R<9)*_c-{kXegDGrJr#lABi`LfNN^)_zTi`UUtm3xwQ z?EG%LRc@`%zLdKU3O-JXyXn{C=g0Ok$vko0G>3yC`d_={4BB*bqbB@f+y7zz+={l< zM?!tr7<)=jI_@z(A?lekdR+0Xj#Tk0#D>wh->ss7oh<((^Me*b~n!s-KtKCyC{ z{%s0sE>~>5ugP2#+@$5~l{0OIvY>47+m5^yWrxh>2gn}UVd}ir?9}$h?L|BVH!6Az zkAB)P*(FW*%JGO(D_8wkARAKL#{cTLhnH*M2fKr(t17CRmVXd?JTtek_Q$ftzboGP zKh%qze_}!8vM&t&0#IDd9&Ttc1g`U^fPg|XYCa{lr-)Y-}l6rNpaaqHKm z2WM+q%@0hRm~rq+gVu^$#~bHY%~bmHTU3nYi2l6Cm*)T7X}(sT?eT$vxFrb0GqIVyhvO2>0cDLgf#gn@nuZYfD-DgpvYCWl;??tE8BKLo*rENa$ z`|_gP_sWLY(oVjz8?lSHkIh}gt$A`?bkE#H&gKieYm9HKD__Dk+4Yuc>Vvp9P3K%< zuJ81Tmg8DiIPaRwzWn$8FP}?KXPQ3QDfz_>1mPCx8K{`p4wXJ3a5ktvSJHxiHwBuCf%Wp@X7Il4deH!uoyXeMuD~c-J zs}~hndQ>ke`stA!7@G8W`|e{~mM0iZ4<^W=d(- z`vp^%^}V^UbXni~3tN{d?rqmG1F14AO^JPUt9EbZ#;}~JK1O?Mxdg7PGoImgqvo#X zTGl1XkEc$rnpemo(($Cps^jLlxqA7JKEAb>t9*QUXGCm3Jo901xm}<1;~uS=AKG&+ z^b>ddk;9)}hp|33Inl(rEb!9KlL7I$s}n!`Xj=ccNPO=%@A!wSV%}-J&r6gpUjMyA zZ~2T@e|pa>7Pk2tP<~~HmC+i(gH!SGO0xxcG0&6oz|N6WrOJT%7h~y7-DRNshQWp@Y}wm)b-()#N(tyEl{dsq7}(8I98q zx_mfWZ{@#@<>#@6nqmg&v)hmVHWtyp(fQ!x{0Zx$n{3P!`mJYjeSUkpS)EniuIs_= z{m@%p;a+tlrR2l2`|F;CxwvhYe!SbEpYxiW1Ey%zAU~;O=qwZ@VKee6OP5sZjwTeAE|6b>ThkJP! zZoGBi)Poy&JWg|%|EA6R)iGavMt<}belhO9k0*TKtyY_NqPPC>{uLo2$6p(qpP|n` zD?;s>$dZ6XJH2l0uCS2d)Bmt&`k{n))l`+K;!4qlfz$R2g&q|$y0-A3)Fzf=lj3;9 zKS-bRQOYrP4-=0)G>J@%_*H4Ef8x~9zn;`i0lJ24{)+G;T zp2*#--Y@q?V8-3O@#k5x@7}HcQn3EPt9wT()E?aOo9xcZ*Ha5v&1X%a@mD$1J*@>X+mk=~bmZ+;ti19g>~PR_BZu=XtG3B6cW0Qdd9P^p;%`1Y zY1}n{$Hw4F6B~zI>iMAw4(b`{OCcFUa4V86d|!kJMK#>0*!Skin@1D-6LyDvJXIZYNHwbP z;>UgW3Jd;**YOMFTnf82`^$y=GdJ^>%HFn82gm?|*#RAGAJRxWLa`^YpSl zueZxq9_FuI9WQshe%3PHcoWlnlc@KdS}*#aJ~5jA)p)tLRfIy_<4OCj>I)ujIvKWm zQ>gDd??-25Z~SmgA;3$)_Lp<^i*%9QkpfS3%1u{Z4*AsKweWG*`>MWM`n*Y}OOIA1 zvPpF+L?m6WQx*KX#(VQTi}m``-iHQl&Hk+>+9JJEf4))L+&!OHY6nGUv2B^KF6s`` z&MDU~Ic+wsytt~{{&5!brTG`7w{AEUvc5lm@v-T#dQ~xed%rJTpHTb%bQI%Ofz_w8 zc$`JO4wPpsG)T6bHT8<=#pO#|pWRVgqglM(ZLYf3+}xuK=YH?0PM@8y|*s%bzhh- zwb4aE`_9ap>qWQTbI-N4wmV{Fa@u))aM_+&yPJ1OuYBlp=?Le4vMmg@9ZhYY%W!)9D(2oTpg;d*NQk5@H%mzdjb zKDcehe3a>$x55pr!=_Ukj23R667*KIr%9V>=M_oAM5{Y#JD%}w|6e$ezof`ySBx9!M4w@m+cEnIcTJIYg&tHya?mgw!3d^@!D(T<5T zR<8bbFigetcAoE5Gwp`v7pnx<}n_3=lX~P-aBPJWOs-|2nI~mIO@#=9a z-D#^Qyyz;ran5yj^g@{>Rw_SA=0|28y_51IZcpCP_fHfHK3-P;6x(#Fy86_jm4A|C zbAFmj`X82@y7kxb7f-XRzMua*Ur$f}ulW908T-1DnwmHNU)*>Go?(POW|iNd-bER)-pgyeV_34Ug= z)0nob<=MyA;l~dcKJ)V4r(vpGbyPG^>0-8)WaIaxOLnFiYA$JLeQ@+l$E&Z!3oDOs z=yJI&-SnrzPvb+o=bV*>GxI;Msgw<1ozH(_*6XPnrit?0C#NVm3C$DLO!sq8a4~c! zm~it#&g?YL znaiY|7VnN(6TB_u0AJdQO&Tp%TvVPoT~gKfbl5F(+DgUB>F$pe-(1|(y!S}zkSyi`1bx2w9?Eyt)tphtFTe4}OxNmk%a>vy8!rTvaDG{qVB_yn{YCB>m!Qs?_TSyBzdt-W|GYl;hM&R`G0pxtY;(%u z_c!J4&R6@u=I<)Vc=7esYteoNPl-jd6u6%` z8I{$n-umxqPOFX0qPZV#zdk!PvDoE8W%D!TsooBq&pylEX3#p4#h}JgY@OS1m(k+n zUWPBr3T3hcudNfg;%KpU+PsM=881DzEc$ff$K3s1XOv?zrF<2C+BV!?vR62N7l*xn zPLZ3R-|ag!g-OelPI50_D&`t3a>8Wk=H}0H-_41=eg4p?vsX2v{^(ld*0E3XKDZ?# z$)w_O{M9?x*US0GrYN$B>F}-gOjNX3VrDsaYtmcYz=mgaDvmQ!&r}52KJn0=r*^}j z)Nr!)){Gmm(F+=MTzePKP$->nMMc#peZqSO<|Pbk8aAW``AVsor=)ySmvqQ|H>V=| zwBM4p7ncMX3q&*z-+4DNw5j}Lsp`oqNe9nfICxgIVbSKe`C5#!s}#FAK0H{ZCOFB- zdx^obVisjxH|6+?_jX+UxgzmJjP$&HUzxYFXijRJ+j*X4&T)0SA2(2KVv#$)|Xj^+(D`57;kSn6?p6R*Bdi=)n;T|xarfIq`>mz zZqFjoZUc#P`+qJo%yd2&+8(RY8f1DUw7=M3_L}A9n@=8j!Ti;{WY-GQf?E^pejU5X z%suZ^P5raN0!s>tqc!y+vvBKV|s~f(}YyE#1)6!Ci`Yw-*r)&tLDJk z*uCMcD;KNnYMEg;tL(Qa1NW4SeQnAI&M@^%Nc`t;mpvfW*)cPyI7Ca==pX09g-P5O zdtW3;+z&n}$Sali)#QkY=?%edpYV%6u1Or;SO4DU63dG`UmMYR2WGLj`)zJMu<8H4 zZKfY}_sssiUZjS9NhFU@`^Mmavnusp_N|ql5q4hU(ejflUCbv7>=RiWSFxvDaxUMy zvw`){_Z(RswmO~%kG+#@qj#*b&hY2y3(#&>n5eWm?Z(|%LB&QJlP7b|O7A*0<6zNY zS)+rGjSt@KpYFrne0NP&xZ}(0&HH@*gq{05HSo=;?py1ve(qdlpS9hLSMlhp-f1h% z)-K+ty7m6MQy1fMb>r0B&&Tfix_J%TY^Ru+8h=ma)V=Pon!P^geUsvb9cRr-ez0)u zdTnxyYkL&C@i||E`96JY2Ssf2+4z_jlrpcge|hIroHyDlhY+o0paITs5;_ zb1JxIw!CCo-h&R6m_?6&7+tk8DRW$_&GbkmVt27`U-88LJ8_rKe!P%+@wS=pjnyLZ zm27T-PXtaLkG(J_+#oXCX#3UEN7uZn*fw|F%i>!dH?s=2bvE5T7r+r`$8y#3KF{ra zJ6k93?r4r}&Q&>a=bH9DfN4He&Om7Nm3HEC;AMONP;789en74eEUmR$ICEP~fbQ)2Uu zo&|Ev98W5o0vhUOhb1KzrvAFTrmJOsfmG4bi3gi?4Kz2!E-Z*_XR@eMeLC@G+VUmK zo*rjVdL|Uf`>KdB<>$pMPxfDZlCDwkA!4G;gH;(uMaDDFJp6lL6~{j}5%oVG9)6p{ zG9kHj%7*nN#tjZk4+^fPhc^GnIpg+bnNv-${w2=FR}l{kABaz z6SI>)&rT3Kta;ndNBjb3esTzZGnlwC$j4 z%+AQgo{JgJ-`id3<2b>r^!9`5MZ1|F{+E7O`}=2Q-g4%$3&OSwIZwTmVPPtpKl{2) z`+u)1FG8k&Ug&S&vNZP0o}$|C=c zZu!jfy;FYS|DLEFKjp#}NOApo8~n%b?VmZ!#Z9^P=?QD^yE4A zTm16+h9f8UehW{`J~(~n-a`umTc*3|E>w)Z^oxh#{EJt|>ZCQ#e|&#Oh0*#$b7G@% z>3oi;D{JVnE%bjnn`!ur-9C{IGZ!z5zpzX9&eyND zUtidCom>)he_Pb{sTFr#Oq7wm{;KlEvS1zGIc=3rP3G67Uj!e@))Jll_-&K*2h%4T zHeCu{{3o)Ypp;?jDaA|tHtq#c_A3iNcN(Yt_mKF>lPkI3_!+&4xM}7D9&fn@2?X}_cweNQ#wtBw!@@L-C z<1N;`*E`CuEi%4j?NraHa(9(bj;U^u*q5q9^Vlw5uG@Zmm*hP@eVfDmpLYD(>8ZR*_z6#2PjG8};xE~ZvzFIS9{B8F{{5^Z&+Uut$FlA&y8Fv?1KXkv zzqckozi*{sS>dySDJN@Sa->a+u zb)R>?3-9e`M6|}wCiLoPPFeOvoQr{>EQWzW6-R44GcU6w9@ZoW?ecgVlbwItLhNtc zg8z+^50*VSQ2M9NR9InhngOGg=Y_2DjlW$N=-zr3Hf_t4kbd(M_4lh?_vW4sn;IU? zy4E>(`t!I?^Qt|fo&5Yb0`;<<9NKif>AbjJrT_kdxpVwkVlOOpzI8TjwPW7Qh@#^U zr+LP7`yAZiXVZT5z7WBsx40*qqN>ck;@D8cznMXD4C{9u`jb+i~!&=}blz)9XjR zwd7i^X|xdXj&;}~_e0pieEM0N!x6$(e{-U=o6kxfXl#9abDL^R(%BQ$j?Xttn18MB z^fbS@F*7f_$v)F~n4q`I{OPk8y)&nT<_Di!kbjJqEx2K8ikkEEUGn$tf7u>#X0NJo zY=o9@&;#FCZ;O;oZr;7K?_5orXIZM)&s)u_*nIx_`nqSv!Rf|DrL{}5_W%F;%W3bf zo!9RD|GejB^BeQ6_9hz?6At=L%Wg@#Ge>IPxf3ssY?ArzQe}B@ruWW5rogj5_H5kn zcJtnCi3`ppKI5A|`^r~^+q1vDyOnllPGq{oBG2h(Hfjc(X;&;)c{g#w6TMt@+Y@n4 z3fyL*1s7ADidkJ3?O`>WBq>@t)A)zGqJ8$0iN3Nm&!0E1$Ul*F&}UOpikGiZBI5$) zLSfP4jK2>?ZIBc`!*X9@mx|_>OQI5y2h=t`ayYnvui-_TTr%frg9d>+EYJV(9Dl4S z;xCZZe1~K1?2rQH6Z;J(hDv3t?s#oftaG1j?g!>QTX`SITDDGV{JApSWm7J*p)&J$MW^dkWShMx}-Msw~G56m~tmP}en_=P*)OmQK z#3ZNvKi0+i1s2K7_FZ`N|8b597H1VFNJ=Dba>!?PIc)SiKm3l%OP7pq@%{A+*|<0? z7#o-D3voHp?{wASy<``6WfKuJAd%d9&X?=+JS9uf6#D^JRNIDHg*=TNvK*YN+vCIqx`O$=Mel7tNpb zb_v(|l;iDxFJ4ITQ+7%|zWajHGNJg(3!fb?=MukhGudV3J3juF;x@JYckk2$na0Gw zX|C-&H(ew9P|I1*jkf85x62s6)ma(dm{Agacv}8J9}DG#uE`y{(haY(6uW^ zrtO?hKBto2W#2kpQ~!O_MGIEV>pgxTyPs9qcioX`q5LbH5Aj(Z`=-V=zi;#7kLK@0 zCw{GvIjeK%o3g{{wO9KbWp})qwzt}|+3A<;Ir#wn&Z3XptXtE}zn5{}h%Gy0?W&zp z&LA0kCFuiasl?9PI?XD~Db=T67)&Uf&^1?1DCOql&1c^-eVQ`!_O+dl&WnBbDqC}Y zSJWn^Ymn{Zh0bv&6!d818cf;Fkh|vyX|3z!tT#JWR~0)dq3mV)A`%w z&t3I?`|Z!-s?vXsze}ns8TYUMSKD`d_ukM~GqoMxmb97u5YjCRm>F{2c#o{`vWFzge#;I0 zlHr%-_v1(LiLfoo&n`>0&J@2hfvaU-zf|Qz@ukakn*6m4{yOd6v9s;k)>SHp56`(K z?AdzOwXuAKfz+H6rgI$`jsAwLeJ`}A;P%R^i$0VG6<(jDuH2Q(S$$q;ckliS)?8Y5 zj6VE*9bUBdMts4x^DwOaXc?xV+x!^~T+=r)UNt z;G2$ydrQyRWXZBRCBtd*3CADzepXzNpR=C5MNa+S1kWx0g)BFo`7ZhU zL0Gf(y53HMLRXnhE^`w)UuDeS?lX7#exIcutoXOR*(e}8sUc5^u~cUA^p0X@L-cp(A(;vl6edJUT9Tda0{`-n4o%|~86PE99wJDXE?Y^MSb%9fb zzr%u{iofbgDK$=ZEwh?sudI3e!={Q)t4i$9Z?>0_T=^fKl=RyR$T|H<d}*_*H&n)b*c!>w5`aTdPsV2M^JCn+GmdU zh0ORhZtv=!_B%Fdv(`PQiqMbyemv4W{yc4+)So@?`I^(!@;jaUE2 z_g`jthrN4#Jh-0pC&c5`I=3G^EOrvfwTVszb6v$!5+moQmTZ4L`(*tMku6T!O={wT zI;&UAu>RU|G<{oKq*Hm;r_S#3jpChOTe-#OC*Lj;HodZFf&a}t?A1N|LT4xaE7-c# z)^S2S=e^GpUvK$-&R;l;yZ*QL7YW7m#kQ7wk8SNZm8SIxKjP{PtJ@Vjzk6qyckAJh z^JX)YCaNr7cBRmNIk#5d`6-JRN3EUqY}IaoYhK*)jn@=zP78Qs{a*8Dm?)2>t(^() zyb}{&zuL`w$~yR9u1fEuF8TUJ%Zn%MhzbA0zGTYdS&R0qyef4frGqIjwd~Wo&gGk~ zRCPvr_2j8e+m`StuP>|gQ`@#v%MBKXA2fFRU>wm$<``zX!^f7rr~!$i(lXM7))~+DvbSa-$P-1$KVklG-$1O@2YhBmP4#7rm_8 z?mGF!yJ@SIo=rM5Juftnb>jDs5Y8ugY&)fu%IEJ3`#5_(``YV2x>uJx{Z_Z-lyAxR zQ=(t`x{ghc3%$lVasJvh-U{E1PV5!f`Q4_eF<#VuQpS<{Wy_x~jz8(XZFhW7=%*Cc z_+L}EiMagZ+q#sc$iDdw|HR+tmq%4JzrHwCJB#;{l-UXso!fWs-?P=w&aK|c8_zcN zfT+tlmURsWraH)_Okh|1^q_L7@O<71r=LAhhqp}N(^foNCa>Y-o6xTK>BG;j(*OA9yB=PAO=In|#a?GO-;H1Ytn*!9vIv8b>HS>o&R~tcDc_|lg&#n^<*vmS!8CiB{T2#)pzgTe`KtBFjeDH8I5RIjC$%I$57eqW8pYOA`1^6$Lllt1npAz@|>)F}c zReZK`Z7AKutM23{D&5CZa#GfNp>aTp%Q2}}g)-p}X00;3Jd2ah&7tWD2bZt1ME8_b z4wJLR3O2gaSFM;~lq(`F($*wt$QzZC<|M+proF4cIe3Csg0hZ`GUwl&209BJmMn3} zTz}j`;EKD@;$2L8L(eYQ>S*$acZPwnP%C4VzUWn{7ACW4mW#QYD=yx0c>Ln##*O+a zmWjy@oO32h<^&ozv+1O#aY=d!*s(@xXqv2zkX?UOdf{!R-56L)3$g>$p1=EbGnyuQ_E=J1s%8N4;`lkcAA#Lf=roi)QPWT@jcT zE_~3~Y)#J+n@u@>$3ncD-XEHn$i}b!@6lpqeJ0~-(ff51B`o&s+V%45`ueZu*37&- znR`KUXXLqOZ;Lq7r&}IlZI`g#w@5GaP2V!XiV7c-*7yGo1qNK1;qAw}Ezi%sr6f&$55&pLpS5b zC)KH`OXmLSt`gJX15b(RXL@_X62fd-*@gUyxh0SA1FLoyXtjYJ~irZxHS9yW`t` zqs%87@}{{f`0Q%mHSh_@u9@icBtw3_%Zge5Ehab2>X?lAKX09L&SdM)sWQRYAs;0DMPyB-dYPp< zlqPze)KQ%q$nvmOYwC^VD$=Jp<)(BbKYID&VY8J^-_lF1GE<`_%=2{Bn*Aa>j^oh# z%!9$Y$EJu&$~CQC0~@ugR4RFYRdH)-UYcTQ8k z+a~zYfg3AxT8&+z55*@IT}}!*_HjwCxT@mYRu#UlMz$%W$r%a&y&Pi)DKHD+)bCQaTrO z?h#~DP-(oQQ{btW9H{z=`QMB?>E~CpMRkX+lzse^-_rAVl2hLP@^|qYzNM}%ENYQU z$d}~fbT<;c?SFQs&*B|2+*P)xjF!F*oaXoBOTx70`C`w7lmD!_&+l~Y_2z#Eq_-XV zXOK|W|1~OBUt&wl`-jX*PI0=k+yr}1tz@*{B&ld=>hBiWW3+t5B*!wTbY;2VQ^E_2 zBU2R;mj}(^WN-I7LoEU0*F7y3*Tkce@x~Ok*y15~JyAQHo z-}vzXhreEPdevWZ*+om={yyu_`$zLN|IF)BWi=ggQ46E>4EEH_Dsa|cxiX#C<%GM$ z9yQth6_ruG5~r%QMUK^Me|%xGdP@DpY^z)opRU)2wl}kCGIx8fkDC_}aG+u3G+|Ay z6Ah(ZM!h>0MqPLwF~f3_rkdu%s99Dy2bfC_Cp+HQs55o?0(`dxTPyYFVp^lvq__SG(@x!*#&uV`=}gr=vt!GuU-I5(?XmpQA1M*P zKj~Ijd+zyC`#O`)dnDF=ymxZ=j_WeHS3`p{r-tRBfdT?-+J!e@405#d7e$H|~D9`tZB%nz?zg55I|UWL|iCNlf>4_HT!K z{+a3Q;m6Os-O`k>G~_nJ{hLx3Rt4-xcx+U+-_k5+#sP8Jucreaymyz(Tw@a7`nmB% zCx21|+oIa?Cw0?|`1)mUFL!QiITO3$gkATPLyK%|*SVXU-q94DH2upfAA~e72<=_F zbE3P#+J!!I&lV-Fv2;0~+SPKS&|!nGjh6p}9bZqmta`XdRFU&s$E(o$H%^E;TDqTV z@9gKD@`1ZUbIpe@(>_mq?ZsLd|M0}d&6-Vh*8YkIstVqlTt2$Mq|fZgjtaZQuHsX} z?l^0txb-Pbv{*IC^f+U0fQIn_)%Q6IuAVS1v@LyP);Ui;z59yFTJ{yMZr)hDY+8$- zfTCr3ZAsZe<#}zn<@^GrRV|u`5>+{_ohY zUuOTV>+AB5W=F3(Wli9cuG(%f?PiG8)t1|rZV42dcf?M>{lUe`A?3oMxFHuw5)3Y|`OU7>ln`!ndyRH|pI)83`!0-HV z!~MG5|Ba?+=-)ibYjgAouU@D0oK2EXPNyxu%(-c|xtrN+&)Us1RnD(gP_}==QI{WD z&wz+{4}C4&nKE6qe_0tAIt6f_nNwbrSP&062>=xTXTx*zFMA05>pN0EgPC(uu*YSF za&~r)+(+9iXIT^ldHJhH_U-Ky&sl#n);!|T@%wMOW!0CMczl1TwY0N5eg4eKZ!>Rx zy(s9AeW8u(KIH~O;X*EE=HoNA zn*M4v;LPCSXtWIK)Z@}>X7yd6lh`TX80HlBVGie|Pz$zfx#TUZzaDFudrotmG)16g zzVSA{6I}{2Q5{O>C8r;lX7J=7SLd9mPLo1P5~j4?<$IR#z+n0cj?8UFN7hLG?>VOx zZn0?z=OMwm?h_K(4B6{W9Qt6PZ7|#XvQYEMT_3F@j+^v|mge;C@tAtONn*u>rIt)L zpPXlBeo-F3_sus(MS<6|($4>Glj&`=meLWL?d>wnaiWLBc{?7STTMqaq*ELWws5Gp zwN@&~YA$i?yewV6W4d6Zh_)jjlc(6qVttYfvjX3{&#H^jja&|ZG#`|v_ zxw-qVlwLQ>(9bgISDj{iFldP}pONZX)%2Bq*Sfe;e^uIFDdbI^Jb&7|N5Y&-?Pv8o zTe~f6NAL3;zrR*bi28W!#mWZnX={1h%-d$D?3}nSHT=NUrPh|=^7S>J0w0SnTCCW! z!fBdr;bxXOMru!j7qY)NWl`m`*+4TuDPL$-lIfy(S04yj#z>{Kb~$g@Ix|iB@2vy- zXYtJ4eDR3nBF&Q&YgZK$!oM%PDl=br&B7Uy2d}r>7h0z}UG!zs zhuC?a9NG$<@;n#qytHxUg`NYUK4#b6r>=Qx!dcX?M(iE%X(%QORUE0uA8xbXB;v*7ce_r^Rw$WZ$4+a2jqaUTx(Dc<Tmhu{QHkstb&9WdlobLY1l+Qb9t+NR^^Gwr>FC;d5a$0`kMFe z<%=>Q&w4-ZI5U$azJ6wBRHBpHl+Z^_*34#;MeiLw$$nfuW>@p~>SO7}?{n;=tbZ?; zIbUpR9NN85@MX%o^ZGW=Q!H+?EHSkye75=E$txe1FV20iTJlkn%DEc;RV&3(jrM$T zf4uVb+3n%i59{XF8JFIA@LP~mxHM$zB9_}ztRCK8p#J`Fx!pe#ySTKnkJ8$_4-RU7 z|F|;q`diP_pDMD8jOQ7YPJ3i;yT0*&!o-x-a>uUseXrX#ao=6pdK+ntojC`!WoIV- zfA?;KaL`t!xUW^SBmP}ZT6H95dV}SnGl?yH!j5G;pNftjDcihi|Ey1k*joC1%!BuM zsC=EOqUil*Y3kJz-#%5ns+z7o`Qd?Y3;yS>it-mX55E3l&q^cPtZl`cGu^yAdSCAT z#__vTW}6z@yxp^7WPduvTJ#m2{TS$y;voF{%KP8mzoxpVE!TQkl~}vI?uNzuH=%0w^82Rs zwhvcL_OynjUSq6}`X#*S+lfg9lUkQtUFGob`nITcvsc`=s(0M_QY0GE_g*S~()+-_vnr)``}ZWT%N4m$s}@VqNHA8pGOSCQK;knxy1?fKc+{k6t&y$_lLNF zm1()6Vgbk0qZ`VNqz-y5H(Jcx?aJu1bb{CGo*wP?2Su3&U!Ae#YIb<he{qFEXc+TCyUj#dFQp(#1v2FINjn zE$)?lmTGCs=XH@YvggjSBa1IYtlF~itKXD}g}SU;cbFYA-ZQ7ducEH^vtpHc36I0y znT}yAk8G4H`NJ*Dt|Yp2v6$^Mqmu_i-693_HJWQwt_q1wnRS`BKj6Y~`>8SAOjBRW zA6mcF$63L!QF#B)h8i*XjwK5-n4Y}|Uhq5D(=KY!#?XfmD$^z%E;-@H=gHA@#B!mv zdZv!k2mS5AW|PabwN9i99G!h4p^YuHDQB(q0sif?^XGrgK3G$BmFd=fW*0`$2f^GA z#Wp!|KYcC~HgP-azvoj;RkFqQRFu5T`F{9X(0?RbX#-78s&W3 zE0@=K@LQe|-qJTyzxMXjkG|^y-*WBL)cRa~_|#INBb{>hEDGljGjgmiImJ z&Ne(<5nv@G$2eX3?+S%wv0_e*Tb_6J#Yj)`y4oGHFW)PpSfupR#P=Qf_FFfso*Z5J zN9)^ap0ckmuAhDS^xfBYx1{I&U3}ra@q6<~pZh;PIB$(sf59xQdT1ACe@?KI2zPh- z<%WN?vtI3(_ssD`Di7OSy=`|^ZSS7QQ$0;hbico3L08wU(+leBxc)Jr<~#ZO?J*g= z3=9(13=Fb3hFD4}3m}JVAC1n8g^K1t3lL0B)9U7hdVl1{@jG1`MZP6m} zEk~PfEmesNJI#A?>mu%&{dYDPa>ET-O znU=Go%g(+}J*1~T>-^6{8|>%Koy&W3?gj45o)F2+T}Lle9^g`D%ULL7*~+ebY05{P z%5R4?71S<8=&HAho;kNP(arbmr0jzazWaPW)7A1cic#^0qwS+fb<5WDus*KT+hNA% zpVq@{S2F1k&&>+i%}1)v@!Hs@duKjhwZW(6^j3p5&9hIG{Fi>r@7~9E4Ot#-f*n=!8V2}spn}&w|HC@ef)8{ zk8ZG`Fax`-&&20m(aV;-iTW(b@#*rZh>Zr!--5;X*$v#;*^529BGQc2XDq!G-*98I zeB6o5X&su<_4{`J6p8)+`qP{9^?y#^jQpb4RL*nngwK|JB^&;m)Tp_=Ge0Ao^2u2G zV2;|#p4jXkvo%uRWK3C~;B_-Yr1{BD718zbZ%u`#MX%ndT)k)c%Bp>3xf5soQA)B- zu#Y$RalZH8yQPjieOfNON)FSiV$M61#ZUYD`I-0mlh?kdo&MckJjv*VqF*;lnq$p; zD=~jz3DwJ&BT|DcrO$o-lawB>oG!VY^@jY{bO#sizHJ}96Lln~#6ErWHE+ob>D#@} zTBIKy-D%0N@?_4cS!=&v2!EL-Enwnwn|q4KG4VrBWTvSIrreLb`lw^^x>tW?^w(XT zdF%G=+y0MVy!-s)?%Vbkzn;CaJ$uJkO7Zei-KsMj);7Nx4YY(Ecn>wTv1ghyRF$tb zG`Smey0g0Xzw_5e2dY=*9t{3=``7_H&AMKnFr5QuK5h85e|OrS*~P~46F8f$Z>|#H z$rI4wj$7r*H!qXn*SUv*rz_-Ubxipm-O%4$Dz{W=cH{w`^UG$;h&X*G%va$^R55Gd zU!zCaikl*)WTZB;=m%H3Xk=wcazB$Tj(*J}EYQowY$TMOv2Jaz=7dKsFFMpuD*S1S zJn-oF)pycju34$`)}3l|S)?zYvmj&R1EH7&>%O=A2)28c60j zrk*|3p1G>xtJhIopR-4|OZm+!3JLaQUbyzk5jLk68yC*{kTkpN&~M++R&zi1X!doS zTaFZ;jc&iHDtqgST46v_bHxY0gS**SIr~o-D1BXJdO!cm!G!n!RIeXWOX91XbckhX z&0AZJZ#$X38#Ia>m@u2&oVl;}m~Xevwh3;9Duy|`mhBGx5NBjO?f2K^)v49;Hr#t6 zKW8LpUuAfozRIv!YE6@i%l76i7ucR}>o%E{X3Ajuc%7hbiN>t!Gv@pWdVaI@TulSx}57{ zxB=t3w5L6)!b%78?#UX?cJGwW3rf9yrv1#0l$+&uF0fZ0J}1SPe>tZ1LLxWgL<__I z6H6rz@?H4rb|TyK&VgUaT3NkQ)@IB;VEsg}DVDu)jqAf@2TS5B&sOZIEqt?c!R)|V zSuyoVZ~5DH9+|j6V`9ePrapnXm+CpiOJ#RjmVt63Aety+2*=d zq4)mp)&DhjwXga9;o_EN>zW;1^9>}nwdFSN_Fj9(SMI3Iwem&othQMTGV^Nsxhn4* zxO^jB-a5;q{N?efhdwIyKjm57bSUs)+3y?a{V6RG!6|v0^?ASC_q45DRB%~6YVVI< zE-!5-{(IB;dH&l)@6Yik%x8SHHNtuMsqa6Ot{liNeZK0(-ngE;l@-b2R^K%%HEqjs zOY*&c?p}K5;ju^eGd6d{T|FDS{e5VDx!MJ1o^S2uZ*)XXbWGl9vR*Go?&59pzKoXV zV(U9UvGQ^&%YB=1;NY8gX`SbsC&dY5*LT=f|5cm5bK3U>{!vZaCm3hVyr38!$?zpq zV!xB?p=revFHW2<7QAp}fxv2}Nwa4Pm2Byl`FcVhuj6`|Ln3p1yIN1^9KV&osli)4 zuOpn`Rbo})fzgN zt<8vwn(~QZHoFr8o6SWdA;)`nSH(Wv^`(7lNLcZd-t3t84f&1pi_W%fKA&}PUv16A zY0O2vS{s696dUof{_gdeWVqmW-kFoD7j|erWw-e={f+p`KDWeurQr>CnQz+eaX3El zihjmr-pseqH=@UDb;IpS7WZi}&m|v*LNTY{Fje`?6mW_%1a6-2d{R zjVr$_+x8a^Pq?$mhBO^_u70^#=EH9-n)^$duP1(aTp^E{^8Tl|@& zD7ycn<(lVu`!5U{RiYm(5 z`(~E-$(ud+w!W?Po>M~oyrwOaMb~&_ZrGPmcwe%{aoc`5ee>#{HDhV}3DJ77C``H`pRw4YW5eE;dixpU6tk0M7bTMF;Lc<|k{ zc-~o-*PZzr9kQMMvgb_xwLp5_`tDt~)S4bC{>WW_$@J^S@Cjj!w=7Q>tvtEu{`$rV z)>`J@)VmKktZ_{V-#VY;fM^|OH8e!N(0naA6C*S0-~cL_=Pl-(%K^!cjrnq20r_N}Je+Us7_ZOZ(&&hq%` zA6qZDoe*92ddtCsa>>o#>$XU9*R3};5MH1t=({z_Mf1fvsmQOZ?Xn754W7M^oWI_5 z`pTm}#W=UM#(ewR=vQ46)UF(VBJ;;J?OnCMzt3J>_~qND%f4SSYkofb_37{1_SqRV zpEKWhw0!u_BqVFO)?!ggqwb=rTMt&n{>V0-tC;vfrE`_{2R+fSDKjqx@?P^fwLWRp z{N`Kk@@My_9h%FL9NQJB#$j`fYx}`>#+K#zV&QVy`NLoVCH?e5Z zGQpgmDNWg({5Sd;F1_Epf79EZ1N&aAiN7f>#Ivs3PHQpOhT=FQ?}`4?*R2h1p3)j( zp78Lx=Lz%j2M^CxGM~%U%G}Dd$hoRw!PXXzt^L=osXBW1q&ZJq_;m5f|40j!{UW_| zr}aPHna|3=;KPgi76Ztbx{*%lGcK%zM2zcGvFq-c|p;pS#B`^CM_wsOsT|H|Ktznf~lot;CA2Vj(=6 z*ZNLrIejm6zTMt()rHd?)?Zzo%{f`yWP;J(4ndp3*$%&>G?S}U(^o0UeV!1xE@gM= zsbtB8!mrQot1Q3VS%2M1m1%l~!|VA6n@$THRJ+6Q*Dzyw#?5G@E}cVWM`9jWda$Zo z^8E6*K-cK8-39iVZ7Wo_u;=~|KKE9-VpthH>O~?404a;Up@QoaT4SjtKN7&g#~^>m1qD zmC(KIdC$tG2lxG^{Y%<4hrey@dg#D^}N7#wdO# z?_h);%bKlSMwi~!O<26L@SeofMVqU2XY@|>J8M~Cb(r6tVX~l3p1Z-Uez_ADM5iar zpW$mxeFS6@;qAjR5<31ZS{e zE|y@CnadcAKCND}geCIHCbyl&m45!GlN!ugm3&z80=`Tto4b#9YR}J8fzhc8@5I*1 z{(5}z?}_Lgk5<3?r&4ih?Mqer>uYavFA!SZcHyV9R`kvi<8SWYH^02ITD{EOMp00( zt?A{Sf4*`TW`C5Z*cEo`+sB)>Mc0xm=kENTYxc(J-;JZ0>l1!_m@g`_rkCrJ&9tw# zKGtr26kGAP%Kc~Vle<6f-L0u8oqRd|?YbbvpWindZM{2pn{$<~w`ggy^14q8rmypz z_Si6#hat;%-p5L^ullkXau-8BShsx>5a@85s~A_{E|IcY zS?j5S%In!j3NmM(a5@<(Y%A6!Yap`p-LA}CU;Z5YQfDS-cSRy*4XfSth*eB$@-ocJ zXP1bw-Y*eKDeT$xvgMSc372q4tM8YN_TCbyi=ACk{uw5wuRDw-%`S3Y>B&raaJETm zX~bD4o`@e6BB}=urzvV2nOC>L?N9Ohi)Zc@Oqx)X9Hadv@^xwQY+-?goZ0O4f8}@0 zn_!#O^F4^)$<_I=%=uF?g=f3(8B8;H+TrzWMoz40(%)^y;pv|&R!Ntc%sP8b#Ps8$ z%_h2H$A4-ayE#!%$3SndYUOsq)4Z&`GpD`X(cz--N08~3V@9vq_paJS5xMN;;l)zI-51}cR6PFu zb?QyoyYaepZ(CAKYXw6rHvE0Z`>XAG!AF_ncc(v|^htbucg*CiaZN1`b}Gc>h-aqh z{rZR`Q}ccrB_v=VdBV!~ z&YJPN?u*z+bZ{R_{F=0@(Q`MWE57N0+T=e@N% z(RaQ6mTRxKr=9&Yo!{45eah52i`g%-4p-PUhi|Voa@d+E1MV-LEeTnHU(n zxp2>f=H{oA=A_1hHkg2BLZ61^f^MDp7x$vxB1poMv+(4N_SEDHrgz0MW*^v8+S(ZK z#=F*eT93+h!`J_Q`*qIVnmK!xsdTe#e9n{I&oAyh*`;J*P?`DC=Ie#&;!_U%J8~){ zjc-?V^@OA+v4!_C*{M0iJ4=JA3mco9$ z!TZxnO`8Wg+h52?a8G&K6*2MeA+?I*iJK2j5LFDDWHh0BZ^48okxLcy)t8)@Zjj2h z()$GWZ0Yv7Z`aDsQnP5?e)!?>jS_Qv?Ror;*MI6$>Mj!Tb(v;7PgtSHk|**ng-2+ zXBV?FWK0}7SdyO>^~~-Jit$OV<(?*W{Z6^YzWe@h(msN6!pU>qfBiIRw&(XMO>-Xi zmdz5y=MP_~DKo#2I>+Z@a<7x@8t?Q_y%2NmJ@!8~txXr8W&meNWd( zX^+^l)z5x5_t&qF%~|04>QR~X-@u#&Z(l9SIbI!bDE4S>j7T-SdsXXn6{Irscw+}4j z_n03po@=1Ws~RxLXVM{q1D8)+x+!+T>Z@N@_N5Qo_usXiTQccsze-ug{U>P)&SmD8 z=kI^-eCr-thK$+63CD#6dD=Mla5@WCIR9weoO0qoZ%xI^I99toFF4Cz^r^gg`{qr~ z!~bQs3yvMpm|*lkQ032M|80V^+h;^g@VeF{_`TWgpJJqhmP?(2u;7dY#!P_+Nrl(B%-_}L@>?i-f7xu)ptbG9rteEH(tUj2vF z=1N=N9unK*AjvnAVdfIUEYq1sWPTmAe&PGz4)5;|#nN${daAd7DfXraZPI4z-Nb5Q zyvJH~j~(Z&&>g>;`tzFKdS2+Sxz>Jp^Wx9q)0aONKQ~*xto-D;Iqzj^czzgk+<5cc zaeiBUaaC2}%Q=6Ge%^iA`T6p_i(4W@~$4 z&4R>84aqaIY7z4}#VU2AO@%L{cS^V1{%i6{D5Ueu$^}pAKWCy)*M$~7JQnOv7lP|tl7T|lT3wGL5f!rq*k%Mi0?RPE;}>6!seB-qEV9j z=NlP|vWp}(r@wIi;j!?L;Viy$+`bpS-u|F8We@9mKK{h@f9Kb4|9;@PkK1`6iCsrl zv*l+;elZUH$$NZfMX67ZW%}~x(|v#JdUo>VdG&LKuipH5akO9D_l3jb%}g(@o}BG` zJoC`+?+O1Jm~UijIUQ5-(yA{md=it9!`0y`QNP7X_gEV5NrC6D&ZsS$>N72{HczEA zKuv6?vRbnE;VDKOJK7exbIYycTzBO7>BWbyH^@m&`egWR$DwkYb1lcEGKvJYHT)Ai z`#hEF)+r8ohQIAxGMfZ^XD5lZnTgK0)Y5-polSt5yypCH=b1)lbLPySw6WnMw*+_3 zrWCs`GU~IcI-Q$QKSnexR%qYKF!}m<`t({JJhvsNb)wd{;R9bD( z&ZdB|g8KxB7*$*^2!0ubjm~?(bh?XTKw;HvVRT&Ef6AY$1O; zF1_pf8S!|FwX-G9ug+uH-@6ypmmjZlunM{}t?K^5B9pw`=CA*(x+1x;(J}g&pVS`J zBHK)X+jkvXybN-}=RJv;{>xd8w}|OmbKQx%D$5h?9Y3GZe6!_KUcQL9$eMqSK@Ya? zj%>X1ijVu9_uVsxa=&igE>^VKe$&SH3!dAU-)zX4x~k!jANvdzrBf%QA1hu#c3unr#?0Tk@7I)$Jp}z;bf+V%r z!)0eYcyVxR*`b#owT>I!SG1IqSis}^?aY^F79w&j%bSdsudkXXJwf`b_xU4gRBWND}i zBkROhNXm1mjkq~6H{|O#>+1!l-7^0>o^5IB5-xwcvU%Er&#xj*I~d8Y zbc)bTN_Oqhv3Jf`X*GXm;ih$B^M&S|voJQ4PHBl;KI75NUOu;1>6+6ne%khg|CCNy zfvmT8X2RdPX$G&H%MuS*e|G+oyXL_?srhSPMOnTmeY7^`9?RmL#dceZrq4UHc;R`o z66Lj`(v|x-H!vBSN5!YSDHi!Jcw<`y&x_TYiw$#Mc%|v;ZhG1i`$zejp540@^VTZu z4{hh(X%TT%p@dibR&>(Mbt`U38Q)SqR`thge)55fqQa9`^?Ws0x$Sb#rpE9893r)q z1jUuJU;9p-6cpNR;j~b7#i``2=gx{b3bEwgzj&@9`EcQpWsh@2rmTz62``MC`1W7y zlo^vFx2nIL+ith~tfNlC*>76YPH^gNU(7eH<;-RGpfhtgSLOz~tl4Jpb=}Vk_wM#Q z$UUVZXuRA{bj=oP{TV?`{?e8vF`FG`ui^TB;w#JY&sx5&vfC;>twOiV)(x4T(!1iH zN9Nx~CS{*>ZkM<5d7i5)jFYRat|@v_Q(W`u(I0Vjd(%vo9b5}NO&*H9-QM+CM{Z-u z@3TcmX5IMu#Ph-ZsdJoa_e#9ud%Hc_z2oPPHPaTado$-LqiC_uzt3g5?t7~iK3TDH zuCHIH#0{6`(i1+?uKkgkr>3!P+sj$M>EsOVFF((|P1|;0o%7zPbKWafzI-gsb-(1< zr42KV+FQ?6_{6f9@A%`)DG6<>j%RPx6k44fyn@v`sK zc->cy*HOCvjWsW33L_|hP)IMsHZ((ijo2=$f`p1&LKK?1&GIjC3$T#NObNCfs zXRSHUbzAAfeXGFGBu`bQb)-m&mPQDoEopkm$+p@L$I1F=p7oOR|uIc5o zdM^LXqU2D~=0eL=l5$Hj4Bjpb-Fi#u(3YJ?kNg$uTejBl^XzXEc16^xCPYo#mUu61 z!|UW@|D5J;KEpUUb3JP`_d&PJ8%<|h6Y2`CHoZN1c(6iv4ev6bqcK1RFr?>iI+?^?gB1*6I+>YJbmQZgP(Q?D? z_Vw?Va}Q+Al-TIlYZS)SF3mnT&*t*rW(x-H>#!o3j3FNzZKH_JPekJS`UV)-)9$!Vzz zcSQAtHo4C+yNukXf1Fu2nMHY`fX^|TPoI@nJu>O(+rzj2$D+BhHjBTn?n-u>uQzvT zM5pg9Nqs|k^I5V#0!zcsZ|*R*5jj}{#`cN&d8)y zYwx+HCugFKPX-u-U8(Ex+{J62R>JdQx#Il|=iXh(HeO(urXTmxc-JW>r~Mw2W%s3i zSN+`isyqGWkz0pTmc+TtC_NFg*~Rf)Sn(a3^^43GEMzoqZLuVua$ygl6TmBRXSoc$5^uCGzry{;_4dbSMb z!CRtQHx14VAuj9=|R_ToYue3DZ+?*u2;AhRwz{{)mW?gi5h{P?%Kd8*e+zl0-8Ng=l_Pd#b?~fhS?VHP>t>${S4*qB^JQAy z(W}qiU9kTZb?x1YY}@Pld#_)Z@ax(-FID-i+jX~_*2U*XmpRwu-cu9XaeETC9QWxr zgXxJYlYL?i)F^*E_}k~9V@C{ z73z3zDDgV%a+fuFm(GPdc42H~TeOr7uAJnO*jrR#wo_%!IZkQwZ?6{3X53-1tE5lA zzs}{5N8a*d58p}fh1IJj{hpWdZbsG0tKQk)ou^%U&abw1W+zMQmUTN;IUh<^{QO@| zYMPDX{``y`$#WgvI&<-Qd%fPbFtIZ8ukb=gojzXgu-H_W&F$C3;;tU7eEYQb(Nb>x zYHhFF7dgGLYxe!n2$TPO@wPwL>y5uMxN0}Kw>H0NG7Zg`Xsa=yM0C%N;B{Wx{{&eo zg~Z=Ww6OhO7Hw{^`Z!bWy`oQb-K(d*Pj)C@yKxx@(}z-B#jNNJ+;eC8hi{v4rgElX zde&;O_j@vfXPXyhS^GwW*SPrCu9x*$+9cE;>$gXK!|^Uw zz1=C6$%!*<*KM1o*?VQm)$+4f1Yc%K>T1DEVI_)t{%tY7*S zbMA^oZ={p_9WQ-9@7DKkvYGw*;%EQ$+61?=typUTQZ-}z9qNn!c4H$uDaPCZ)sn(w;E z!l%Y_u51c?egDttdeL>K?Y=gAR@x%6FU!yJg|JiDAH)4ppX?3=i1i%Po4l@TmQ_QZ z+>@YFM^ltKGFPAG^vGbh$TN{f2F; z|2AogRn4#aWRK`5U$%7Az52)D+kI9B20?Kw9p$3bwA7;1ykzj+hNBVp^KY98)bUUF z|L_{q+MFGIf;swrNecFNOb;YUcTUjtXVRUUt7oJ+AtXot?7wfas*#g)cl*Asy4tPs zsp9+Ha(B6ti;TGgBWYwp%lIMhAjHa2I(tEL64?@fzMEy9+_H)K6<@lx>&y(f| z8BcySu}4;J&r@Z=2OMnt%-^r={`Gm!*XY;R!%qKx5-1zfdI(`Vxe@7ZzY2hwkasIClMY?R%5i^b*O_0lXmu`@@en8qKR zaN(QRc`payQ|8>lGyPY*QMtVHgVzbYUHjv|?>SxfeqVKUxi9bD&$Hj%eeh>fwyWmM zMH4>t&*AN4Dv+K~cW1M~v8U%*FLR_%kjUE}T=Uk9*OWWoqc&ygv%ELb9b$1QQ^K8C z-=_R{c<}Q>#)eYmEuQ8*0 ztF0k3Yv(yC7U~};z1GH3q^8roywg}VJubWNqQzFW9dFGpt}N&}Byb~Q#x2f05l&@o zFWzy_zPg<=zVXBfRWI>pvjf&7Cfu5QG9dk4h=fw>$(2)k_s$8qwDR`uTeEzcd;{Hk z#2y_HxTzZzH2XtLU`4I*i~GA&=lYqpXQ@jUPran~H^{=N_0VyVirHd!5>Nc)y;(7< zJ7|GaCs)&yuI-mEnst>uEPi;h?bzo3>Z!kqMg3;={rqnoARPN>FYgpHzOAM&=WewZ zzx#61;{f?Na~-+u>bHH8w<>xu(JNl!g~RHyARY;wJ^R;HPv3sGzwE*$b^qH;;kw3m zR~`K9^(X|uZ(egSo*Z&n?AA1K*+5;t*X&beyJqRCB;8pcZfxKzkgH=uayxC(Svvt?4EUt7c_B_xcBInR7c|<+WQ1XOGoz zh?ZM^W)bz9o$=+Djq;Qts-(zCLqRd}Q zE%G{J-bp*2`+or)Rk1)#H;-FWz_h_v&}M zzJK#9(P^A^YxAb4?X%zcru>bLnpE#ovg$_|&o0-HS0SvEcD%`}c$xO_PgUT~oxAt9 zI4lx-&)f1xuzT;LNla!uf=Pn6CQs!SwlXlRW=JfIm@v^e1S)TokCtNpoF0GlpZMW>Dw9Qqf zi!b}+hdvBBVB=}^@p9+!UHjJGS*KKWHz?{*nBME(ED^fL@9!3=-Fso}?(KVby?s@< z?bW&O2ac4zfBSm2W_Uh-92Nz;PY6I4eRetuHg^-Z|Sn-THLyUm;J&)r@3{o}V;e)r3tWG?w3T)539ETa#DW79Ms^ue6*n zX_b1(J?=M=Gj#SZEwhW-{aQm$aFcZ7)S|TcLYu#xJmpl_y1~tNXNK=&p~-Uhr!9Y7 zlRhQ?vDLP>DYqTx|4KL|ck$8-o%M~ArrI)3W88H2sO<@xn}TW)adB_>lHYbERfx3iI8iCUDiZj;M|5F`B)|NqIT zMoye-F;!;&2{TR+)uWF;R_yux@zR%fFE|!lTJ5C&Ao(DhGpqaw-Qoqe#Zx@ogra)g z7V}*X>6tM_=Yu0_f^s3RlV`R8m&~(A4ngOcA6d7vyPvq27{qyvUzF7}MJVOLDr+T; zgnEUJ^(&ZTSat}ODREifz0WVQSySMgrl8TY<24E=&w=~|hH%5$vW)!wsJH0Jp85?6z!d;In?a%bdTbIWnx)!h=Rb>`v0 z+C9x7EPFZkxfoyTP|{XcmaJME?Y#X{;P!75I?5;33BP=&?!@$9;fH=6+uAkr^E=Zs zU)mjiW8`yT&yrnT7NuH(t8Xb!7QcP@X};D~^Q&23|0*~C$kW$~qxPvt3+jNlF*LIGQDP?0-D>N$mOA8~wJw=X)M=uV}qiJG02eZ`)q%X7gOX z)#kmYyROVuvE2&yPMzC+>Opq5MReY;Yu}_#cjxVroPFZ)mF~*YM$zc9t(osDLOUk( z^%a)vk&1qB{N~TcK@W~wF{qgT{iqk2%J@Qa`NyYBt4b9^8%3kDT{GXO*lJAg^D8LX zB)R#q`put{ixQF~9SzO@p3Ix||4_lMxncA8Yfg9XV-0)LaB$h)Z)y{)Ww#by(Ocg7 zxvXqotk9hMtP9Tj-oICBAAL!9$#ot z)1LdE{#5q%@#Cqp|CQ9sRH>f7SNALTo_o>$_>)Z9WmkAF-;2B%ccY}FZSm&2U!v=# z&9&D)Tb(2KHaPBF(te-8F^rhVFabn#3k?Qa}0m+l=k zb9H+8g2`Q+t#_WYa^1wa`!xdZq%bZ2nH$>}ocD{nxpgVWPM#-gnLcr`WT-ivzJ5(| zp=iX$=@!$z&FX#2`(Ca*|HWHrw%=k0?e69HXs!rc)^Ne4<#TkT@}WQ9uNquf{aq*D zBvYU)m?K){p9y2ezOZ);TTbv!it)7ZE@r%xiziYZs{AWAYFOeEA z*;iK<$ZP%hbG*KK`2&`aSDw}aOp5-~XMWoAKu^oyDci2oe-5S|vC;A~S@EJ)U3q&@ z>+jApRbJkoIUe|*=7@cnI(Nm43nHJEwf1k@x#&Vp?EEhQ#>*oEGw0tq8p)+y{fqNX zx0LnKsXvo$Y_L6=C$>WAlUMaDzLh>#XUe?w%$#)nPE=z>`TEoQ_pG{eG^jS^*Kxk! z_NP0yeY4UzZP?#h|HFhe&?uLaHE>$U^u*S>`F%dAla6xRP1$F3a?{%a&;Pqpy;`Px zy`LYKZ<)D%ucD5(`?9d(bIi{7ecu&!{1s1~>V6>uSL3)0>u8hY)|v054?QnQSrxAH zSNy}X>FD-u zKl?6jJ@@**_I8r~rmdnyTY5#pB8uM?aNfUIlJco*a%J$t2RFBU7v(c+70s^Sz^kIe z#JTLsfz!F(Uc5OvC%1mt=xAlcxuH1m;FCYkGt~~ie)>%%yzKLWEe{orB%IgUa9rhn z{o=PdpK2vP8En^iPlMFpRCpB(6{k@$N<8s!YZ_*cKo2IqTC}6wh3geeA?q{jV z)^Z)ZwB*D2C)%vb8WvpavH1L=zpGaxK#_@2i$V3+uk|Y3vwc{@t@vf_?;0(1dgS`% z&Jlsv1;$IH*4DIhxUb)})ag;nvM!Cq)6S-xSC}buM*hkId6uBqxMQEEPY*1rPW$g? znkv?<9w;Ga5PvbEWQv2ZP;|Y5(*(miyfbZC)D#ze>RitG_^;AL<-8b{+Wx)=eJdA+ zG5BQ}xo_^7_QGYt}sTvC1s3guHu^^J7h_UwQ3~Q%_R(xcrdtbDnr`|LC6RPIet{j0=Z$d(*r{W5pqHo+^m8h(Xju(6zXm1$y|W^t3l zT!neo5s{3?d`>l+Twi3jMooH{s#=$HlzppPO3v4nUo-5!^G|fy`sTdbd-Zw$J}h9p zq`3YGi+-I~<*WzRudL5pb=muFxxamB_5Mite{Z6C%U0jah}a+1&iX*QWD4H$1QW^l16KuPd0>>O6(q$cje^90LZ?d&`6w`2Z^@b{AE z%D9ey{*li;!&0_C{fI=(=DE`ir40+%b^okmxH9wFjERDqCGGDR*lhLt9e!BaSN#m%i5A~qXOy2^ zkz+APs{0{rEqn367m4mWoo0U}zyC04s7t%oY2AFES-qs|MU7ZTM7U6o;%-UkMl=Oynby0Yny2vugvW&ZtCaP zRd3(;wmW@?e_-e=N3rsKrki>bxE3m2zgL!HmS0(sAT9iCH`|en8&m!$EK)O4wy&^$ zai9H#uiYemc{_*Y*214G-iJ$6l=C#Z=P5o@u-o61-f*TwU_u59AO8XN#oBB2)MB|7o^^g&Eg>cuDP@Jv+HP$xPaJ)(^2`_x%6uFZJ2CQIh5Q1@+^)msCC< z{^+}fDP*?%QSoV>Qu}Srz1w^7vU0-Yugl)eFjcyK;cp$o!^iB~o6`?l@5`2{wQLHm zIA3cr`w-`S8@9Rmlgkd3zqjQ)Ak2LtKQa8Q`|g8hH96DtcE8=bKigzB=j@%c4@8>e zx#;;lliiTaEc$Z`ie?BvhdO!_HMkY{FN=TNi3}`|jKA z)Zi8ImVd#fuyF3xtLGlF(u>t*u&7y=&GE_QYiZ$|bSC@zvC7OI5mS2^Q`W8%54&Fd zsCUPe&?5>TUMh93S@BLwVfvdlhstA@NN}#M3g}rATAq0IuC*cO`P^0+*PZq%t3=9FG;?Qz3iV4}I;k50_ zUd=0gyC!^ynjb2@>9(WS&VP%nTw|l`N^|L z>!lu?k1Yawt0pd8d&R$F)@#>Q%u`%USGk4dnAV&R(z@#LbmEK^Zf`jbg&Z)s|N4SZ zw)-otuP&xq9uwFD92Yq_HpMhq38~ET4O^jn(Z#)~q%~_&s`-husp-a%tG{Lm#bsZm&>`v7LG8}_tmi*+RFR9=)Gi#l*{9{&=HIKGb@#Nd zPu%l#_vJ9jrH?jR#qS9+eQh?SXi=@NPW$=A5*Jp6?VhQi|E)~ZUSY+oRuL`J=X*JI z9-fwV@mV$XT=CUa_a2Ek%Y<&;`6#we5-UXAsw*FJtFHziD{dMx;6Y*ak=x16B z%4r{AwzprlyHR)M<7e+ei)P<`-)Fk#^vp+Xx36iPKD%1g=iVV}ub`6R!<$7+&EjTP zJ^D3q>HO^Z-`wgp>bj zKAn^c5So51d!yN-)+9aIw_&aa?fEBdsapE+mNw7hOI5lvL=-gDu4`Ur((Jeq({c7Y zU%2?3<4eCrnPeUbKC>-&4$qcIZC1_1_9+wcqulM4I=x?SEtsj%n)GY#)vH&d%~&nn ztIti`TD5fJfyo>tw5%O-AceZKWWz&)kRtu>!F?^d70^hs>) zW4*v$rRjU`O??0O;jRTImbNs`UE#LUJ9EDC_uoohjaQaho$w4<{9x&{_2ng%+G{*M z1XX6JtqT0M=|)z^?V9zeUuQE1X;iP&{w91?qb~B^1c{)v0e_liHU}^@p9%JRHgT&H zC(kmWQwQQt&Tn>-ShBt7;_Nk3nG}7NU2zgj&72;4LT8=t#7Rr0=-$2X>y6XV-99mv zORf9kABU7DoHEs#-;?h5*0tJP{;`&T{~LO+WZMQ zo2BsdTtLXT7MI(7S|1apXzyDw>#3#IoJ}j{Np_WqZ+lc}SI!W8CUMFyg&x6mpJtZo z?+|#ulS{EBDQNLkq1nFcCki$UsIU6!Q{AGn;n=FO%jaLMRMzu6Yn3dwuG7(c5Ibii(0PwA?4j?8kc)E{q#3-gzU%8 zJMcfTiuKV{fBmv9u@}cgClpWezMy87qv~j{yW;M|Bd5D!Cd8cFW%Bp!T*dFM`DJgc zEMv4;`mS3W a@^Wg+3o(Ejwm%P?K*t*4Uc4$q7fy9C6#0O9O3yQcDHt}qh;F?)? zN^s4L1zpQ>% zeEsw3)6>vTj~;)%Jo)nE$&;UyIvF_#1wEYWl;gFua;D;(-mTm60@mE|S?$>7ccP}j zoKLiU;*y;kw%KcUJzQ(G%RyP=+WL;OrD4xz^mxxq&v-Y@cWcywMD~42TRxeKUc0NC zQP9K|+BNmY!$zUvEv+7cdlYKgzUe!1+HID(SiU#NZ;9WsgwvXVFHO!IRc~1;=&E>C z#Kz0zevCBB`#qCZ+o@Bfm|WS8yIFQ9HAdeUtE% z=F^`aBrhqr>9Y4}eSy`dRa4(RzvdFL)c>fk;N*!LI_3U1t?br1{a16>ipwvV_Vy-w zF*X+~H8^NaU2I>y`Fzt}{fGAdcKV)goxL#A;*uI ztLEJP>U5gNXyz`JFZr_r>=oRta}`YQ+Q-Jk^iMin-xn9Z$NQZAz1oV((!b9h#mZRE zZFwdzcT>N;%E@&HRemO(K3mGJu}8sF+{?$ao!914`(Cs1yBzi_Gedt*_vZ{=wr6uo z`R$jPPeVA}f2U2I%;;34mlFK>7w3(wHNRq>2j`#IwCyvGlwL;Z9?dO<2F|aRRCRHc zW_IS@>)W7yW=qPxg*QJ(ZCBo|CGdsi)6Cw78pk`WUwzvA@w}T~`nwgEJEl+D(7~t{ z6~6N5y&r2e`k0#v@8}e7`>m#^^&o!3@ABwA&L81X{EPjzN9O-e_ntl1@6RGF>&YVN z4xcz9SKZ9=JYo8_=JZUT^wRc(ufNLW-m7tMVBq2VD$sEuJ=;lfCtW@|9GHy|26$zif4z z?!O}{Yx2!wY`zK4?f-FvOih0HL}o?sBRMXpFM@{TgviGTOCg>{Uj=4vitPL zGpfDco@lPVqPT`tEGdI`Z;*lh$^A1U46I6jbG?`lymFqn$eS5TDpz~g?2L*1k;~Pm zX!Xt|yFcm3gp%v3N4nW2p8I#~mshT;Ytj)TrT=QL&TUMaT)X~=RN}20)0vCs^j|dT zO!)nwO>AM{?51TM)9Y$d#njj~ioO^&KxA+^x5bknhW`e&Ax zcdeLi$G-h;Q(V5UPRf7zcb=!4HFx&*iI;lnEh(JyE;^2F3CnuTQ*$;=l=-(rTuJrhdaePI1;I@vzZmizJPi{giF3C&cK_L`hG)nw&~ zl^LP3uKRY0p4i2_kK@|A-kj}MBR)TQT~U60srknJJQ;5eT~SDSxUBwISes3GSC9W3 z;l&%(d3e$fZzJh1hCbA2Xg)kR*><_u?@V zU$gtiG|67l|Pb8OV4*i zUVq*&y>~}(gsr=r=bC4N`)3(QSDtHq#R)c@eh1;J_`64g(z-Y+qF5bRj`cNd#d zc7aMs*;N+b9eWkz_7~LU*YbwNoBVvw5tv$%ptf-LKJPzB=P({k=+)^dd8d1ohk?N` zkbyx0W7G!Jl1K$F=-(=no&VVEQ+2~1b~9Ec>kn#~jddTFF>c$7CNwx8^lnlQdr66nSBFZI6XMpZnoEcNDf%?00#8`OS$JdGi&o*rV`cPqM{H&laO;Ov*nL6rE1ndlpLxwQTN5I3{X4OM&MLV~0>( z@4Qzgx@)=5Jp9i6#p!cx)RT^yvl0(wmhxP577Jd)%HpEP#=&Rgo$;Xiki=zXCZP>( zvzWV^o>e#}&yv3==JDW3$EK!KP4(+deT%+sVbA1#aQw)vqD{JwesmQ4u=I>i+NA8j zr%*95Rr7Sm=c{#B=Ztm+>=W@vR4v# z&$n=zzkMX#WS@J$P3p}borCO$jCtm%KfGWbQn$F^f;l6*T2=dw0<{mh0nAl5FBkAX z6Z?^W;y-run88chr_GoRqaUY|)zQUir_yJ81s?!{c&=BfB+!g|1wmzrtI0 z&hn)!oYV3}FWeXNs#(0Rxzz4ZxnSDFiFMH`iF&209pw7jWRxYNC9+ITDhBaO9(i`C zX-2y$UkXRJ(DDVFZJ+&i750l*wWQhLw&RH@`|H)*IVN_P3zjcfBr~HSxWV?YZCd!H zW!ei*M=V+2kgl@Cg73_!3+FY`SqsAtMX#JPXI|l&32R>cYxtu2$Ki*w)W=CNK9geK zMXPy8e@Hs)?6$ckFmgU)ou8uN=dvA_m24;JvocDDr>^2;=yMh;x@npA)2oXovh`DK za7WpV%T0eGWz1T(b~Y|P5gE$0a&l$O@*7WhoYqNy3OHhU_EEBVipx>4OT5QVFb1DE zvPRtVhWze_o4y=XeZFEn=j;ix=Uy6r+#&GBd&^V7dml{N-tG`u;yLS&Ys4$Yzznsgzb@RM}Kq-g5m#p7S-!A@WlEEI_*}37u#!ahp`nMVKGn`%?AlI?vY5k_& z;5W`*&iA)hf7&{${J*Z5$W%wo_AQqUocNC(v$dI7^Rmse>cY*h6VjhAO`iTIdeYIP z<-W#Ds#D7Q7jmh*n5w{2@ZTlT;Fmg2^F{MQi64xdM;2TWYSGBP+@i8`c820*k-~>J z*?A}K+nD`ShU32W1m1%A31%B~C-Og#Tzo#DaD6McqnU6!$DYo_e6z3n*X(&2A8@5} zf=Q->xOJAd`TjU5#wUEsWeij8e=o?I^Ie7Q#U>lA&AobZ2VAxEGQPVoJ{Jg%=SWa! zz9}fn6qv=biHr3^_(^F#-UZ?oQFm7geR>&ped>nAj~wc1qSt1GZq#@c-g4`dU#MW7 zfqLp$%~#Q}QK!_I;)PaTn{mQ1F68x@AQi`S)h@e0v6W0(`YwXH8x|}I&eFSH*LiBG zbf}_u>c$X@Z!?{De>}5PyEkx>$^UN}6{|VV#*0sDVGr*w6i+9r?y7a+>o(?uh~s-_7OMO)&92`8}j_?aV3X{`*A6J=pQ?uh;ye zZnxz64#*rbY}?SZtI2U&NP4tInmbEht;;dZobrNC`blS694`HQv&d9?W z848}CSBd3_IXu1;srqZn{G0lE(?gH1TyCnL;yNv=WMxlC_wnW>2W&5foloG{n|0Zv z&_n5(y5k}TSq`zK9^qz;Grt7zZVs=OTQ7gaaE`|3$?YGqzoqr=bCGF=A74z6ONqn^2@uIb?@H%+Wzp- z8=s5><%9=`fA{Q~_%H1cuk5Pl=`23IrczHg^t#N{mrh)9z}0A5L+`s5?ZvC~wNA*z zEvmkF$ji)FXTh7SFM?kBmKS83#6DwP?i*Io#on3sJL+R_~I~+punD1FQYMosysB-JKmvYC=W0yG$OX9N( zmgPooO$b|bHE#q_a+ug7fpQ@ zlW*L&ap8-nyvKrS_dQ(2<*v}Fw~&2hwDi1nH#t6UGryuHFk3Zo`__kQ6K1J5ZZ~DC7?Uk{q}Eo<3c)7bQce_O6A^B)kqt#|VB-UyKeb8?!etmQhoXSJ-- zxlfDCOO_wFJAa#Kv+$OLEy|g~+aGUT{7G)b+Z%r0Kc2g|M%D?+>_8*vspUC!H#Lkidr{-Z8O!R|w^lG+ z+}{*h%5vc3rpM0gzwbY-s99FrYkTeDMkdRq3o@1mFD`F-?HF{UXF*Lv(Xz}o@8@ri zEj8}7Ivbw7KG19N=V{``Ve&=BUr)_jrRDi3`_8w!pSR5Sez|JNvfq{eP0Ov0x~T5? z`LJYy$#i=q5388Opz8~cAJac^J!>WBCBAI8FSi&~_MS30n(%zqm3uD&cUm}E@fn1* zKMVCNZ7T69Rrl~+_hw7PzR0VZnowSX2f>N{ktJVNwpeXb?{&HbYg zs5RYZncAacum3tO3enrjqu<+;`RX&%VV%c!7S3GJ`|Hm^1-+iTLY3shQy4UxM zFSan&25mo@*1d7%p`Dk_OhZGKrL}P-zCZ6fWszB{aY)anP4_~=*G+%7cd5a5CUvd= zNkJ)55_VYQrWGvd(Y?j~Sch`50^MjlGNpHiIp9_>fYrc81 zdS>wn>;H~x-^OM5-myIA5*qgZ$judh>t4y6n!l4FcfX8v_wql+ht5UJ*roDZtaxA4 zg@qQ|Cm2t=q<8XU(y`C7H`59ZRBT%!e}2M?)%7nDx=b80cR8P3Hamsw?whpFv+wfM zZJzCGzI#{RpX(1Zg}Uu$J?+!eJb2{F#j3UMy0{(Ao-fLY%Mta_aWs{CI%!o*)c0VW z{EPd(1tsPNtVynV@$A%|_FcO))jLi-KX>%rC-3h``Jz`McgI+%^^7-glPcWO5-}X*iTz+~73Umg_l0?r@wsj8Hc$$j;z05a8O;4 zM{#mQ8Dbw^|R5{`L`{E{_l6#&z#RJQg*%cQpxvsv%c^w z>ARe!&#zp#eY=GWOVpy=yi_msppCUR>%PxcT-l!Mxoyhb*Q}0N-JgG)EwE5YzjD~w zDeAA;OZJCak1o$tdj6%c`bmz=Maj9|MKvWQS5%$F&hDIIBjCb%g!K_$r|Rnol@C60 z)=WI}om2GQ=k#`ki;sg`Yh<+DuJm{-HFri`=n(v2)4L+zjB=t#gVK)$ns-9>bBL5n zE=)X;q0(!k$HDs3;mFK4lP)eh6LPIQ z843=pS?Q=>SbOR@i%UaqOk>v!ZL4Q?;o3%wf+1@>B-|4fBE_FdL@t(G(CZlAvQ5*h zv$o!K#cx*@?)kow9n4&k?TG@KLOv%dU6wyM@q21Wj-K_CpdEMlZe$#3)Qx*nWN6wK z$#QYJ&rR9t2UTKrP3_GYrHkh8tMskwsxA65tD*Y{GqY*T3TOR}<95cvY{xdMX7bKV z60AHwb3&G%YxHLMzYgm%m)z9bZQQ_l|baTe?oIQe9 z6mr&knyon;uV9lm=X*2%baTJ|-<~}`c=xZW%?``ma(DR8|6*oYKV9ihkWp!D(Vg1g z$=_%6JYE?mWWtqnrpBtGG_Po-Lh=b8fi)9SEsoZ(cZL}iD@q%G_{*d^q$dU6JVd_cCkf!u0p4LhvpJ453LPHM1GxKKH)dpf}$;4k~_}Y zaD?+6Dp*mX;A?U7SIxgSAAcIhluhO^YMEX%NoL)(f>P^$Q+K{njV$Zn+b~(!xTI)N z!;jci>vLNoXZ{d2f|zeqf{L z%n27=Y+E*+6|qXzk}S%67yd$lLBuC$wv~#6^@5wCT7nbIYrUgiabH-``a0n6uKv!` z|CObu`}UrhHrbNlL6OtMTTT{dnWiUiKd6&;YkAv>6V54rP1+mt?W~SQ8tR-2Ql89y z+2*i%!Hk&LL%&|1pYfYD=K8r$k7n6{oegj5rLf>c-7l~ZWNjr`RVNQsI{x}=hhxyG5`3zo6XOQ{FYbB zC4acSYUjCUhBKe$$QwM|)A*NlVxINvuoJc?V--v8UOD(-r*tFh2CgMPuVk&~Eo#VO z`xu;ep-RX271N@1_x4Bg_io)tpOmnsFw1+r&)++2&HY{9g71jkp8Z?l z$ph`$Wm=Z@Q`U&=J-TSauQh3H6W+U?Z@Fu>KYrP9G=r}Ba~ORXZ40Yu4*z! zel)A$$Tg+YJ3Lq3{&v7&xmAlJjWc4mM&^n+Z&Ua2YBhXq(yOLsyng3~-jgRK_pIMo(V=M;I6dxF z0%O(MU1p2Tn0CH$-0n6#dV=x_(Q?Vzo%_;~a(L3t@Ln$6S(~lWn`E$cIz#x@79S{zg^wjx~yB3nEG)q?GE7uG+7kD%x@D$@cq2UzIK?ufH!NE1GW2%YRgq zS1Q+{%3+57&3(f2x$gGY`0|RaRXBh3+vb_BXQ!Q?{xvp-MRMPsB}z{YycfUSsa(26 zX>VBA^os{v*Hv{3>qi~E@KtmT8`F~YH~cr>`7!ClB%8U)nNv#RuiZA-#ND)#bH4`j zw8bl@))|{kuAAL?^H}EDEms?4x2aB-pWGPtLh9Dy&a~?2n*mvQk2I6ZmTppt@(%gG z)sAWQ)_E)kPu(~cuw>z)JZFQvKdzf(7j3`$%87L^H~6k%_+~fb@t%N(7f+lvU+S>&U8JDp@`Ak^ zT}zsZQl|eAIu#^%3;+d?!fHtU$a z*(_*dQnZwDvgeYEGgf!Ft#;yHlWqTQlDBKx8UCf2i;_7C=fCoNekfTnA>mN!H`aF6 z*wTh$%twshFTlEQ4Id6{*|*;Q;Kn!qE*Df(r{|fhT=M#=z=IeTN6%L+E=!l| zxnIv-zVO40YdeKcn{B=$R=he_{!#dul3m%URpBb^FKuJIzBev;Im^lDjHb$;S&oj#BWCHvNgMtzzrJz)`p1^sOGGF$gKbMec~_aA&;F0o9zVQF@p@Tc0- zeXfxWl4CIxx#&#{+JHlFx%Q$_XU8#(1oBmAcN#AxIo8|QFy)yS|c*u@ zud>bX(q#;K>U`;KcA)X^#in0QmFjuNqqgYoP+J{f&a!=@ z%}3EjHjhc$dCePoyjQ=z>Tqn?zIzNDMPdv$@1DN*`E1j%z|Gg<)-&9&=-XDc%bzh) zEb{5ueRpqeOpKayv-;YxqT5$%?reNyCtH+`s2`6G^47I8eGS7-8t$6k}U7#Q@d7%)$%PcF(YE{@O52OX#d zT8MfzIy(Qhl~A4jg#QL77@4fq3vVTT*SY4&yv6dS*$p#8q3!IyRW1n0Zl0*B>uG7& z_2>IsMa}3=88cNLP8;y%~wuYm|Co_bs@zaZcIU^$hR-G0F>b=HEX!<8<^B zEu}4Y6#AyNZI(A*kScZ8F?;6S+t&Ht`a6zZw2N7Ar{;|ESrfyq_79y2R(my9Ni_N| zX@AjT@(vhI@9uf07%{|GrB3+GEUS~cmR`}M>)0ysRrEJUBTgG_Zr)AaTjsJXk z7B}!eeDmwovtz%@zCQoH{`tM>as2Zi+*sIAaa6fVL&@HUnNQvAZjYgq#7w>*LAIDO zH_sxk#mZ*Sv=U$BWzUW`_ANNidUwG9n&d}=orJi%r z2Y)3z@4fi*1xI?ulg}>Yy1HH7^?@QCis$$r_TKdG%3=N2;kw;~eL}{!K;C@XK&A%eg9Sejcbm)OPcn4FM9H1y z({tLAS=_hWy3JvsCfU1!^?9w;|C+*=b7N!wS?u4p^MJgbeVz6Gm$f$5<=neYCWuuW z3k;YSEcJO(!W4P-%RvFFC;wX+d!v})N2{a6@$z;Zk@7j4nrjn8V?`|6r#XJSGiPzk z>gNxpB)nIBnpm^MokxA;*&{bAW^2x6PSi*~vtY(v_n2Lk&t@EHa9T1cTA+sSpopwO zjmX@Gvsh*d7xzR&qxc3b#eeMVPoWdfuC{oztQ7c1PwRm#Lju8mxSciBdmB z*tE89nyHdsFu}ixn>o~wMJV~8qLSFNl}fAkNbbAT@kCvWWy?Mzo!}=987G(g?fnpu zQD|UxT!u4e=RuA7O(s_i5))7HKTAvRI;`iG>+$R1Da(|Fk9L19>8n2$TXJB=E5_7I z+e)uK;(8e7knhmJEO+cXi&N)bnJ3oyT#CW6Z{qH~wg}%KAk}i{{VppFga>{*$xW za(7YavmFX+V*_^G&EgE`&-*^@b(2c_^5Q;z)tz&4fB#PFN`3t7k{WxrQbhCH`AvCg zo1b4$P@jE0Tvx>Fxyi|w4}EqmGn2e}t>jaDfad4__sl{+r}h@Tc9+YETpY^vcJ0aw zVx}uECvUUL6)L^mv;BGas{OY7y03yR91HoUv-E4Mw@Y;JTA`oUuB2@Bi=Og1GwP7o z))>i|{$E}QO?c~jtm=4}sH*6tY(}lUyIZ7G6U#Z^t+)qV) z0;8hk)JIFQB>WzxcWq0roGan;MPZI<@w?>8cArNg%@@BIwe&Z>^j|6Z*;ylnJAMCu zzWS1Tx8is!C(bK;cH7LSu5H`tPuxKk4<@)h+OKJDJ5A-_3G-YriBHwcPQ1y_W~Vu6 zKM3+Uqsh&eaPXnVH$kN?j%mAsZf)7Avb8>`+j;W-*z3ZD>1?IFqPIB?_8V_|nSSZc zjIF1lH!pKEySeFR=;e6(bI+<(bxJ+2x2Z0ATsiMdL%6Ap-GSSWU1vRtn^5-atdyW+ zl$`eMe_{fE)h0+jopoS`W=y?*+|dOot!gKJ<`$~Hh!fnx`NU|=D&HwL%hztU&f&R} zzs-Ji--=sRw{on_ZmEWH#&7ptc&UDI@2Mi~tJ%-YgK~eCE$qtQoVE8BzxHa);P$*2 zD}D1|;bXJI*ZV(wZGLITzP6lK%U%iTE#9_timlMOsuv}T8!o%{G@L8>J;i)+1oPb` z3CzVmHaRABKhj`cApCLGmvX0!{bAbE&TH&^wb|Tu`la0ue;t$QUNrN(e9e2Sqedxb z&cCeKQ!r&mG+WO3{zW~HA~$ZGJ$1pC$RfA-wq-w!ivu)W^X9!f)mpYNZ?5>7yLtQM zR;~Cw-!gXJyaefGx1WoDki7Jjn`3L?u6jd$yR9)5st2W}OP^Qv4_qX!9X{`Vg?`Ap zJyWK~?~19a+c|q$bauhI*ZKRRmVOJ8t9$8{UtMJHzx0Qd;I1{7YKo?u>k8QwcBJX1 z>I|9pHD{l#6LDRt_03Z>$M@>2)w%N{_N?15pF4(vfi<`$9^RHs&rlv(6*ZK(MtW zbC=X%)>(U5v-Qu*I{e%I=3b^E596_Sa^`u$Z>K+gbh(FTetLYma#|&;(P}-GXI*#i z+v&)$$XFk7>Ee{yvzuZ5ZdPmIKRe2NJfHEhuI1oo{`o>>-Hu-~#g{zOS+d}Ga01t= zu=Y2zqJ%wpPjk(F^2=$x;=!aJXPl*t9ajh0i4-KV-Ozrp@9CU+hxz>8@7vPrtWUT` zZr*+Rnep_Kt9PB7TdP%~(VdYj#T~QM|C-5%%+s22DbeM*H52R4db*sHGd<3|bff4h z`FVPC`qp@+oVRBx$?Qy@(CSffmNo@kr+xjd`I_Ydx+G@G? z@ezUl91^RdwyBs)T1_-@*3>(zW1aiR5I+e&e3tn-f27pDmwWUn19MH-GNl_kTXW zpZndwBR|me>0+gKw);%&PaN7CVbHO)@A&5L3ZL}nl#1!C6HfFz_^k9s%sIVf0?|iY z|Hy^io1c-o!C0gH>uH^gqqkP>36JjVkAC=Z&6EwS=T4Pp)-8VgRgqU~|K;!Yh}P`S z3|`$m>UA-o>roG|VcAfXT2ur*YO^;qHe1?SpqBrMJ3bsytRA6-GU8N80CV#*euz)GNhOPe6F`s_;U4RgRoQV%cmI{ zw7OM(TE-{+aK?r>%Z1G0DRUhabc~$dJT zc6!m5Q*y0BPIcbA?28V$E;iGPxMPlQd+TwcI@e5hy+nz_kBqg2jXu8D{niAW*nN&Y z?ziIKwNEoTWU8&61i7yKvP%EVu^rVc*0z=FvtkQ<D4AzjmBxsFO_=cL-Mq3* z=4??bOJ>{5ShrN5*LZeP!{0qt%VnQ-_XoNg@k{mh{W9?Mcy^oHa$VB0a|=FY{_ZY$ z>HBA*b=P(7zY|V8a+WgIab6kd)O$TXA-np7%hiyamzULN@%-xjQmuVwu~=?>YNvbH z^5_3u{?@1W>$G=D%=MXf_=8ul;IZIa>{>VzLZ2 z-f??sSRS*k(mcA(eV@FXhWE`4d-R{(Ws>*rZ|gs>ch8jj)k(ekd#7B>bMN?*qvf;w zuf~bW^bDrG7PtPfBeKw8OGjPt*h1qxW(I~-4h9B!^wn*Ut|0P4`MF{D^KV=5fDYqn zyb*Uv(PI0(*`s znyh+cS{ot4G-J)Ly@r)*c9gb>-&5Qnx;-KE?X@!s7k*zdc)5WoSA=!Z^bU>kk4ua8 zxFkd=8=L)nEF|$$UBKPC>FCDubJwSzx%AyQqIi4IJ;u7LY-?Fl8_c5$-f&DxT;O=5 zv)Cm#MuYV+?*#5s6Ro)(?o4JCzq2)9GPhdvg?kyPg(81c;=4sReib?2a!2M`T!&c1 zPuEpj52#MEc8XZP)rc>IH~8?hkQ2ABS>?PDxOck9WQojV>r+cVsZKu~GGnVzyhgn-(edAh^t z_zsEbUe{_YqcZ>gIv&w%Dm6vbt}*!N{s^nzEUUU>sw1r?UDZG2nHQIEPPKfl<9_wX z<}l++K3f{9D}Ja(9Pk84IO$4}>sR{{u`Q8q+Lx?r%i2yp?%ctg z#gZDZZbqfxW(#Zo8}FANcv#^6Zqq6TRx^#*EBO~Q@SIR0^DRp#9Mw6E}l=rKWsM2}c!sTC9B&Nji&iuC3 zrA=3qcpj`i@@{R-UUljy2;(_TJid3yV$#FbAu z6$V1HYb$L}zWo0=a&`f0n0@-BU03hA#B>#~wsh;gV-yq5wt9E2Z)r)uM;+@c;jc7p z)lQcC2X54y?R(+d#b0MPZ7F`dwt3P&*)P?|*H@gfbkx0PlHL)|#lWCrfMp?Seo|Iy zatU}L>RYMU{5v~7{sk>WZQu2}WOG^3+tXHt6K?F=9aCLaU=}3es#vh~POMp!r-J5f z>BIl`8mqWY{1vr!ug1HDbsKaG_oZ7H%e;EgG2!A(Ma$EldLNvgs`UKJwDTw1XD-m* zHSNjUj~_p_)TAYyUHT-_E5t2{L2k0sCd0_|;(ZP5CnvRBDEaqjxAFpu=Rury+9JwX zM^z`@bh;aOkmJvO5tGmyzoLnZ%0JwlkMz~g(v&lH`aCC4k=J&f5Z4#R4r5D2^U_&; z*SxhJ{#4!hIBTkC*M{FQ2AZB~9P!UN)59DbTnrrwCPX?j#|x=XS0mi|Y66+O@CK?*Hd!&sU#*aXLCC!KvZR zO`kMQ=Kh!Aohd)Wmvl`|I(K4salT=db-QGh&s}1T z&tn$LImqIje2t|hlVS6m#+Am3f{#)?Rt4NjUcRE#>$=Y~kw>17C$b0aH9T{I`B39? zMK7k?bK>XxmF@W?FSc6zKBGWI-LwxCT>lU9vxwOgq$;{87@g$zKeOm3@3}v{E1ewP z2rU5Rp$T8daN5My_1b^j}#ZF+^xnz=N6-euZa>RGq_rDm|D#YpuYxo~`wN ztpy}DIo$Q$E}7zYGUP~N^7Y2!Y!aSw0vjhKZpd)$WLbNYBgT8u8@}KsC2fzcQakR0 zl1tX|^;bZ1dIa$=WCE&IH;0 znIY=5_FLMLPjeNyU;KI>aQW}k`qW(sAKMExp9vhk7ZJ_t_1s)-rg_PsXK%l*JbXt`^mQ+xpidb()k+fr=JcIZ<%;Q?rUWk{y{!2NbG#Dz#sA}gpB?_!?DazXh4-ATRGn|+aj)Rp zCU&;z-MMXY{pMyTX3f#^IPU7qmmfdP}vd()oA?pRp zW>4lrcX!*VgdE%|@X~`_k(E1S;qU5=k)H~rrs?rcj=Cs4y}!!AaPGQpm%87@dnNO9AeYfwNv<`oKRcylI|Wa=tJo&Z>Lc?aec^A7brsW^EK*`U zQr);L0v0??IbtyX%B6@anSMT$w3*Tb7<)<<9-!Y_qjR^tQ~6 zYE=SEU2Yb4HRVqv>tE(l_xYSKd;W||%Az_CuDMoyD__fba?-19lit6$xskV`O>p0Z zCDZ>*TdJC?_nM7A!sJ)$nyFR+rpFHdTqI}yYv1ck-K;4AGq!k4y3WPEPxGkb+5`*d zR81}xrzkcDhlAFg=NXL`vQo61X!73YUA7^kn#oRngyWw7zw*JOphhTOwEsS~Eoy}bIna{c3l zsuH1rb3|8iEjE#uvc*m3(5=Mo$dAWNz8(F$Bj#4l(!47-I=A)jxY_oM`T7$sBg`K?dW2 zdm^h6uSmpCuFAjU{A8LM>*`kB7m0HdLUsDJc#S2To<2O{Bzd9~)J%VN6kPoJtWsCYg5t@p0mDd!!Q{yw!t>P*px=Zp_Z8fEt$+V@jnkIMb@Q0Ui(s|}Q(%gcp=3b4Qd1lk%aN#++G7OU7Sbu3h4PF|)&N>nh_A z>Go@jz3Y$OUpC>e+_OcWydK{PIr&yceHRppzkD^_eIp}Ak$?L& zah;QEH*YUX&it{d_JeMS^uf}Z#}uv|(>h$e^^zQ~^N9lj+jdKCVwL*qmz`vEOL9YB zL;g!S>!qd%dh51tF}(Wr*!x|Ljsc%{ukKXTm7l?~wrBRD%Gl)1wFkF9Eb!?6EA@ER z|8m1$si{X|e~aJUvR=7bxFf%2@p|RlZ<7;0zP?+#Lu1{O?CDk5p*X%+9-)+cZ>^4~|nyHUUAm6d$=ey1Y~SiVKkK)_4$*3Rwe`D}CZ>Jo zJAdA=)^*wSKmJd*`ChHvaWHt{X;Ja%&t+HsuVxbM)!#7b&%$qt7Ioj=iruzX`mYb_ zKXNgEKw_7xE{KL_79W+0#$-DOp#3 zpFDTRbni=M@3(rYc`m>HGSxza)w4%4sDDY$>!&~eeY?%iz~T_FDCcXR@mf*A8?icN z;=dUk)YYAM;^jK0AI%D0_Ssc8?r8YSkUcY|d{l}Hd-U?<%a;**rav`WyK2h`*Vqmg zss1CoCMj>!S@x3WU*Jg{;X=E=-)0LpSop5q<)i*Os;g>Z*dnd8uca|wjPswT&beNs z6_(1_@ql@&2hYDfD=xcqRcxJ97-_i2MBMN|yW7e&#~w}QzkERIi0Gecg>{#!0@q|K z=7%j^qZK$sDR$ka5G|&K%99vdn9p93`p~7)eR(N^fWfgXY$C6>^r>e~yC!YOEKs;l zaCPZUEiFqo3!c}PnO4Ly?-M#6cKW8(X)`51z0Z%VCKq!)Sm3%fZf(~lv7sa; ze0scW)zeKVx?3Gh5>HJ}l(K~fkvbOry`$yAv zh%EPS`4NyJ`GHYlnn-1+yJyVRq%bk>UeRNPnr#LrFP-@)$oz9PqmX~&^z@{uYSSeH zhB+ezx?~|Z@;%% zy0+%~>-OpEUzW~NzgeYqbhBq*$k&ru%$q09KTyI{d$nR?RBVaatW#Egn}vJV#lPlS zrarlJ;`S)@P~J1MOPxI&Ca5dOES#s>@b(?&s%_^|Od^-x44Jm-|MvS&J_d!Yws7Qg z&i)u`a=*a;OqKIzFxoc5&6~4!nKM&a*)f50=XUU)k@{pZ>&R3a zv9D>Wi<3U39@(Te$u&k!_}k*o`TKX4P82c|=oi1N`I33xLCNFiZHy+aIUV%ORO7tM zqCe@bKHnA^$SSqD{^Gi?IbnK{GF#x1AHuxH9-Za68rjIIy6Iu>35hc~6@_e@Ebex= z#%NC1$X#M^sGKACT$<6!shnOPS4TOdU#bu(4yZE_oUG$3vP7gO){Qvzqq{koa^>`f_=B&E%ds&dlUw-^SkxtQ#7tNrp66*E0^{t5SQ$f@ZvuTnCo zT2Ss>9kojRok^(w#^B3KqfV;y8nemH@(&LyDV{cMRsW8L3(LY!)VIa051(11@F8~T z{>^PEXZz)3AL^^lx~MVtxhv--t$d-KhwKi2pIts#-@x2pOH!;_MlXxEtet_dN$TV& zJ_SJyRTqnxuGI&oZ0d3hI^idDlC@DvJ;NjL$Gy!;hEF!KtqSaVeA7eb`iJ|X|K`py z=Z%}5`lWfzmY^+-=sln#1Y?y73q4RYj_civl zE7~qH3g63L^j-emp1&fs6(47Fdo}MC;+N~tULtdApKg&P!~4ZAmi^OlDdlKc^r>rw zP44#nTlep{JHJ;$gE5FnWdl#^ix=IUuK)LcRx^IE5F0|Vrl2PoW~bDzYPJoKh-`a-K`7Y>=Vo!>B_X`&_XZMVAuXY|jBC+uoES3U2baa zKl?93^0}c)-9k6eB5 z;QstcFAiI+zr3_1+|^QunWKce<4~&Z-_oQTmTsRmXh+KP9_p^ytI_@1L#fT<=f}X- zBkyA#y{&)rMDSZK+rdez7nlZcJFE@4Kkx3ui_Zlgb7mFX=(2q;lDIZWu>JUhBl(yA z+CEv!Te5sZDfg@}6Y+%UEnAno{x?Zf>a5wuSL#7-bM|oVS?v2!ZQFDe!3`gRE-bE} z-u?KuT>0lB8;#z@&K!qda^zfe=_&it@%nz6>Q-Tv!1Oh9#G>3RN}UuRdsGJ0KJv0% zW<2?n!&=1}J+^Acn4%7!#EqX#6J;*_zx`J7@df9+9bGH;9T)%Fb*qUtD_eD+gu24M z1#xHR6r0$6Icaar%-G}jwR+2%Kht7=vQ;biW?xxu5?J$X6GK+iGS+9?POKB*l$aE_ z*kETE1zCcbe1+ewqVbiyy}$-wQo2xQ=CGgkLQ$ayQE;z zudG{bw>xjGNt^Do69qz6Ax?iDoMby`tR?9^W0Fa(i(IEVZ|#g=sj#mi6@v-uU4+Yw>=$rF~CLC5|Zw1$N1Jx$n9z|MEGT_kyL|b0RO41mri0UB3FPL;jJa z(j7lH%R7#oKl?r((zmax5}jzGdiv^w-p03nWhYvW#h%KVd(|O1T5r!(y{gaCniAd# zmN5MYjn4Zu**E6aJ>vsFcsb>rxON3`}DpWuHT&8xxwn6jYwNp>MKQEc$ z9V6HD2XHg$)Cnu?=6)gQ4qRxd8f{>rq0OUL6G>w1RA8>edWS#H!f$$5J0Rmg7EzfYai zrt|pKSBFc#Kf$8E#$$>n!+)XcC!N9^Z^f{gDrXt>sy~XdYdLtHTPs#hv7=S{eyn>bGOc>aA;HCc z0xKim>^iJGOQm|+hl3j{Joep|ym??o-P!e*=Wr(#2CaYW)4+Gq=(d9JR;|L=q`8xu zI77QKK884k%9mB>i6v6M10r?m6(a;!&Nttz z8+w3!(VifoO`ORetMo3}N8%mv4!nm% zU8X&6pBn9TWL~2C_9@yM7UpDam@4TT9N%Kmvu2tsr{?U`%ko_rO`LMU+S|htJ~Umj zbcx^aq48tmf|jy#EJsdcRy_PEp!LjH@7@HD=T=L9T;G4B{Jpu)j!U`~cjIDOe#9|K z@y$CaeIfGJ7bhR#`jspzzQ=Ex-FSD0Ec{x8H2yHil({T=)lusVzj*;H~a?(Jp& z>i^M2?;id+AXFiK{%OI7i7&;@Ds>rX$8la*_59JoMeh}J?^LbWXs2?VJGiu;J7T`U zN!74IPPV$aM^(c*_kM8NnXI+*v>t!jj4A47AtsI`XZ=*GJNYKu%{-LA@wKiwGWC?) z2DT42R>4b*vlsSS&PlqkZV~r=7tykL$x^a+Ey0r5x`=oBYW#WlK7fr8f z@A6~|`gv(u;<@CgtuZ@y>YZ8{evY-7+ibns@ghad#+w%IM|;c#8B+pvGcJZ7V=w28 zQpizXxV80hMCt~CZJmh+Y8bB^7q=2-bn<&|*lOCn`Bda38QGGBIcpt%>KVMc88@#o z{M4OqXBAa0ZmHL|YpiBj9jx}e@YxRgb5S04Roq+R))jtX`I+1(b9CiFzWd$#y>~A9 zsc@9T>3-~=Bcjt*Ik24MSaFZ*n6YG0LrLKc1N)|>k}_H4ZcdloJmNhkr1U(p;L$sB zX<1VXmpOmqzef$G?nggVO;qF7t$lDK=u&}TXpjz28_;8aN30TJbY2aW~B zEe#J^y^`(fHAl`zy^^m!f6(4!C;R@DP>y8Ynl1ODXRkMTGO;2-VdeQ{%f+ic>m?U_ zbeL9r?^o8Lxo#@rLd$EE3ofLcxa<`6)A^31$LhVTBG&0U)VDV_a7%ufwlz^;SIttE z<^aa)2hO(qoWGFcz;m}%GOY`}7PvO<4scYt7xd(q%IdcjQxAMQz(|-BOMv*=TcAXU}NS*&vC+%mR43o0)DduJNzjBph;%@fqPG_pQHYwz( zN#KFwQD1z{pFVow%imjvzS*lm~HPBrsN;&n9LIMsKhB#k>R%-*YL(VzFc!rV?u4^y*D-4hIcCYu&pa#j zsXN89bmhyJ3qxLSe{ZWDm^r6H+`LuZS4H7~JKOC--IKC`I)*p1rb@^$H5TsM82fzP z-ny2@?5C`>XOx^e)p+_}R8Rt6`>F~(6%pxVguIS{vhcfXOjxT4B z-@;d0=XJh0IAT_D#*5$2_|~ZHby@dbCRo7l);*8Z9{1C04t_ec=#rAjw8&W!hcxCc z=56>F^z!b+Qy~ZDGtTNSp4}WJSt5UQZkgl}Ztq>DN*>Y4Yh=s*a22Y|ttx!Qazgs_ z&R>qFjXWCkd$*i(64zO$_tff0=rRu(I^yyQO|LL;hf6!!O%~z~Pr^psR;yik;bHyFs(rZfZ z&zzk-bJfgChFXDZ6Z+keUDMY?=XTy$|0wG_&u`6j5l5#BtcZP{z$Nzb zluWYnquFg4dsj|Wcb)r^J;h2V&4O2=+j3b|&f(C=eb;;{JKV0N^txCVzOYhTdt}LW zo)^Av?i?+gawus1i!TRvXnuJ6`b6U%xqcRI*@lwWz%Cq1jR|F_PZ#dm#wveLU3zxm(2c(+=!>W_*_h>66v zwjJM`J6}57tA4IA>q*Ug#TQ(~syoGU-!j~FwfVO(HfBT7wSTc9rlJz;slLqHdpwqR zbRKv7sbqib#EesXrCu=`^)8-}c)`;*y_<{w@0JikRiHu=c$XO%soXWm+!-w-D8{M2>rDUEXFCu-L3nzoeTuaiY}={@IpIug^; zdAcWQs#_{;Uj61WmqYc@Kl{=bJ~_ToFzlo2;cz{^jvqYVCmvuqvN|+!%_))dMm$?) zn>jcb+^zUhd2ap}F2&%O7Tzrymo${i8WwvzJi2en#?SZUZq^k%{w>w<`^SN8|4+L& ze{IW{cK-cYuLUbj-o2k$xzzK@`g6B8NdKRD^T4{&X8jl5*+=KS)Nl@ek`ws(&r3PE zEv}7GiMrg+(*=L_?w=g=a6xWD@130?+a}MS))lZqgV)#h3eQKy>Z8v?zB)W-nQQcM z+kza^9}UOKmP}>l7Z)t;XN+}sJZHbV*M?o0rLE|2rjIq3(&hubS9RE8eRYK&6g7S3 z7h2H7FuPW-+DR|C!&g~+_qVw+tak+e?c3w^Bni2Q+wSuYt4ir`E&fNU3=#g6Z2d|!*SuY=H=!Ul> z)Tj%$lucc|c9+X51JwsxB5xY~Is89=`aVa66*jrtJ)XWRxr1(GFI=2xW^ldPc2ijN zho4-b7jk0QybKrGyLGc$_ODHR70b5OzsEigrx4mcLcGq9Z7rv{{ymap)>*m9EYc^=!8JyAo5S+E zvt%1KW}B}!ntA?p?t<+f*nZt=us*daaO=Df&zbAq_;7ffw5?zb2)v(}Brs`N!?yz# zf|=rcy=q6dVceej~!tCm@dznfO^E=+Ml(wzCwmat>FRfC2 z|5%NoCpKHpBJXAGMTVZ(j7OfKDX)LUWiYsH&t?)lVxJnB)7T%q*-G;0-tu0hv+GkL z@2B(dB#O^l6SZWsb5s)Bjq4h+Qq?>8zhw#@{pmRUz@F{4I*VpMny^e_!B_X%fHRIq z>K-V2|90D%T$nubUUK5kI~9L6KM7Hob?dQouH?`E5^2H)dfPRVlI?7c`u=#wHT8nw z;RX5D&6-S}hb`_^RIlmF&(Ifg`u+Gz@#;x6dottfGxu-%BHB;=~<*VLbDRyW& zc%ybh!hgApv`E4G*(NLr;)|4aiuWnq>`YY5f7i^o>;0C!>|1x&u8k}6_-{PfcH^mf z8G+S*-2K=5R6IWGyX@;f6FytLw_g9*xv%tI`I^jqr;;|zZSPgR{O{lrwFmwjT9^L? zE?xG>zeDfxzlTegJ$jIscFX?U6_Y=bAJcBxKe?Q8$MQ>Xyqv~8@Bd30*0XMpKeBvh zalw20yQlw}Zz?J<`qstV!)u*kFyUK2n+YTP*VC8p2{yXb-{?@`ZC8mX+f+Ai;i}W6 zLBW|hQmP-l{(j@!_iNSHL-%)fiD-c9Y*_I95? z@;V<0FM72j&G1%}BTGU_xH?qv)_9oS1~oY zeEGhgwjZSG7w<0L7w4BE8TrqTyQ56Jiut0QH}|BtPu0$s>fE^}#qFqePP)I)H*lkR z^O;}wnU+ppb8kTgZ+_#(uvzye?C|FfsbmjGm6&4o>o2QjKKG<;bM`hmw2MusP2A$R zBI{e&+$Oa;^K}yWuUU1Y)P$x_kTnyUwWW8CUHPW9%d@U3Z3%y_b!TSxncG%+kFRQ- zeJ(hC)A#rBFT4L9W_XkIIZw%F@6Wsh9^EbTm!3Utt8p;){M;*Fm{V6cMksc@$@*@q z`HDSD-PLd5E_RtLnFr_M95NCV9sCS`*)>$HpWXO%)AypATYbL8sqPLtey=;ZBJj;# zwX$`sVWOM)c`Me>WMB9_Nh-!=XV&$_+w}yuT@0_iSp0Fls>9@Y3?-54O<98dUmNq} z-HFmJUAg9ZQD<)SwHkhYr8g~a9yhnt_TO9Qe&Fegw}mV=z58Ns+pgVp`rN%c+iZ*X zE?;Y#9&`SMaq^CrXJ4;fEn>SX__EmbN%Qu0Z+rOomQ(+}3lqv$zFJYfKmPS$IW>l7 zhrb+t{HpWk#LmaBR(}1-Df%YF{I5+_OTokc{=Qe%8F8*^EEM_ zOkeUO@rwZe-;3t{QTJ{B=Jc^%+W-I8&c_@g@utUA61x`d{63@Xkyibi%GY^L6$fu; zU5ya6a7z1Lqccw+OXc0c<_o`<|JwVkZ@Trvndy3S=5$=2vbA8H@`JgbRAp~GzT&g= z`{{EB`JQLh+ug6b@aNOxhxOAh3o6wroqF`5O7i6r?sq=_ZL2;$JluVM@%;Gxe?MOK zcmDh8girgfRd0p#qx7%#|2t{S zo}^>9+d%AD!p$uwRO64Ao&38d!CBtLno}lrbAs7)qZRR2o|>0@vaCp5w%Ag~=Guns zv4?Vt3y+K5>HRi4Cj3{WPxWQ_&gIIrJa1Qe_cF7|+dl5szjD6j#)Vlev%*;G^1j;V z9Zq_C()izxjrFDKj-%M&#@grx+xvERE5eS+OyZE?d9~*e+e+S8sl+3y=?`E3VBPVyd{*w> zKTYKyGH0!w>`-&}>FFCgD-UE#>{8g_X>s}eRSC)RW0z`dFF9RV%ls>OT9ZxeDc{t; zQRip;%bhzd)Ay~oWBT&Miw*oYZgE@|pOO1R>iJjih*eiOjhxt{Y?iz$uHAe|{Jj|e z{T0l1cZ2^sOi*vP?VZCExBO?+y!R7Qyi2!v743?h^gfTd`N4;qs$!Y^8xK6c_HR+D zc5mqGkFU?nWm~!G<@U)}zO24y@bet+-Cx(&-kI-yN#TsGR>kia&a{HA@0K4YF6X^_ zY$anP`_(HOOL?7t=l+`-$Lr{Rc5O>^-lkY9`+&T=EI!9KZ0ByWdUo>qWX{^Po9$M0 zrVD%w7kpvI9+mWf_1~UG{$o;ZSLKd*{7|_RQhIk%M}Ph8nvM_hS7UW~<~*Hx&i?9K z!Jl`xE)+X{XG4}>J<|>OpS$^rS5^Pm&$M>_f+`aZ-OOA+#eXm6lm$yv{S909KSIb+ zW7mo+{^wUJZ{E6m)1-YxH6I}JJl*yIAB@>8K8n0w_NYaQW!Zvln>KN;f8o~r$aaI@ zavKhrsWTUL%10f4U6)us_ZR;xp3eytCLbaM_GwS~-|y41PVwt&jtK_a%nSwp@43+3 zRTp#OKw;pVITGg5*%!WvD%J!ZcF}vZdW*)};=L!h-%rq}|Ndg-ax&5}srR(i(v~A2>`Mht(igjM^c;4Pwt@-D*dXLHuwZCZ=1=`Yz!Fhs(i!}>2 zp8bBnY`?kL|9?HXH_rTJ*}GBj(Cz45N{2Sw>}1^c_gOt7XucIP=?OZ5McVC5dm|eI z!)6J{dR_2*D|9jyG)0Ph3QKZ9!O@85;#(FXb?1Hl9oC$?OwE~d$?aN&>9Vsfm~B3r z%5>XLefCF=Xg1ShpFD~h?ta_Tto1%TVj} zh3X9B&7q1y^R*4qvQ7xImI!fcsTMHih_v@CV_dX|kD2-Sj9!yptokZBEE!D2DO|BC zJ`?S@XU=kJQ1dWpwGcF%zGdCpi0HkFZnGEIFDwo=@i{fW4wO7`mQobYsq($(7d!$uIamy4k9l=r)T7kSIQ zx>7hfd~x&{siR@4oA!Ravz)P8W6$0_Z@%4Gt-qIlx_I9APyMea_x-f-e!AiO&XDSD z`>LW<;=3B9&WO9J)4fB=Je>cB>$g!|WOmn-g{h}?x;rvB{Vhm|l z1P|@~vd4wvmG#xEf06&?o>_?0yb&_=a1-gBr88&d$@kyv9Yd8C*{pkiI{WqKCGwYw zu5Ptz{k6<(UO;oXqWUhb@E3$KK4>7E2wNgk~ zvZ><2{~eK!T)S5*baTqT__4*%<h=UC&je(rS+eFb6+y%k0hS#2JfjT(nlmmRCpdz{9+ogvw1>aCVCmGA?4 z>^FGoy3Q}S)LcC`gwKFk_wzZ`OIQ819~!B5zKv{??zVoNuDqadidJl2zBI{DOPW{d!s0bC0&Y($ z4(<#sJh z4-YVQklXy z_l2_XyEUua)T(oxPJfGzQf_h1IIulmqr8Vv+_T2=|2KnaQ|h!UqK`9e_g(Q zNNsYQ_0#`G57+ETGd8JoIyHIumz{qemiUz}&b(jzYO!4^^lw40iXN}cXP@PHx}6mjKbL=Pj?Sd?#&|B4Up`^iy)(?dd;94N$3DE4 z#r}k;Anc54?H(wXYv&CYGDy$c1(#$53wq^+oH3Or_1$%LsY@}E3=k!y?E{tpxMZs5GZ8yrK4;X zi_x`|uWnyB>O3M?GS=>3Oyb(R#AhNa_smlXog6CX6g*uIsg~}N-TbyIZ^p%^wrpoz zpUqm%puYcLrBXr(lc1>fms3e0c?Wlf80?(cERKzxWHR1_(!eP z-1zFv``6$1|NrIL<^Ai_#M2}T{~GXW>@mA>Smp4J#|zhgv^nD=6_h?#CH=0SkCK*f z)1hb84@{On-u3f+A+PVMhQjn(w!?}wbME`pmAZYtsV`8VRa*Bz@7ec;*)ioaIeKz$ zZa9{{dhwaU)$*!V(_|0kJy#4bpXMvR{YrRkL|~}PW7ad_+s+4Se7NrNWnsm-v(>j= zE%a~{T>hGCmyY?zqibzX>n(2Ke){yk-7L}DW(j+xqVi*$-p&k(SkSat$Nc-fz^`t? zw|^H-*c{uK;JqRH*m8qcZ!K1BeehlGbZ4OAjt$?JHLVIc5_&x?^Y+`E>_ehozcR4z zG;7MU;C|KmxFS{+bYE#mN7dwUamO|0mX|Ws+&#u&JI(UD6?R%|W(e4+mdVjXfm=Nr(@~imDf*ad8 z+W98xadFSW1)*#g+?K`JRL3#Pcz9p$y=?I1M{I0Cz5TDgD>nI?!p_cR?wpG_%=hammL|=BMAw|JbCkaEIoth|@EkFk19oHvazV^UbCErXKIm znXBb+c#*EdYu!MVl7*(T8}fAp1OMH!&0t98o}TLBDxbJ~FVCFm2PfbDXcm9}uYbfua{YvWzwF-yNtM zpE|diJoh)12bzbC%z1bL~!by!X32(Bt0O8T-G4 zTUuILSxHTnJ{1-?&pp$rYYNMS3YSxJ`c7!^F1Gx0B2z}#o-=-*1xrWb6mgwdQ(0Ay z8lCc-cdmQud5y;Jte+=0wW%a)^04UdaSiC5zr#5wYF-z_yl;66e+~_-xc?euUpn{iW41ZmtIl zT;tLrPjO8;ce47Ke#3)Q z9AJ?;n^WKRm-(lI=}%tFm@vQCE6?ou=KC1|71P6~Z|~!tkf>mPWFhyqhZBM~wRFn6 zc!s#t$^2~=I{sw$?@vchi{Ec6kyD*gQ(yb{<+a^EZ@=xo9)556>-qNc;!8r}{#-x% z^?39>bFZcyJeroXmuAMvq)9IbD3Z8zsQ;03Rs01O^+$|nKiBLzv+3nFJI0QN>7Qnn zZqesHx4Q3E>6p)D7Z8~1~C{qDOdAy+0d#TA}fzSb@LX_nhf zcCLt4OV1zr`KopExLUS+6I;@zk|46=Drb-Y|DhLuL_OVIeox)KT&AsQ=|3mcNKdyp zvsx2apWS+)Fl%A_j}%wIy)iEWWR^239Q_&fpFyNML-cR+|A4=1GuH31TzsY5k@3O) zC&iP^uK9(Ecg7xDWIf|gOU8<2oZ+__-ng1{Uo6_VB}PYd?j5-`Rh=Dw<$nJEalUKb z(gLHE1#0;x1&{y!_)$y#raj(MrIC&<_^Uf9?)-)Bv*N6ZCrx9&-*DweAKx;lF6?v+2Rd#cqKl*F(p5=QSmSFA6?9qdZOAk6%-DGjU$?14Z^YIS7<3WihW*$HJ^25$Pm18%aU3@Yr^S6eC z!UO-AYi7=`6y)z#$7``=B?thli7PL7_$XS<7!gyWME=81oA z{JzoWz=gmSUX7g0+A(vj-m%P;n4z=o_Oxp(QB$?M9(A+5ncXO4Z7F&%L_2*|TmROR z$24147?=1-zB)ED^^9g^eei}=*8da?`51g<6WjJ4IL{q@|KSwl%bxAg*-~d9>V3V!k^95+hWqYi(~^`Yq*vQFzl+gZsCjvo*Zrk; zBaB{pq<2&-EcE+rkhnWp=zZhKjh!cxy$d&&>|Ot9($y8I8+82VZ}MK8V)F3YOaE*C z-M(L)pKqo0?~nXU{*RyZlU*!sTz!`i{@ zO?YT`W27`28K051PC9I2k_NdOEB1JdeH9cH1Kt z))%k)m?C@B@aNi=muC*h`-e~Y@Zg^IxmyX#H@#ocWUkFUMet5}qs2A*2MUX0)+%r4 zQVr--t#i7?uylT3(6rER*A0%8%D3p7$sJ%8`)l&pygWj^Mmg({ z!6fPAyfoV`11&dC&q;GG@piU42dl5P`MBGJD>rA3&mV&?1?#(`CFT5@8@U$lIdWiK zLi(ze+kGBSFv@@S`~cs_#m@|mIh~tyY~hskGD++_*?U(Ai1nptJeVhNWYyIQH}SwE zuB5gr`P-KWaP3_FX23I8IrTPtD~^I?@E&6@fvES7q5 zZa1{l=w~;RDqrKqQh!kTz0ooG74HNsABvf}I&wYnRT2Y;yk+Pd}BOf}~%b+>1U zUXyo|N}ka=T)-!+AlkK8L~trO0BV?E2?Qpq>Eh2vFHK(mag+PxW; zcHeH!Ugo`R=I;l0H8wuo*}h8qfx&Usn03c~w4G#)cygfq!HO%7qGpQDKF?^oHt5z` z8Rz5~QH~R}7|uS3TD-LB-ZICx$8ERFdbz|baP7_Oi%$nLYlm|bB%iC(d%GYxVT~o{ z)mi>srLQ{Yw3eu5#jZST{4(0pkY}1*UgPqdr{31TR#47klCI)v(HK5Y^n}Va&n|qIZI*e8=n7B z%~`)zPOz<5&1`igraEb6O8D#JyCyFQW&0GO(c(6B#fe1s7(bPnZY}{cP2>VEec5|U zNmG4o;O?7jrrRGDXP>(L+VAzpi2awB^+@@vCjYzHpDZ=W)J-zs;-5teR%Lr@@MmW7oC>uM^%!n-aV0rraU{D-BRXWDJ1zj zAuY#8?;xLU?FD=J%`Z)~D)tE^h$`(-%08gr$-R|nvZZ(Uo*;8kWuJm%MT<}!*1TV= zPXlcD_ePyp{%piqF^~6wqE^wq886lqAIS2Vx5c?Rj#pXdQ^YL=H^ZrKKMFG@w6AJl z`t2!wGxd$PpRZ}a`?{IS-0)hEw6Fb^LqAD zn>Cn4TJ)Gua9|eu@#!`u)#=l`<)eHw1Cw|Sde$C~-2X)!-FI2K=-{&7L#&so!g`AoBBS41jE7c9Q- zs5tlcHD0z}mfc5oEjwDfMt7;6$0gOZ=8sH@$|iog<3Hi`R8Jq(_x?ZC&h?(S#dSbR zv69Kir8!hGT=3+~D}Rkn<%urVSC$EUJ=bk1U+Cp;y=<~UVw`U$mOM%4Pk6O*&AaPM z>U1}qp77BBpZ3k7?Twk!b*IO?RrNg`V4jkv@<=`T@H$RGpYQ)K|LlI*Qy8N^lhrV# zCDmR2|NUKI?=#q21zn0Ywl(a(Ayc@~~sh+SnL-NnOkB6=}PxrW8Yax?#sIp?k@<06T^IxXT z-6U`-_TZ7O%c7+&$)0n|TWu_KUOwiD<5&14w&Kv~2d2l;KIIsuwKE)NK2oT#JxoM% zYmUnNX@0HuIxpHJ2==?rRXZj0j6v$~o!W>M>|8a)@A33HK|a~xr`-WSA@U2#qIO+ zU>Zm4N1kmA998FgZ}Lpm6gc6gWPJQOLx*=`oVEly=>-INPt;+YHoqDTXzG-~J!IocLo=-Dlv>u(bW!SWU^N~lXkI2MgUhX~yxx>*e zmfL;27x2w<>7SIQvHpdESn5Q>hr;fLQ)GW0V?BA`nyaH^^V}&NuQCd1f9~y((9!ea z(0eXbc2%)_XYZQwXS2l}gwMQXV$V2Hyh(6!d%x?qa>j4oNx!Qljn2$u=#pL##^wBY zrFY?~*e{ZbYyU3L*x1{k<@fNGhx&qZ85@t8UgEF+%)DWu3fs4%mJ?krAL0AM#Fg`_ zj#=NX{aF8%?ji>@jfEV)^4vaoF`T*Pe?Y;#@I+@r`{e5yZ%mCgI2ChpH)wX+Y`1Cu z%5ZsYly#-6b6kt33SDr$CRnqiZskOUCyP#=fAOJj-88|;lM+{#N~w8m>!N!PB^wi0b#3(KdEVE01h;iZ2M0ynogWzC!G85^vYlr_nM1ui zbNaalPrB1KbiXL^;G1_*X!=%}tsQ)w8V16fN^{zjGw!}xyp`*~6~WL4pI4vV_sZf- z-inBXcMT$Idfp!j*s&%wC2Z}Z)oYG)I8?j{y0JQf`?y}v`dy)qR$P3druHL%J(wp! zMt8?*x4m;#e{K-ieOZBt-#fD6`Ks@wRxM&XRN`tS8gM$}O6!DJ*LN1Zg$<^+I=Ab7jx0Ho{&CCCj=Xb= zitW0e)rg%pmsjWw&-BO^cero1^LtO`gzD$}oUXMfRo$~c{-I_;Rm{q=8`@0l_YAj- zzbozkm{zQ}-FeSvRbD&m??KU9Lo5BSZn~Fyg|1a{f@87l-YKPj{G4MypU8jl z$kb4}^U2XWT~5w>=CA&HiO>5^PDAl?dHuSAw!*#7yu}_)=RVL9a=dNJ-oQPN-gl<; zZmv3fEcd2h{_8Iqi)~+bZBJ`|^eyMNk$<`Pb%VD16PuF_e5Nj6VYjs4v-$hKNBO6R zi{JZt_UQ5Q?bqdHeF~n=zN*t3`|0~KrHGY1@t!}v-PX8MX1d<%Qf9x*!-GLzW6s~t zHj?3cderElO_=z_D}u{ACT3e6{{FRf>%&C(ikdBoKBYEqUvIshEZcN{OU*XJEs6n) zCGvtlZ@%#BZNkCGN>?`>mq%`2{4!oRf0*jX_wicY!}Dr}x8-sV#g-Z6pr z$A+z8Z+BfUJXSXI&aVj7RZ%DAKQ-hm-Mn+h=Vboa?fj=^y8rySC|z2AN4=7m)w^mx z?S;SjWV6f^5_ay$=KVJDf8hSu)|>yFdFEtqf4Bee=G+e3kTtI}SH?Y^GBJF8O5T_C z75lz8t$e_q_y5B&(`&KpjwdB}4UeXup0jJ6-I41?FL<3eubfMMm3(d2>dSTgr5*E5 zS2oYow>9B;w@{|0cHe%sMJnQ#)Y5JV^gnrRb4y^^;+xkq_q+2c7X8R|XKK15Sot{W z^`{~;CH8N-LOJ7ZU5FERD_1VMagqOf;lE2a`@_5Ue={rG*He&dZN2%raism+Tdy1c zK6rZj^}E1;f4Ae>L+d{{2L4prTfCYwEl&a5<|-Rf5+c`)b(&Uu=+ucY~B2K$9vy> z(<~{o&s5kywMleFQt$oF*R#BQJMR{53`+X`?zq4|9{#VwCUg0$_%@zjZv5(k$7fdQ zgYN>4o=#KTpOBZy^*SZP<b*GQNax1dm zw0?T%I~~3_-ouq$>%-%FjO=Yc%hV-DpY+|nF7ls9e2@O@=C-(~@&{JtlP`3!tSncCp*;ge@)xgl>16PYA4(AAF~|)^19yHv6erpYi7SiRk}jk z<#W}+jHk94%k|$q*SK3F^!nF8?*P>vr#+b~)&;7&zFsZmYxMAQL}1Tr`~MG??&IyB z`XcFJh0}t!)wisd7V_D8+%cl&fyY4Ws#1^JF!rmG*; z&0VD?nsdASV2ISht2_QCy6T%;m?~lTJ!w6GF`X6@$3s0rRcNoZ@p{SdhmYU zq7NU+qm|{@^RtgIKg#W`NZBJAw2RqKE9~AizG+v~4VOzV>N>D}YqIsW$AUk%x!IW9 zzm^d#EjOpvabG0$>eQaQAJWIpz_3vaa>ODRyyTM1{5Fl~>PMe#H-}xG z$n8yY+w#wyKR>kcA-~2Y;7k?^C$eQA=RAj^G{>0rN?c85Xy4mIms#a0**HaC`}r2${%z*i1=q zS%ZXPM3lp{)jnDKRAkz>-dnWQ@>TGY*$)fnsjzPNpgHw-i+xdxGw0m&nIUW`Joh!f zbu`v!YpeHsyP=w22bQtj!^pd=t1fETD!SE>hbP2 zVw&yw@88K?JNQ@s_51gBto-HnwfpvMJgvk#+2+xQMCGMs>5+|&9_N+vW_X-?WW&ol zYt{7II=g>O+M;Rn&&;!zPvy>uFFUquQT)NA67IFiE6vLDX5Z_c#BY(B6^+k&Z(po@ z%F`r%tLx{yb~df$wew}T<_I<{XL-7O+rPsrUNAZNlx*|dVSMHL+_?MYr>qW{9ua-8 z|K*dTD>FSGJpA2zD&ern_j`B6vnMT(FRrlkQEwNmG?;7S?bC2fN6fWxqT}23%PY=^ z`a9nXn)9hPpw{{E#~r*a(aZdD=7^Q*%}em-IJ?Je(!Pgc%eXo?ZY&n(KA?X8_~xLR zNr;J=~W1wlTc9 zOJdJGyIai@ckgNWyi>R;lh5FnXk(pwhS9FKdvAa3;$FI``S(%bv+M_y+vdcb^mRDy zxou0|)DK$|&-Jq{WObW=YJ+gc#h59__er(*m{%4TnZBz^&HH*Y-?d3r$!_m0)=x86 zyKM599{6ijXOO$)Dw)ae70X=<{H+)1-gN$agQefjcK-Wr>7`BVc`?^2fBZdf@T13F zq3loFs#?P>TmOEHnN+#CpKY?5@f9uY-w9^z-_6$dCoj0ble8vGPFL4D#E~scE9#EW z=?f>%?d$j&6*MPq=9#ePHGi(02|HPv5FK+ssFf#xWmh>{yOlow6~t66gk&q2s`*aDd(>#YOJ_M!S2T6ng~wM# zgHlcI&g%nCHKBahUgZi3v7R%D+FX!~FYAbnEvpn17no3)>d!v-urqg+6PDRXJ zAGOU^MDtL#)N~2IeO>b()y(V&kVuzN2+sNzv8{chj)vx%DWB8k&${rTt@^Y^qxtG@ zGi|)1K5puHx#^)s@~t!1)IQZ3Ss5rCShlHwpZCV3YZsg<{>SkY&umgXCba4cE> zJj|WH2tH)Im>dxK@=$xdQEGYVjmY2oeQs~bv^qJZ;@FvQE7!^dZ=3q*l=B4R!6Kl@5FM zWJTp}wYU{uc<*&$)l}9MWudLzb=Pi`{ZR8+_4-$?L$G74(bY}Ni_ayzu4?X$K5cp?vBG2D{qEz^eC-SFTP?g=8pyhwr=ohH zyeR+HEz@=zem{47*}jF*|LcDI7L)dBnc{u&(F}onl@t9po*T_`OPyb=o|{s?ML}SD zcb4^!<0@X}-X?pu3TDsx(Bxn9zSPiL@94_Ehu*ChI(pLn&YI@iU(fc(v9H@@F;D-M z@=KuuwT+Txe}6u!zxU&p;WT;E_oA!nXU}Y!6aA%O;=T6i6OO&p=eW)iIgS0(BV+HT z>?`j#Jx)*DW0Bh8%5& z-LjUf zPt3{DE2u1;bl2~&0Z;3D<)^Ym)7chw-Bo()DX__@(97jjnCGzvZ#{RHWFP#zw12oUT(@r|@%Lj-9K|9Mi?0RV9yfXEzV!U9Eze&Vo81=FU+|MVX-|J* z%7VKeY<6oW>g2tC_;dETL#5T0W~EfvM9ES+hEnIWUykXz?0E z_%rO9w{V`;-z7V%PFjeb>Q=ohHe25~xjoAE_?xv}uU<|%G~vVkSDNv%aeV93Oy?&B ze*2#|b;%E;c8`maz0Ohn>X+JV3=GzS3=FEcf~zP!zNEAuCpEq}vno}upz6XndH`_hRZ{0oF`TNs-cdt*;kIdfA z;=jxuy-&IFN%0fsUxp3lUlLb*-Z^pd%I51yYRM8ky)(Mb9I9J?{rv&USw2zPTbY(C zDm^q45xYI%WrW(7!%4H60zSSwm)sB$mHuQ$0Y{#eZp7Rj*@*%#YLi-uB%Je1<~r*y zb=hJQm#MDIGV!@akM3Dd)}}R+dt7ceUd)~B9o*lt^nU+?s9h`dWFGkDU5L8CmNIR* zkoI?v{<#Y4Pd*Hq;n%7mYQ((BfziudUF1^dMxUj#ot?y5W;w^rh>3nPVdkZvm#4Ox zg{NG03ex!2bmweqp~1Yvojc4{Xv_)ESZ8q5at@cfLf4dS$3*VF^GhmW6An?#bl-D) zT~^Tl%JSuP$p%+jT9<1inG`UbP1}6C_QmYvZvM*BocE6J`*`h+JT2Wlb*=oqeZ0<{ zJ`?kWdK0GnxZ$=({mhaR0hT8Wq%YsqU3YWZzxCWIY#WWXPf}F3F!xX^ah;cx@s$0| zlj1`jZ{G!o6@;~1)cLbqV5N_Wl=sbtrn7T1gkGH5^(l8*aFNZ?tDmw?>igbM@_fSk zvhL1Z#;RFo8N5C}IUil(7B9>)Ek7nSzT_jDW)eCdeow$F!QPY+zX$@Sc6dWqK zKSFZNHw8EK6e$*+$3OL_ZCoeKuzpz+TTStdf3H;PqD&7N1@_#3@MwC$m)}2623A!5 z`KM9yH}Aloi}&AuJsf}j{7e}<6XwBBryIS$PLlf?1X!)E7wR!LJ z`OgH?DJL#GYtmX9($K#lYULF3XbqTihHCV=a%OwZFZ_!O2C_EML=fBb#$#g8{v+SUE9b$_^e^XSP3U%pN_ zHKA9}IBP1`Yu*!8OHbt5>r2H+ue$EI`09t3kGB2#`-y4K{Mz*oH-=njYdgQlbZv-W zOy7yKi5522OSfO1m>w&`vPOEB*%_Cpf?Sg+{sJMaaYaY2_3WE`xqjudyP?g6f(xe$ zg&t+fyY-nNFG}auto*KP{H5*_t5>g$GMvSFzvYV1@_Xe8W-nL|>fVw1`@bzFn|Wub z#M`xBT;$HxFs*#YIG58(f0m%S`QOs3XZ0T6Kf2GRhr@bng!nV-C2YQT=RfP+#3#3L zxz)!Ndc8gCa~E&gWguAQvgY^=#dQp;-UY3jHgkgd z&bMcdhGgGcFSbjxU+{l~;lX#Cm;3*|bKm=@&t;Wn^QIz(T-hHTOr9mPUS&(&N$ASl zck`#G^TVENE>AcvmGBAHCiz^J2uwF+6_EHG6r_Die@1D=t%r?V(=4t93q|HK^X95H zoiXNSdAZ%BdtTsEcGFFZmKjKWQ&KiwX;FFn#X7;rQy#H5u38+@xGxo_aD9@Sqm)^m zVcv7cpQ%?hUjM91zxb~9M)SWW zq3dd=@^hCj`SH_O`;Js_(}G#PO$($vPPOgbQg?sOl{*i@>t683J0=D_k4-=H+ZUEf0P#ceqHz8rx)E~+jj0cptF4c<#+D?45sYOFMl47sGL7; zQPa6rKks8bGXsM&7xu%~K$UYcq;}pL=9~Z6Okgkfg?fpcgov(CYrb1@S5z8i+kTmF zm+c@^wFXz?BsVkZ&JfR2of~fazo+<=|K?QbeC`nSSyi9Yp6yk9%H8n5uBAG1dzXGV z+r7=E=MyJtZA+Tk_ImZ|pCWRBp)uKdtP-4(jmjA&ZUHCfh<|ZTj${(v`97B6NsRQ- z%f}REh+bcinix03X~EYZ!$gDjD9=;Q-0dgIUbdRpI46|$`eeEvXEjJt=W(}f^*=tv zdR4j4<@ez-BKeX*4y>D>!ftxRBFwr0ZAo^S`AD+=aQ7CvlS zy64HV)+UJ=84L45bWQy_j~VU^id#~p=Ev)*oFf{NcXmqSmR9y}ivj|y?H5-a6N>(E zf~WI@SJl*@@_peNkq3oboi5I-P4}KEQunfY_Egbe9o>pn9e39426FxBo9nY@y$^h| zvG9K0ti_h8cWy4ToVLBU`mo9IqG^SjXCD4n{+h3YD{fJ#py+0+n_CwDv0gUKxAl-i zYpB=0T-|Hy+U*tubjaS7b9TM4^MuE-%)3#)^(!1x#R~RURCwI0kBgZ7{QBqjljG&& z-`ZTV*86ZIoBM&1_H3DlYEy$|N8X)uCu!Q^#65E~O?rh)GB1b5-oMFkQ0t1RvY?FI zz5{j3yO-*6FDd-8S0!4#-fYbiR(Gj}XpUo#IgXhyIZ1DiIz7omr*Qw?`&_mBRsHX8 zx^4fOAgoM&$WoA-j#eiZzoW&Z#s;|9YqDd31-zq>tZP^6e(By(j10 zr4h)o#dztpYYTa2e`ibl5OMzyfBqdd`?B{Nulz8R6i*93kpKC9b<^LqyR3KE&AN2( z3wzJ?+GC5m{ET>}?z*~WnZ3lb+xfRI9Q%C_Dc|z#tI~8@S(m$pm4U%UfB}5oKl7TUY4G zrLbKOR(_V0`0(V-h5_H#osrAKX*ngCEq7pS5VuRyU>wT~K+b{HU?%AIv^_oRh?M{{2NhZ%#IqsfX3_m9rg-o1%X{Ukuz0kia zVwDf%I|^jo(b)gWeXZyYwWk5!LZ6ff{gD#Pl!^cHxK_&R*{X!w`zi!n52;lNv)oMd zH_W@cboxWBB*jM$#h&ob_wWC{sP4-&mv={(oSg5XXzONN66o{%QTN-00<#`}yx75c zs&%vPi92zw)e^pMpCx4Qer*l5o3roIY4&%2pU?fdiSyjzcYmbn|8Uzntu+6#b7%6z z;1A-Tel0rrzu@H58D4=W?zim!G<}zrk!gW}Yd}ZIW8TKR$coSJo}VnAkhx{g%&g=S znKhiEt#Q9zt6%@)`8DOu!P=LzTy=tePj?S_6jfT$&3d=(%yQRfllm`yI(2&Q>J#?^ z)6I^4{U22P=Vwepee9w9Gk@dH{Y;*@eSSs$5nI!#d@Lt7X{@|j_2dZ?WA8$_ZY$^X ztUA+~O5d0+-oL~ox1?~YhE2?D4(0nAlXixx`LNwCOTT^Rk3HUC zFZcV_ro;24yV-O)(miJcd1vitexbrB+%-jf2m882%jqxY%+By%>T+H|hI@La-#QmvtEtjv!iWQAtTIaKTTOqlO zZRh-BIV|goR+O?PWtBQk<~?~zwc01VnKC=y^ogt``!L;cDJ_gixiQ|Oc$1U z1kYP=>w+a`;^)@YiPvBKYfIp(SsD25jHTO&thXPW7A6OzG%>C5G|GCmc1EJbQNweO zJr6Gm%DHgll0c*HJQc@_DT=RBx=xzagk|erEch;`*z3G({dJuS2U{*mo#!`Qk+Cgx zQF1eXXzvWoPAyLfP0t56jU`l6x&JbO>urh`D&Yc(^Sd? zY?_xRvT}FN&kNd@$8gX7pTPDTs*;Cm)Be0Kt3$fjg>PS#CgZ*`?z1cm46g*RPlLb; z`qU!5g37(&x&Dvc1pdis{!ipG+UPv1rC`n#83o0Rt6s~SGM3b>@Vj}p-W%o{)A?f5GW9BVTqrpDZYRHZ@kueAFayc{ zG(MT^H?aKX6H8W(cc{_yLZ&ITouF&)k}DKA_s?;%7OVg1sI_ zyg&T40yRBUK3McxOnW(TzGu^>Wi8yvU0iWTDtKBPSc`lGjn>_q;~w)|K!8cua>+~| z;a2A+%?WATr%V2ic8=bUOf&n1 z&Mmn9y4P*D+I59@lVY2<2Uqbv(EB0V>$OJKDCfbo;5|HU@0sKlCQAES?DshPsXoQ% zOp=IHQqS`v`MRv3S8kYas3dW2-!k)gYn{z2<5P*Vf^DY=Xdcl>oA+bq>J3J=%)6s* zK5zVB*l@c0{QUZTrR)Fgk(l38FSUFBF1NK?4zaF_H8~wq5%^4b&bi4hF9Riuo-9tY zk*e(EsIZ7x^73ccZT6Ev+iSL-e5hN{)!y{7r{uF$^+b*}I=f{LCWUA!Gm0Z&Yh;(|s#_wMOpiL%!l$Gxjz8>JmUst;Ugh6 z2Yfd6ZT4F4GHGK&Ve{9Uj2TRBzPcuhR)6cwZD3pQS;Rk`{rR@XCN*o4cYl$*HaDv( z=*g*xztU}1w$BbtoArBPOr6n@Fy>=EOT>0xTWlEhDf^~(6!)}_sMjZNxxi z;{9t{*Ok86tMxM9=j#t|-SfY0u}@ueJo3nYQ}t-K=QhO}#`DiaHGbDQ^+Lnq_=L-X zS&c&X8>J>Y=qmm)ExSBT$bL_I!K*jZZdC^Nsq1Il*y$zpx4Je?K6~)#y z81Zu%lXm8v*->ye&enCcedf+p-Aer&FAvXIt+=%6y~Os#$82J)tr4*I$EBYxNN!_BcR3kl5v8yEN zUh7Vg4}aD8CkOetOj~XsP_s}h*|=`fw2Kj42B%YIi1X-sxo~_~7^u?SC}EZ;74iKr z)4zTC?-mtJ)ALfaPuZ!%HSw9pI*UnMjxRbg7#=kkZ*41Ny`VLVn}M;o$4eqfaOy*i zuEj-~%NUe=rYS`~iHthIcqlRAuw=sShL1&aqBWOyTf}u0{ITUFOj0+< zN>u;T2R4q%y*gf&`ZXVoB>8J*C^t9n^bt#r@K8GwJ8S=XUbg+di)Xa?JXgG+b>v~f zR#iSbMHhJ=xr1H$&x|x1GdOjQCB-bORCM!ZOEx~P5Y6<7^AoRKm3F>z)C>7U!OJz3 zr|j*2hQ*}qw5U{S2!F<6IY;4SXT{Drr()DLuODn#<`t|g6_`%Qf_13R% z7T+H?&xU!MJ!c)yf~gH=flAj+4z~pw^@$5>o^#KPn$lnSqzY(~+{ zgGzqE;tP`Go~i0piEp}Lsqxvs=(FXn=`F>PDT*7EwhGF-e(g?b>+ibm7~&x4lhE4u zLBZDI;^JzBDUm#jRL(s%3G8{n9VIm}O(FH<6Q>OxAMa~KrkC00S(~g)veae1TAJ#7 zsUht2;%cMFGh5BL)n3LL@pT&=h%~JinSbup<@8_jccX2i7pAe@a!}Lw?#S{4{GTA*qE&K$Ca5gEz@S=&fOcAz1kh7FZ3z2*74zsdv6UJlf%C5J@>?7)}gq7 z_+u$T2lUuBU3}3JlMvOHejr3>T1K5je^TxN`zbSlzH|3xKNWcL#`I;cUBA?qb0zKd zR#h*S?>d{yrN){g&X{*d$ecgPe!YhJ^5s#R=bKlw?Rew#LEhFh{nD!jUah=WXJ=i! zxt)J*stxCqW5yDf`y#4Kblw%2Se)UH>yLh^C%^To3BQ!?`6KFT$#QoO9g?)V^+0y- z21)KW>WrIiPK&x!w#V^m*pI8P6Dq!bo;_c$J^bL+`1^b6tZjCMXCJT+>&@66v^s2_ z@sG=wzb%TLlgpC9#}L82rt$0237j|D4lSJ$!Mxq_I@3FbTia)B&hk97tyAF3!B?8h z>h;<8&fVG2QCr;kE!rWipeVVDeewn#+v6Gg7VgZ}+V{xmQR1y*1;RG>YHF?&?!SD2 zXO88~+k#b_cW5tatTndF}Or-Zm=LF{7tPT9ND7nON>xts1=trBD zS5KXH_tj(d=+nE|w=ilZl_@T0bC9}z;@S+!6#@ZUH>6$lH#=G|{o?N>+k*Svt-Y_M zy=3*-qE->ZyV=#txu+$)_^5N{_mU@T=We_v`HjIwb=76nc|zVBxFiBx4em_;aGattn=9IOxHWbIngU`@t>b{ckR)el5Vw*+Zlox zg;-a7+YsW{E_Ssx@Z}Hwy_Phqx8hiE!8*zBP9K!_>Thjb%IW<5&HA@DU*!LE+EQe^A*z`%`#{z5bQvHoog zIO=2b|CM$?i*Z7s9sk5nE~3WWo03@jrgl`G&FwgPtaatfSYgfey47Ml&7b${rtDK; z%J2L9?bM?+oBx|hJzBF=ApFy!?yF|=+h5)NQMXD-kDx#Qio zJc~b^93_oEKi9GdEq?baal@qdTyllsweC)L9rs=qJga0Gx$pC_^?MsDEVoWSv!=87 z<^-LZ{E3e)ooSpRylh9L6_dfF!m8)duTL&uGOY_f7^!^5sf~f#c2bSK*u%d^CCuDo zHdUV$`!z3(+T`6Ph4<(E=3v>7 zGSf~i=wrkyIlr}=8zq#&_xC3-CUh=*ACaay|H9D@^KG*&WLq}|M($eP*f9T8ocZY$ zU(QU}>a&=C?ewE7?2^{y^;d{qPTA$~o%KeKtKg@tF&x2u;)V;loQlOo*(4_}of*+E zW1o{5!%C?~ht&AJB|Oz`#d=KkUG?@{&)Syz4!gUP42~>aa;=hY&+-id4>{gzZgiGm z>TF26q0*PPC@?2+bIis~3$~p7%k@2A+0UqX5zN~Uwp1vv&kH{CKV#4Csr4y$D~^5G z!0U6?Rq;ZK9aC@SmpdMP&I-!0|1U8u`zaH?VVzfvX)LqAZ+F#s9gzzkOIo-cW(@(GP5ZNum&vnhTERA!+rhui zq?+_EYT`KmTrw-~8QTl)2`L=vGp##UIbGsw3g0_R?5U2wxVf=+1CPmK4?ZQ&S!uqV zQXQ{3&ITAqJ*`*}T`{|9$9k!ThCeRn9F>3D+-zFPXyViHY?I4nyJMW%k5p%stvMRK zh~?XcBMpt6Ccn5kxz`3f^WHMg(uMJaO$gJ*HjbQ!TKm@B*mdy#)r(u5t*!sKC`cVu zVq468rXeWIF8y)T5&rF!B@cHfu9SMXye|GyW9w(BrHmZ*oqJy2O5@@9E%&bG#s1wN zB*M3e)+)p%D=lFUk$xJR%e_~3{o#EV`feY%byRn`%^Tl3;lME0+Qr>kA`_aw_G)}+ zTsxQdtEZ!Sl9c8@uHz~4yw>6SsvCbx{4{!dZ-ezZnFK$xyD{cb(QESL*Q7ssz~Its zW8hT3kGNjtkp=yjp$co6!};95dA$ zNxxF&Fttrqz45;yt>x*R2}(Eq9(tYb`{kot!-BfN{ahF1kM6$l3PuqAZSEyc+_P-{+_O~Rv(vJ9htX5oF3+A?8`|O>-vh{eS zcRDCFwKF5 zM|wW8_Vr(8_!6*ka+=|TRWp56c$7b`;4$I*c*fwGc~n79knlbK`bkIk&wm%Q)6+C% zXJ5yHw;UHTJSN@SaLZrU@Zz=ZWbFv+&Rge}G3GgYIIqw8@oLG+^zR3KSL;n(eCKt+ zu~#bdXBD%v^sv1P(we*IZ~ccUuP?kj%$>h|b8h0g=x=IS-LrJx6}qNrm2Ur?cxaY! zQMznawfgOx@>RSK?<9V>yyzR_i5m|(MgKf7*pRbj?y>c$AGPa)?!LQjUl#FyX0-0h zIPq;yvS;0xVD(Eox>k1CtEBG@9L5gPZ`Xb>`+V&N_rpW?dw*`Tkk+tXoUQ!o$mYfe zAE$B1Szq6OU-iaU4Ugw9^Paj~GwPWfylu{ucUz6K<=3aYeaILfBgbPdtdyFcakyLe zV`gdjqvxBd%~&*aDlZFNZ~Rp^quX@G=8rq=ukCqPJ!voViRUw&cx$icx~_iRezhXR z*51M`;DqRAgZ9VY{hkyy-I#71>u`PD=k!@;;?Df4_Dx}3aNd0G)-$i)?9*i~wwbi_ zUHeszy3hXtV=XU;+9GDX0{Jc&rg{da`4Nw zNxk_+cPc%iRSe70g$_jK3Mnj4ykp=tCA{;O+I)xqk2sFLe0OiAQ-JP!6U4vlu>FTvodIZQ>sWtwfCyT zHIo@GK2PnO=QB+py{NlrrdX)U1M9#uI^r4!gAKc#j%y3$X_*MJ z<-5uTxhS(=4|VL8Io{~b!*f_Nkt1Zvf%!Iy*XI1%WXdpi9$(s$-%r{FVm*2m1z5Pv zSkRl?YM7JU9i(%)b%(cQmiL8Tk%ns;L6+@qCju9KHRxZj*7{MmWBxoH*EE05Uo8ug zA1J*uRJEM+@%w&#hfVJ;_{J>LT5v(3LDAQl$1RA&63_0o<|l10dCPfE>}=VG8%8m!W@ab`H1AY8D*H-s zyY!x$QnOrQ|2$pu?}Mza(5DH1r~E&k)*R#{5+yy!DD+|E%b4j?4EC*LwEI@Yyz0H9 zZ+4*X!;&tgL(>?#y`Aq($S&&q>b|3?weP{9`&;za8~$~BR3e?(^^a+#H^*YOywwFp z4CTkyX3IbN|NpY7sPU?D4{fq_UIcG_C%I%o#buMe%hp_4ENj;{Pj>Itn72SS+{N6J zBP!1Bc>Qys>020%g-;PGpCs9XWgR>We#`+w<=8XPoW$ zziHMA(OnkTZ4b`7enaE0*LNlt>x7`psVWy2Fs?cIT{}wS=3J{oZeKQe-UtfQm05Fh zWkrW-h}^Fq<$m?SOQ+nQ^S#D+-tWsVVzr+a$-PYSIo_pYJ?W6a+xKpL&B097YbLeN zPx$)v`*w~j=aUEO5>{MsPiIiN9~Z-MCo0l0?5E*m-1lzR=elT)k~|FbcOKeKdI()W6MPfZO^P|+C0&acXAv-l5hD=y` z!7bGA$P$g1G*iaxD4S-k3;dlk9!r+Bm44Q8o{`y{KBr{f!H}yHw;fwI_4div-*c8< z5jdH+d+8zZHmSX8^R@hg9;F>q;D2v(pm3JOrdPN3uupk%KzQop`6sMf5|nOqy*gp& z+YtEXb8mC_tmDOJ?h6L^XTRNA_^3I(9=(LGwzt*~$o;o6tTwYs3;#PdScz;Q$ z-bUXzSyo;Jfhjg;i%RN>6;>t+q`6Ejy!~0SYwiR0J}#O242w-%pPZkT|K#H0RXc@x z^tVNCvz_iE|Ia*njd;|Ct=g+*#xMKBpfzpX#IUf=rYbp~$+N`QFfH~94dM;5t6k6h z)7ENAkx;gfMs|m%mSw9>kdEs-!-@rIg8J5(>!$wTZrk=&=|`wL_d?$3Zi(T#y*m{@ zWEyZMeDB(uD7CFK`$a?te{=DhzO=bKCnM7?m7g?DYFK&o+onqYbZP#NSKckVcm7J% z4wH$szO9E{ZTGC2D=}~0x6MDx&cx{RHXZbMC2pHovMzFm!Z+QjhxXAIdCEIyw}>!l zyzXk6;eC9nRnFWcHa_gj;tK_SiR%6mt-kdB6?14zlzslW9JgiFNA8)$nq{~*DX6fN zR7_g4!$&Ehv?=6*j+wg(pU>9gQ+8GgY+_}}l0UR|M%LcIjgq!g5*seNwf|<}UfUNu zvp-NySW|tKP?K4}*<9n$H*N}37p(Zl_;tFk`zwj}-MWXg+t=0lF8O<*!rAwoUhMYc z4Us8d7~b!4DHXr|<&ydJXHoeE`(v&Ys7={%FY+*V4PR{C&KJT(ZY#v zMGucF2~|#}0e3$i@ZVg+|L?C5_tS^s_b2kC*Y~NP&Gw!nA?Nevw$tp!iX~A~a>D}^ zj~sf}W#qest533bJYLq*}wvizb?Y=VmA{XEr?&A zXm<7Oo370G+n3A2oHwc8@A9*k*+2OZ+p_WxC!Qyi-VfaLv)<(Q{6DWhzI%UgmwV^| zmYYEvj59-5?UBDb^Xnllqm_<@u@kptGhOwUT4r}6FO=o{t-IUT%T$DMo|D@uc>7C5 z_$qUwlH9Q9d&}1p$iJ-1y&1bV@bPoQ(3t03eg^^*i<-mNB{m++TCz5zRLY=oU47-b z_8E~Cr)MUb8hqdQ<*o!TTbF{w(U(8=YJ5nQxG*i~{k!_W(hGCaw5HClu9344dsF@< z_C@*!ciyL>u{!%@;mF##Hc$QQv^ju=T$YEe5u|{XF zHP3<_Gh8o!GT88m`B2lhcE&G?XZe|51Qg`)xh#~fRN%7^u>08fVd8%ao;fMuHD98o zr7q<0aq{`yXlD`cRIuT&lZ}Rj2{RvOKG*TD%$)}-=E({f8|ZIiOt)FL+GiQB zK5Mvyzqa0e^X<#OeBK(}c-mv3<%{a0wr{7%CR+MVl})r zBVwnW?t8GSXS(b`%eT`(s%FS0$_h*gzWkQsbgIZ(u2UP|zdx1Ke)v?X>|2ggsR|%M zc`Zxm=id5zw#%$po-#!H)Sa+h#+kF;7evH@h}>nZH|?aGnKw5dx}Ci|lj(N(>dZs8 z%hzWXzPFq0D|{nvx3BOG#l+nG_e(OguX(8*y0?#&L;B(GWrAk$rNP;ym*#!Eb=&a# zO=d2SqL<<=Imi9NEtBUQUz+^nhnZma^Or5EK3Nw;3k~nCs0=sU6L3&}j!|3c$+f5U zMb2n1=2^U?dUB)Rp)7|FmZDcDwz;f7eCedyR+A-Kr#WuV;JI>qN>AddYulCj{XTwk zP7N-+ns7t;5a&~6)zm#(f|m0*oOze^e1R)xFOSFSKT2L57raBy+iBWV{CJQ&+4vTx z2EPdZ)n!qv`)ohdWa&8lh+ofc;vkY0DX*qcH1WYCwlvldE)Kiz3##8A%)H8b{9R}N z{5dP-n$*Gy&#ZXRm3eKex}B(*YkcACorxOvVGy# zU26F~^JezT*s8hzUS_@fdS>>qlHG#)>Y7&AMy)#XbzW8A#Z!`-OB8bUI35Z8aMIDf z+46;hRLv$2r8TDOii|jAmVKV#U=^Fxx9aysmGu*wjvcwB|Kv`O1IOm|-IvYM|JWQ| zy>(Odrifa;H|bb%uAzsApW6R(HENW0Bk5)9TF!9|$Gy5@E5< zn$mdX9%sr*hiCh_rc4x{AjVpnu)yt1W9O1vFBHXpnw7`BeQhw8v*V`ll1PrV6WzGv zZL@TiY29DRR96|w%6jQhHj_$VbJ9nL%>n|GUvpJl+d9X6*2eUEje=3Czt2qhqP6lA zHI{nROLtlua2&|KR8xPF`f=ss_QhR4 zzddHA-+uEZ3&08OMcu(C>_3Ow%SI-?5x-yrh-I}$eXI|4= zH?E>9M=dPwM0^#vUwfSWZbO?P~5?|XTg?yQ+cyI1Q5 zUj3cCb%#&--!qw$zCGu-KVwOLNow|*N6A}PN16WE=X7pL_Av&>15{&(x`O6TMt0X|&hv?#IR(MWL*c5slN%v%lVVqqOK{daVAFE0QZCM1O~} zhOXL`eCLF0`l$(9=fAtWFyO5R{|krMtv`5POyXY6oc`RlHFQnxsZLg-89_7CeKfvS z{cuvN$vu4Mu~h86zYbq{n|}AkyyWO!oWXG|+P?b4nHiPartAv1zU0z{H^+{A+4z{P zY~KprZGwzHy4d6McG)>?EiR2+xccm>vcAyO<+mm8iVAL=D^cEZDzBkrwff_=V(H9f zuggE)KDTfu+v{aQ@2eUoFP05+vo_A@oU5armbYKwaFy!huWwT1-(FZ3xy9>7wEluP z-FI!-KQ1Ng{Z_D2p``vs+^79ZyW5{A9uoITShu6fRXtX`!0|*;Tj(L7uaCku@P_0V zZ1Rnpb*sdrrKo7)2kl)}^Sg8UGxNSZdUwpF{ngg`uw!psm`+TIo9mbv7UJ9>_+(9* z(xH?MCri%mj#_ajUf+80k`*m;N(Gnwbdz)qk9OtS?Q!{RW7PTeQNP^mT9^84(d*RO zrNJV_%YJjw4AvJHzbu;iW{23!PVKXa%2RITnjg!WEPJ4_B(~FBbj9qT*^4$hZMHVZ z%zVa|ax1{p?o`I^XG{z~gyd_Pk8!$NRo?k|?ZLLHV5X-IR}UUc-@V35{fXJZ@ggY6dH6}K`4 z7Tl|lVEJs|)%0NDrb9n#FD!}>d*)&&y3xnxM=FE$HQkwE{%a=d#a(H=Wa?i(&c1ekW$7y z-JJ&A0j*b1`8F~)|F(tDzqkee8%q~@b&2M`dGqeA<;KROjTUbh%XPnf(v_~r?Di{} zs_DEadAH;L-?q+ORhvcBbMxPeMKA@b6j>P0sZ6t2ayf4O_fJPltWv$!Tr&)B@}2Q| z7th)kJ7bR6oW3#jG3%K<`$~WH+1LI|GLR5ZJuMP`v1#x9{j>i^>s;ZC{$TNKhVhqm z#~x4qn)R}}&wcVS#^Rd$lB}Xp^X{cx&7W^OWzNc}&NDlvi>F=q$k)E}^7h61WP7Kb zss38`-)!&Pz0Wh%)|tJIsBn9xG;!uE-HK&;;^j8BGpqKN_kBP2vAXWSy$J?UpQQa( zfBm~F=t|H+vz007;$Ii8HurIC2-xt{$Tw{B*SNc?mz3KWgMV+`v8T%TYt4Sc^OoVA zOTY58H=5pCSdbO^?t)P|pR;he#O=($SyC?6_oq3}fADd-J`dluOcl}HqD9;8oM`Pj zaFac5O~Zw?gK#_qWJ-COO7 zR^Qgx^MzT>zSF~B8?6-GY;Su~c5z<0z+}GZB91mX_uTx;h0j)5|Kd8g>Wuuh^8S4X zw!Zgz9>l``((qS(VXy=j#+85SnPtDls7sSfJcx8LbhX9?MIg%$YH2>Xv)<&UXX;#x*uM-8I z{0%-HZ)2DEQ#)Bx%w68)T%v=qw^sB&JW%Idv$Jt_{mZM*WtZ^8)n4b)`pG}-quTDzUh^l!Z%thG zrl)X+l)TQNf7UW{>wn+bv8*Djp zU-RFub@d&QvveA_u}|pnZ+9_$_xS!f+4&c*e7w0lyI{BGj_r){EUX_mMYr@7U9YzK z@o9m;O|`IJDN}aKzfXTwS}lH*Np||J=&&|>whFT#SHs})MRzn7`{WBv5S(VUe_O53 zoo*3LVavwcYa*d0m6A(OM6G)~&DiNiiKynpb3Ss0k{etJn35 zJC3bon!Ktly!=p#+9^#zR!i?`5jGYM={gCjM#rWnEGlhds(s6R`rw(lCMNGU2YNaQ z%$!m+Q<6j2%xrW10=AE8R=47QGUc$nd9M0(SyS#y#mQDm^7-pMFY?TbR(dRSUzah7 z&wb6ctoU9vhaEjdORAWXgn#=A|5vNecHy=*ds?w>&C!Y_-vw?QD|`0A{7()`$(6c< z>ZBj@<~W=)^E_N6ec;_S+qbipJ^WD7eCTya)SF`_7j6ElE%D%dKPQs!gUu_4l1snm zTwd2G{^@ycN&nlcToNHa|9HRHDVexd%)NNwHm1!n#}`Lk{TQ3$+953A6%Zw^z$LlE z?ZDDw9j|*nGd#-XX*Mx>6dovXEJD2Oe?WpibKlBpy*y=2O(DhE!hZ8s-)z42COFjC z!YpWsw{+8GeM?vxb;Ht5tHcVQm;U9Bu{<{g*b_365L__Mf6sr*Ni=bv+~ zm{nNg%k6sL|0m}H`>R?a?Fk#Bi)-(EEwW7LlkGd{Hg(DN`xWm)OZg;Z>r`b8d&68! zgXSo|oVormA75VUr&3?{ULJnH zU$JmS$@-5)k1wT8R@J|M%6Lth;Q{w&rvB%i9a~QBSBCGk+OBr(OKIR-m3VR4Ou1R^vua{4iMpQ_ z*y>y`%jdz>zxHiUW*-ZRe#gHeHOcpQ%Mxq5V|k}_BeyP1I{NaQ^4fF(mC$R=uGkb=_0brKD}G9 zBRaD`{;|Ka)v#04VdE!xL`&;+Qm;-<%b{n* z>^_2BITFCtW`)tLpY2JP1{1(X@C!TnC#@P5gk7kzUhX>z6hyLo%=paxpPi5_R>_f`aQdL&6}XUEG#B_OP-3SLxqpm*<&fH!SfDw zr&ao`@bLE!NIoTaX^%8_P>=>^+k=B%D!sLey#5jkT@S9f zrQ(o`q#$j9Gf%lge1O&3Ysb5A*YHfUPghU-p-Ydb?Ew$9nirJ&;?!60K0ow>n# z(wtACjG_;e%@YD(J${U`T&s3m{6xRN>kl2K#Lt^;e9{@RqxbIfR- zae-sDurf?@HpIjled(J_7uAes*`ngtpJo~KKMgBz9NtQ_CNdb<}) ! zH18~s-5|e2^z@7*rX1xG_aKR-*#eUesBL}baBvl0!;8vWuY!!uHwwfw6uwTBPz$gT zy~0@;qA4EoQRc+`;*`Csv)Ar0^l5pwRjNh)!?qKRP`?k8E7Kd}HkAYj#nh z46mK=N6~lsCd(~D`~;?uM*GBN9tX7bd9^=oTYO^#XI)WoE|RD zuJ8wQ*X_-&-OT2e!uj{A+1~l{{}-Aou2}5LeZj6h$!UQZd+4NJFA6`MecR={WL5gN z>(?Kjy_DxC?ezG-mT3hmkNhuRxUWB-P58~T?+%i(ZS1|q&J*|B*x9)o9uq&F5WlEf zbepMaLh+~WApPcroHu^Iv`JU|dHL)7^=ny#3)~Kfl$*+ZdNSAUk&LEDz?BUf+RnM` zY*Kr7$=B|h?fJdCxn{VUCvxo3i+q}4F2o$TeueWZ#_h{Ao?H4K`up{V`1dY1D<0|d zQg_7|z4*ecn|_^Iar#k#$7-ivg6HG|^ye0BY;D^6%-}np`G)Pa?fhnIXWgB8D$OWw z>iLyvPu9k>#j@>q-gwn?!UnISj@+`FWKKrb?{2Vp`_t@&_CK~Wzkg@zzHZ86ZOc1T zZY=^3E@*cFPE%0$xSr*`=Yi?W`m8i2ips^ z!yD zb51;-;>ftEM68$JbWzo9&L*~hj#_eDmEwWjOXc>yd}C&Ift_pBJ);kQzZ^N*wfE3X zx&1F6o(_Gx>=3diCK zx7>TLzt}(G*;n#m)uPo`Zb_UfN-s?Q`sK;lMXwqg4cDKlS$+C*w8_I642v!c=XV=P zo!{7bwboDQsKcFnJA=L9?|H9nTfHau!qd{Lt5~DM=bgRqIZvv*j+gPyLQ9_NYN3c% z+f_D17iMM0u5%vvr`E86(h%Xaq&wu)CQl{op@#X(BKU@5lpObUW zQ!Dw;lrOghw^+XOs7ai?HDo2mQe?X@Q*aIr}z0S}`>sH|^x4RiCBnpZx5PGvG4dkk|Mn&$64x%v<$( zVeNep=GrBnn)^=rNxIloUDs}UW%EEU_RxlB|1ZqzQGJl^wJu5hE%UOCy0Yf1ANJTb zm`;0D^K?bR-Da=LosU}gO5g2N{Woi~Sl08E`Te{9RX%W+H<0pR>p8}fEhgjk_jYD< zL+R8ubNc%S`T&JK zUwie}G~`#wyQwvNR6US-J@K^>Q@hsBgS`(PF0((`nkn+<_pkkqYo%XB&u}h3r}0G_ zQE8`?ebkxS_wZSR2m=FqDehfS1(orM1(|vUm3L#Si*H*@`fnfllh5L;rBd#(!e{eV zA1SMxd`2yF=MmGB_pVM`n|M(u<)hQYD7&O=+h6al^ERk3Fx8wmr&78~(o^Nv$JcI) zFES`TSO26HnSbd+)y&D)4_+_uyT@i8pW#+#XZ7pnhmVWrpRn`|Pn_23>2s(@C(~=a z*%K??M{~}3&YK|lp?b*)4bDfFk*c2yHY)xU%GjJT@ji>Dt7f-K>o?v=@t0O7SGXUl z5EK1uu#b&#wWx1;qQJz;8Ba4SLZ2)+tNhx8(P0Jal7$l@Sxx;u6}Sls)F^Als>Z+k zGoi+VL&GIU`jdVBdAs^wKc4Ns|EDWu>YCXG@nKBfE$vTuHZ=0CoV-(I#@QEE=R=fF zXq<4k&=JWQzd5O`=mndKo8Tdb#_+_Rf`j6&`+R1Y6bMS$bvG5bPGU7^t1J+8V+btf z+993#XD7#E%gB5O2cL82?oXU;60tsWmf^3}DkqCBc71u6HFwDiracT<|80LvkeS?l zy#Ltq+5O@Fz0-gGi}lIhrn2MIyJv}9=G*)vo|jw3u3fCKJi7eN*5Gj8xl<$~=9ULF ze)F59(YfBb^Oa`iu6|Nb5wbnkmSYv7Un_s+i5v0{7gCVkRl z{n?n=2lN7W1-v-Up`wt@p!Q?^w32VF+%r3?W9#PYUS|BO8T@^E_IrQdYIWbc^E*WM z{`j)<&Ecz25&NUO8L}7KT(%XNdTC9^r?&++gPxl_dC{gaVPVGQ`n3z2a#oj0Z2iPL z<$!YSHl9nh=Rf`Z=OHIIIlXtn-GW-_mbDtnRn{q6GG*>oq-I&Jow+HBUFp5tkE)7m zT~}Tov*kB@&Gjs=tIXi((*IUIKN;BVEGuhx7d3s#**lqm`@s5ur*Ga=_U>K(cy`p< zi>oFkJ^H$4^GY|HE%xWl_ls@(&$(*bk6G0dnl2|Ec{pQNa?c&jJ=*8Y?Y8|++@n`y zx%Bh1*BU#y7M&^Nzh3!j$6c2DLYMg$?O8u9+A90ev{QVnN?fB)B z*UY*5^Y^T0j`Oxh-Ar5`>(o1Y3&&2cOC~!P7N;hDjX$}k;o(p5S^N1;r_MUTeD>$x zn$LZ@O@BB4oMUXId_SHw@y+kWM)4hA#h!n;&vsLixwmP$W1HBPl8qB1{mj?|i=I6U zD&Wi0^K-bhNodoXu1QZ9XqDXD%`{b0uu^?uZQ=^YH%nG}3;%I*a?VYeaMFT&n|rb)Y1In?D4o@B{co=y34pM5*^{8{3!dB?8rlvp9yyF0`+@tWXl zF4uMg7nOFVdoOs*rKg)d$l-}q+|G4PHF`qa@)F->zsX?-bEW;=<6b{7``q%e)?{0; zbfr+H;_bPsC*M0AH}lf0)u~F=>#ix3U5ZFnkG#Ck(_Qgxm+s~}eLRVmFGS{*WmYrn zE!}xCZMVu+zw+L1dS6~YIVO{DTc(5n$9#M} zPsw#HXkV>U(H4~(Yxd3UyFf&_sw zBJiJAqN=Xg)S8N=Z~Ug8eX7b4v0U}>uFVdg?FZ<#M)*Y zzmcqVVo^bwWTowk+Y?Pw_+2j?P8YM0wab37rSJW{7jjIm^;WDsvHIbcm3KCu{B-W% z6!GlL@9Wt;XIorO{(pYOKvYTy}5Sjh8LQ(1|4#oN7+^` zHlG!>)^myd0rtk-!Uftt>RX(@M@;E?y8n^7(i7Y4LXSh|Z`i&KocZrgkG8}9E7r+R z*Zr27w)b;+;f&`8r{3s!tjn0)_^97BQ)-{u!#g+GlVjNT@7l$A>^ajfxBaW~?7oM; z*|sXH&R=Fn?=F~sFYBOThRxTyCY3FT{-5-&xU713cJ`moRhegHUvGBZV)LxN^83Hu zx0Z{TxaJ4`7Yg&{+;OP%*R_XCUkuZ?$FiQ9SJUjQyz11s8@8*v$^wg)O=y`p$yI)} z^dle7j?!R?&$Lf8RscuusdcOb}!tp=%y5pNcyGs9<}as;-=>}@;>4F znGv(5&H=UqnIvw55D3;zgY3b|xz&u}1b!dq@prm76T&k8*|CfV2j`SEgd{lD$! z^X=`eNFZ|6*1{)BnD&xuQo{kwJ5 z1s_b)Kk`)Su)e4Eg`Cr^76%-HW{GF=EJ?ZTv}e75{lhEKq7}>^z4ab0X^fe6hbewb zeZKapl1nB_vXl;SwD(Uw+0yM*e!9ZiPM`BPzn@CtpH+2Y?xlnK>O)%s`<_p) zYCVyXWWjWF%8$(or{h1pDQa52Nb8{T^-@=v&UepG$#y;yIB#Ofqj+gk9?xTr=QC0T z&MR}&r(Id&5$u!RE#e`&z3aCT2kTnqxzq3bC=_({%WPG?`ryOY&ql5L{|+x9)_xV7tz+L?53_9Y>OZTcNNt9*7%-sQ`FE@A37 z%`=nSjQ6`Jd~{waBr@?_(pz@lwCws1S3=6&e+KP#oqS_UQFhO^b5;j#$){cx4*Fhl z*Zu3>?uqp#vz*=uU;8Tg|GD&kXQ9hNR>sTXQY>X=7CpHcywGz(kELV#a`uAu=q&5i z8qZc9nqcF_5T$csqV^Onrk(Roe>5o<`}R>&(9LL}Wz_Z^Q7NjgbAZQy zvB&DiS&JnccLW`xr+-;zQvPz)tqX2O$IhqY;Kh7ssVsm-Q6MOl}5C4p-|BHY7xBkuF`!{~?-~9c5!u$Ux z@BKe=Z@zr*jah7=HW@|{Dw=tElLeN@>}}|uu2Sd7$LBOLZZ@N~)?w3WYYwpZ9k^Bc z)%EM6eTqG;)t2||gcSr2cDTKL!^l*)>4UsU@3Kap zn{`rGuUPMXsQVS$36Eki@xsox|KqE^Ul1*2uiLJ({;|Zh)4Ov`YF@8gkREV1|JVeX z?Qi$5+d4CD{nrJntKG{NFFyJ}R9=>KO|5O9=$hzE$vC}5y{8Ktn}4^@zZN*7UZ?0! zwV>Y@~M2&S-cSSm_B-p;5p z_$AwLSUrJt$-R{=qW@Lc4GwQeG*WTZ*2@=t@Q8cK+IKP1!`veq4BOrc`EAf!G4+Feg5fmYgW>bUM6NbiT$B88)il^+uJDSvmzTKkA36G} zYgvz7$jcUfuOd!EON(oNPTkTzKh1izmp+%*p3vFRLD%w*F7M81?+sn^VZZyeAO#KE zLv>abW+hf>9($HdJeTxgedlsM7flTomYWW1MdKyQgs!xmi+a5<==@Cyu7Cwr65&V9 z_6JXXT#|UNOENpv>hY8*Q(xR}iWWPr%{7IICG?HV0olzN5*?DfL1sdY$!|{9u(5i? z$Alh9_FQ!;>Qw;G|9kiHzIH0c8H;_4;)>X?KVS6XjfwfEC0w7Joyjq68}aLkE=(-gS;+Zh%0~&Com|)Ynp%=S91&Dqe(7D-$?30kdK16i ztYw!kmdc;|&VXnB63Hz$Bwn{DZj@?XFlG7lYK3=CZ^o59VyT{KtyaCEr*+BPqw9QC zy7ye9Sl#0Bi;kwC+>n!v6hBFe%GleeS zSGY1a`rApRdF<83A4FZg^VA$>&|B!QRvr1&f9I*S$ zv9k4vcj`@E%{f>z&urBkp*5ejRNR-fXtE4>&9ckeE<>CB*X*xL43`$MmaRCe88Kgu zJ!AT$sq>ccY)ZW*=2zYEKVjuUwr$aE2Le`pPdXy7?b^?mTbEvXFSk*MX{CZYYtG}K z#vfmH^7N?$$YU)7x1^ZmX3ADlK==FrZZ5jRPBdb{C=IR{$Z+VmHO)a|nlTgme& z+wG1?U=H(Ew#z*SSlN%KT{vKynsH#d=4G?*M&A=SuKoXfCfeG9JAp-fhp7a6Ty$OG zYzdvXm+WU>9x&nQV?EWp^Zc`I`42>!SADzrSo-++41H-+<&NvArA#yHmTOG97&-B; z#>SAQ+~SAkA1Amb9-rl+{UGAzxh17x&(*}ePyg67=kL8}|82beS-r>4cbA2f=CC!omM!ma?u}Q8yH-RNF5a?j{kq3Xe^2t*5&b<}GwaT)d&;~F=dM`4Osi-4 zTled$k$3dLRjy*oSDVKP)+~-lmcDhY%lBqhn-**Rf759XIv2LtZ$6^Lmj5Uy@~542qYh4zsr#vZq1%3Hmfnmh7gq82Kdxm6mU_5^ zqt-vJ=ZUw(Upo%}Ap4FF9&eAGuII79VA>6~WItrk;QRyeM3lh1g+-Pu4wpl>as z?ZrvgK7M^%-u`gHb^Z(LY$1EC-0rtB`ABiZ{Rw%z<0HrZnw7GfrrXB&FY$eUYVC_e z&Ekr*=F;-Vr-Qzk>7HElX~&o5TdhgfzL(|MwT(UflYbu#tMc-BN9GlQ!pX0>|jn|8ACCe_6d@AvA?WMD#lYY%PqhvN`3S+jvp8dnb`OJG_7R-FZ za$#xl%X_)Y+5Jj|UWxd##9F<+t|1Y&>7ZyHvw|lyti)HgQ zo5J9osexjaw`R&S#G1acX}Ejr;H;9WcU1`omd-r%WaaX+GdTR-UOTux`R%RCyt|o~ z)O_U<3C)W>Fl9Z1eDOwh^~=ZRtyE-u*Kp|16OX!^1|0@sT~nIfpZYH^&ENXX@#xYo zj-}!yulI-x^_TQ?oPVb}y|8HdQagL2XA-S08+T-_RGZ*p!(e{%4o}?QbBsGLL->sO^W9=5HT*7Mnb-3|lO`bg%Bw&JzoM>aPACwxqa6eEQ7tmp*eZcfOC2vHdHo z!h7A)_TTgSknO->h#mqe5(PSm&tsi1aqfS`XR_f%GO^nQFo$0ZCSKh<+B(J@9elD9TIB>%)_f5zS8&uxnkYXZq^Q>R{t4kpf9^!d2|X*+^GsgJVcI!& zQ`e4(R;;I*lh^76E$3YSP~v5ugi`O1SF`t-$~->(gO7V5bMEyd3#B)|PFHXr3Td5Y z6npH$qJu|-r1j*p)02V>B$NF-s~)+<7HK?;PxzVal<9E)%p?o`$4;|;*8Q+J5~p6? z`|q-ejYrJiK*vu%1UbId9(nvbM}74lc7s!Q*RcBOCA!T0l>TeNr@T{hH+(wJq;Iq6 z-^597o2Q&RRiAT7&-o9FBZI{pSI=X0a_bbe>Nh4hF8LSQ;I`RB>rKZNc~=vGzew|q z3%O%-;v!0Zoo8cUsF1{dcRJ`mr=rx7(xSY~ymZjgu84ThnNIcnQ{EetPt-T#R9yJh zR-$9d;}@b+n>D6?TN0F#JBRn?qcwN8%63@nt4=R}d&6%ILwU&BE58`8z5Z#xf970Y z-UBw<9^Bv;Yl`((uJC`B!?SmyLa-5c;{LnuOg^5kzY(M}Ww?OKk7l z&n$IlY7i3CD(qo)eCcsG<3`iNRVS9NxUO>K`}Km;i&o0JJG^IdJSGudPGM_`Ps${M&T(AKbV>#Sn52YHQYRdmfiXFh%L3v zpmXOIrn9^q9SK_+jEl52+{^C;7CPJRYA6;;6zFW9@Ae{gtC8S8o^_h#6K+qvzhtG| zruQM*C%xDv$9q50R87`;!13zquY32nm#>eSsFdmvXH*~btXnOBtEQ9Z-P_E_`*RLA zE#UmT!be@y#m#e->9O4|F~^NhDbKiglS6pMGpmqq&pFkaf^_v3J1VONkz%+U&X@~lZ7@+#y^9Sg-cSHnkPThZ~lDwGyl2Y=WRPX&eiRH{O8Jh?>|b6 zk4vO`mn7Z!`pB^L@Wl7+7vnY@xbtDJVK2w$Z+WboGJCJiVsqTya`5ZVme~AXQ6k4{ z{p1%;VGX_#v9`cyaiW8PXP3x3#oHH`wCb+qd8ew~_DkYmXJYGPH|7w_Z=&8?g#uY* zp9%5_MsXZw)H-~s<1WXvlPkjBg`Sx0`Cz*D0ruAa9h_&2X8!(H5U}>ZGxha*UEV&t zlm2*JklxD0t`4cYp6c=NozlIur2l5fS{oZ1k5y9_+}hT+B=_|P&4Pfwzs^GW2L(=T z71_wNW?jRY+biRi#YAwH?dPnzm@WORDA$B%^=es8VMF>@!d$DCPg$*}qQ zwzqQ=%r^QQp2AZm%yZhv>a2{eSj>wjW(A#pJKHZxbJX1s1FZ<%<>!27EN@0BDIvsH#ts#QJ5%v>cz9|uX4>8agt zIi|&RV|B8=*Wcwzljl4N{x^L`)4ts7taMM_)za*)bw}NwAF+;6&Eea%P1o~)X!g4f z-Fr)>yto|NsD0Fd`@B4>w&(_>;$!QWCM9Zf9u|yBZYoTjbz3<1ZJBA*_1}$&cGGMR z$34GP5bn9DXLZx;ms*9&#lqY+pEs|xy;LU=e(dQTkFI;$Qrpb}bGl};-+lAR>xtyI zDNN_5o0`k5e?3=0GjraQFX3WaKK82S+T>`N>z(e+_mj}qHvczY$NaI7`q9|RxVMjZ zw%nek9PsSfQGx@tG!X?a98|8(Q8lki3pTX;O5gji^YVM% zw&i<`p9lYcBJqFzziZO-;^s{EJ0z9Zs@=cS$jnMAvvsoD+r&%fHbxb_&|Y}3O|P>^ zKua`anXuFa&;GjHxyq}9=NGYO&(I0`aIlEuJU4^!&TG;iQq0#T9gzyy!5+75eb@bL z?e#lPKQ%hyIiKgcMR+KuRbOmYRf?IE@Q!S~oE_OZ*R17Fyt7bt^m=*D``7bNo?Yuo zeU&fIHUD^yA$o;$>wKR>S9h#^RCPO8uE^w}q|t|K?-g0PdT%&szuy13N^Lpk(RV3p zmkKgAxo+7LYP+}RQ_`jR3|TW5On(vL{b8BEFQak&L>;SOpFqYVsWbBOI3Aa+s4w5z zbwRx`cAm|DsU`mpJNQ5P#}n9k`TtLg|MFj>1ND=4$$rTX|Fv5x`a=5giNV%>+(ie9 z=13;qDZJ#U|JSrqaG8fYUw@Hsc~r)!JCkze%9MEXA5i|GxLCv1{Qj%=+QGNj5+yz_ zWt={D^_<7q*Gd!Xm#*`=Dz5VGx$3%zErCumS7x4JYW%dn$RaRvRoFi!#5|sxlD!Ux zl&;8sW(I~oT(~R4;>`5C#FEk?&^-rh!*2K8HWR2de^5Uo?V(p!?EMKWt>2h-cwP|m z6zleFvH{)mq&&OBMN=g;`sR=O)=Qpr@42_bFUj z(>+PtatBkiZq8ZCb?orN75wHJ!RtiMv%KJO;(F(}a07d$*vA=mB5Irlf?K2083e<=+Vc}jHWkD$D3^3ST=DC} zLxCdhuPvIt>X^LOJ&#<-7{1eGslwy~mu((KTwGk-#vhB@6&Xj z4K3NrJYA+;xHe@~_V%QiOAVX_FTA|)Msk&;Z2hggtNCs|hQQV$(76uJbIHTaVPmZHrFfNuHt*!xGOm z?Zb@4At@5q3#%Rk$hTbjmOD}Pi21?0pYl#_7FgAhyl>Iw^0#6a9$VN&R4n?)xAn}l zC0#~p0$1ffHMy+nf3ZB+Zn0Rv`LnhU4gZKFo?&&%6WH_n%dc-|e=B@=aNGPw?IBT~ z@W<(g#kX}RuX*(*y`gCi_mQOX9eQ^z#LSoeHs#zZXD+r~Cxlhz?pqYixp!}NTJ+a7 zyUv=f`eh~j;-{$EQfnb+*4YcJj@h_3_C0OU>*4V&_E0MIXK7lnYIf~D<~83GoX%D} z`mJ{C>$&Y)-!V5t`?vG`d2X~fR_$|1c59_hPu=_ffBsf|dieP5>jzhtcg|E>{Biw3 zd2{n+?4j2Cg_C~k9a_>Mptme?*_VcOA04J!vT^dx{AY81z0ZsU%~f+Q>TV7!VBbA; z&yqw1DetKw$0l#RI-B*4f6&ug0=-jaQ+7u#Wc}p67ZpdEm}=_1-yU+w z*|zQa>AkGqS3WO`+5GtXg2$CA_hT2c@;}-kvTI#$?IzxKQ_r3*fx9hvp+^#~YS%`T z&fVX7S$Forug;t2K7E(B+D=064|Ao?!s<^sM>0jh#f7{BJ#pKB>p4$D> z)lbkE|mSHka{?XM>t>3*Z*r=YwKkM`P&sy2*uV)*Z@yR^@J@stO{!i1szAHOs z^QM4l&vgqcVHURe&u*&5K2z|J6nA`(!{+(7J8o5P=}VWULrbUHg>L$AX5+ov=uH)~xj@4~`vG}EQ$K%=~%x?TjGK+Uz)LH(& z{mXyJ_utsp-TftwC_F$%qt;eDWD#d)VDJ)VU{GYhzH$#fpb z|3kf2@s)wH=??5?d~I3YZuolmn(o(YOs+Z?4HCOYfNE*&jz{_o#s`5z1O(*OSb+xMWEJNHJc6qc6W zdgaiysV0pprm4+&_g=8>!`^ecwo4B?@1GzldT`w`uNO;8s+Frs4*kDn9R0khE_XxS z7SXhVf&znGn~Gwe9rCi0W%bnSS@_eVf0juVf~eFSV&PmUgRP)hKYfUuwoN|AMJ{nemN(?(QNC(;VdIwgm3r zX86Bn_fD~WbKk7H*LBC-Kl78}jjAPm{h9lM+PDrRrfv=M@RHi3?RnBm!* zvHN5S(=x;VJrCJ9x>Rq-1m>o=yjBX8+$S;fdCZKzw%cZCz3b|h+7Z2MgQiinrh|4( z+@iCQGnuY2^?f+_*2C)mE{5w42R2PvWOPriSmfJAPfz1-n890- zwyD@JsM0Ww(z#W-E=5>@uSkMp&dDRYA5M4R+^ROip^xj5!PZSl3yV_C*LidAUASr8 zsY53WZ-3nOOkmE6hwC5RS##!<&HV`;_g+6Tnts}C(=xrgrHr9=>yHRI?7JngL3r=K zR=;C{MPHsx@QzYnlgWN2HE{3!qPDF*PtT=pOpE0zYp?Pyn|CQ`bMT+SosI>!QVqN! zoxet9Wk=lAx_o9@xPINgw>kfw|MXw~==u8dYW?c=K58HJ4ZDT=BW23pJ+Spsubk_Y z+`Y))+l}AWeoIBQ?ESdru6$Y%I?edr+M`jkf)*UgGoEs3y-8zS?)%SW6`~At3XLzl zRDSw7F-3gqDP8>najEaN#)7lN47g?*pXSQ4ZhqMzb;V=f`0guwxb#qvk zPGr9>*l8}f+$dapQ`2*^qirQ|ya@tV)FyISGzqhQd)AupD_tTysXs}e?5Ej`2jSi` zt8`|Botw3StKoryg~^oWZEqMVBUOuxmim0yU-VH{T=YWIb;G@Jigq4s6ODiCJzdED zMQBk`z++B_*UQw@G@riOTk;~Hj4N!xkI(rRIhCu<8aVLm*s>$)+@#mr?&_^$ye_iP zP;TyBzWU{n{M>(beVA+|KGl7VWL?0!ZM z>vK1Ii8Wh)E&sN}U|o)0$unj<{w*9E&D}qrcy2M@cR2^^)y#cv=M-iwkN;5e%It6K z>}g3J>E*L#owt(u^ziRq?fai^yVyPrN?SJj^RLgh+4oLb9(;c3%PZLhR=G_(6Tjbk z>)c*`Lh7qQz$OD<>&aGvs_%^Xe18-kzdG+>ug0fcE=R9F+WX~g>Eg9N8f@oX$&}*Z zDzG|kVk_70xb1>@$TFGk#@rumr|Z~UOH8LQXFma+l@xy>njuPsjg|x5TE__`<&Uv&n4UJ_Uz0(y{K9+yTn{! z!ew#pW4-O$AJ?=`I#+8YuC!iuy4FLb*=FK_)xtZ>lpOp_icHe74FgNer@W4zF~RIz z+e;U@hNgGj?*oz=_em{UtoX^wzp&Wqp6#bwPjdHl8tVRC+hw-rW4Kq__0FYuR|(GEc8@wceYZzguS6Wg48&x*4zdY+li zlINx8q?Y98=@nG=h6HBcHV~*Y|6wm98TnYx`;w#lvn{RbB%>2cTE)H@v<1G|teoZT zG->jz2mkj?o@(K{{op47otL}c@B963Nz7?3E)mbT?kh!_4dGr{+{+U;{5A?J4s3Ch zNSRR{;rv=?t%&k6ZsDVe3|}s1Wa}n~ur(h{uws?C>r$W`y0~)VrVR<%^A3Iu+AO-7 zr)I|4G~pfYv4zPoaoUQiA0)DxlUJl1D~^)T@lH_UW6r+N83#lKDgAmOkU2lz<8&~~G7+O(8+q{q9rGPz&a%kG7k`UkPRp=u;N7kr8GRsq z=|zbNw|<5e-Qir~px)dv`5B*YrJ}Cn`UZ^^Zh4xnXLX}LO}foiv?yT_V`#Q2ub)i+ z^QxGMw`P6H44-{;kKSpvh+isCmK|a0>=RfP7CSwKkNYf_(WixmV%o-S(G&fSg)Cma zIBJvC(sPx`W3J{*K-BqtMpc{j-O2Weg>R0pnjI(dYhP{dXt`{d_VVg{?TJ^s@()ty9D3*oS0hr#1a~v%GkjoGB9ngC#2igEEfRXIWxSX=;2%eohMbc>cA) zzWtXC1opb0s+V{x7quX3`_vt4#FljFy;>Nhb>z5V(Iijf2{*3Y$n5-f-q`Pw)5KFs z8!aurRp;OP(Yv1Up5$$#w_g0(TbIjB(_9^Nl~2svyjwG8Vs=qq4_m&1@CO#DcHtGi zey-M?i?bQpLs`9^Pni7KC-bpjjVIq6%|DKYO>4^6Y&kBYBfV0&yWz!)nS~oaNKMf=ZMksvq2>0f{Xuh2O%-a|-NgL!l8M}h_S6zS9_FjtlvZl&NpOndNMjDr zathO2<@hyjiRY)FrHbo=R-M=$(9v{B_eR^=LJQFt_P1|jco(fJAcR@gZITJ$OZW$;30k@#t|&woGp>u_4>f5XVy*f#Ci`p?!+{#qu@=3=nq zBWDD|q;sp(+;@2Q7S^RjXF8tu`NeB&FI<1l*E{=uTw9vk>6XeTGxK%Trr0;iFY%my z;?l}9FI1V53tzslNLlVWNvm9>OL=WpNtow6SsA&9*ZuMz=d9lTBt?IMtyh}SlY;A8 z`Lov)1y22#WyD_{YC2=evQrZuhSls`*Pf`}C->WPy3Kv*X;+G8D&8$__xz^nq&ds^ zrp2V|7bf@JU;X+1{rM}Tk6-jhl+Mx|leF*WDR>@dVql16#op&Z-KmsZP*5A)KF zesztKu@s}qcIF+X+e%kO3Ew$+e^o=jw)*u=A3xOD$nhuktqZ)Ty||I*iOd|Q4>O#S zxk5i3Opa~7a`flT4ngjxCs&3lutaI|-*i;A zvnmzWFU@LD+~MZxBPeom>MGH#0Y)uXbZk$0tbK0A-e^<`^1tt+`Iz1i?xX9?}v^PHUO8nWA|MFX!kGea_?snQx`mfY)!MQ!2A}dmx?|IeT;^Un6pyKl4c`;vk zK8OS}K6|@naw+G=Njlm+Cw3}Ndc3z}s`$&z2iS9N?moo7BX`U4j!z=?j}|3lzX=j* zPu+C-Y3{U*W$nCKLOVHUu{HDmRta?y|C#*fb5>GVQ&e|5@1C8Fi=}zH-|Kp^HP`-Y zv|U$eUFxSZLCi*D*CVH8{W~L!gzigEFH+yFU((|ukAs;K@_O6%&McJOx+>Nv<`d8K0_K`0oGJCTvHSUU&w1l35$56f{QSzb zmXhj8JjqAbFI-=_U~>7(cT4^~$eguY>2yU?&xR-KzPlvlzG9ji;n^>|?r8h0Nzb2t zwEno|?V(8;cD6;|A6-fopCeH8=BkTWYezlT-R#pA5}xOaN(!GZFq@@XzI|@%?YCkT zA@L<8)4t}OxqI{LyPr3aZoiV~I^@G|CQH(zTqQ&_!g z$`17t?6SOS=jPO!Ja641vWclJp?8vntFq^sRLzyGa}-;$7Uub^)$Nn zW0}flW^c-IT+;7lKYfQ|+hdN~SGJn5ShZIxo8>&&w6$fb?4f2acjs#o4T{L*MH`pEc$o+eYyS5>p@FXCoA4rvvr%vy6Che z$71F$JCbtugpsqc)~l*#i>9u)aILBK+r-`UTR#^5vj%H}y$?wDU_QAT}d*^m1 z^$7VHt7az_T21wuB(n6+^sg?3`=1BO@R_>FI`^7+1oGU!b7+ZksqPWIm?Nd?{U2^@ zZ@2j|l{<3N^0j#j1pHUr6I{a9`r4wfjkW48|1uGUmaQ2YR;n`b^FQ$REKARV zG&ld^5bbZ)x-F6we+y3-v}$oaytv3$ZpP8$1U+p{ zoH3HP=_z+;y4LzhM;@z$7yj9HdcNMxKd+7%hTmiD%Vqz*B=wtUz{J$RwjgOX1!n(ZrV{TV4`=l5vhbDzyK6PLfb^S&eDpT>c? z%@ux}FP|7p4z&9s(zYSPdAmjZ`&2LX^vA+$r>CFvEN%X~%;NjYRTdBazSHEqT-3OK zUd?^}?rXMw(>(b1eE7DtzI8{)-`f6s=kmY)g570TuiYrzqriTQIq&kpAEDEvCwb&=HJ$f&fE+PPxP=~B$=O-m6}{qte0F+a5pMC z|Mm&dI{pd&4Lk#zdr~dmE|!u0aLX&~#W6FT+%7YY4nxaHHv&{nOWu0K_Vc}My518W z{Y{g0yeQ+%@tK^yuXz8NGjj66k79p3Q98X^DQ+$6&L!UqUCzDd+Ol93S8$Brp;dQYfzKT`d3FmjT>EVuLXWto#iiUW_7FHLY+lk8WqO@x0- z0?WK`R$ta`kGPZr9C9kI5ug2y1>1Wr*racHz@_iU$y%e(B`H7IReJNWDo@Kle<#@- zNt!#gX+v(D!8y;c2^Evo4KFhtauQ)?VV|jL`aw0(=`k-O#|1;N1B-fC_jXT?2ua}- zFj?ynCsujvrbMC0wItq4(+;e6xXThf%`-?)s?Kk7d&^ph1B|TtpKY{RPELEWX@R!E zlRb}`a({H3xl~}oBr7WOLTGB@oOM$Y0?E3WU!k_GRvoF1@;x{v-D>p)G z1;hPo5B- z@ql{E>;I>MJ{SgSWX_l(sGR?9Q&0EfJxp6KCm$}D`#inbMNrtpukW%>>Z}hxH&4lv zIIp=QdeS8QC6$Y(P1N^bFFPe{pj*kT$5gJD@YU(Hh-LL= zi_i1znFW~aStSx)9~7^c;p1?|>6RYHW+Tymok~ohd&Rp?wzMgpX8pcx-+H?Yfj>J} zE^`$;GjoRXjOE%1)_28cLJ8NnPM&m`DatwL z&5z7qd1az8G4ZuC?ww2j@aWZ_za@3WeUg`z_Rfj>lT^9ptycT_6eTZ@mv+ZXZSK0b zPLGw>kUTTR%v8-!{?N=bEBjJ(FU{L?<>n6O2YcU6cF3>H`mFGbKa!oXj{jKaBLQhf z-BruY0-OIhw`C>N@jrXCsm6ZmN|9ImGd&&ul>3(${Nroe67?q^48FbnwmRV1 zWmkh}pZnFD`VMoLDrKFT;ZtztLrpHj)zxe%W!7`1ndYlBS2l|tGJfpv&bqnj>#ur4 zRgd>gmJEydDx-ZXo9DI| ze!LpszfQK>L{FwG;c$v&bE37jU0u;3wzSWTIo5yf85%avymW;3_(w|~r&C9zXXu@? zarx-ptN!Kug&P{Id(J1^exh;8ML>D_v>Ihq`9-o5lFmx+X3F2x@}af&OlC5-ZnpAS zy_HXMUMpr9-}>C$(cQ~*666H73n`7;Kmx&y{A|=`D<)-^s$jqzy#rwu%`mrm&rY7g; zvQKK<`gFbX5`#5QUQ{-o?lua!%$URA`E5dz=Bp~b?~PBEB^=P`+PKx%!_Q1rJS*s^ z<v|XWjnozF6`J!;&fDvZg!wlA$cmC^o$ z()yeGngi49em~#xvdUwnaJ|)o}E$kKT&xG+i4hb=}ENJRW4md3_XF zmr&u5#y6qIPhovSxy=7{Uk@{D{75ro|zHlc^ThS$S| zH8fOc|2@OfK8a?BiYwE@o-~Ff8wvCI9_h=Nl%mLG*Vgn{rO&KF;=tt8kA3y$pC7C# zwBB9y+){4Z-P;WssUa>+2lmJ5F8h4+%crBVv?LW>+Gz&k88#2 z8*cs#6#dQpPBq}9uTSuuyPvKdlwDOUbaGYErkK*Oa<-3Z>r@@GS+*zbVir9V5}~1a zCh6y~$SmI#Vh(XBw^wnV4bCr^!1_I_z<6IC6N}Vqi90OwBUAq!n73%h$S3HVbZyUSKnpJ2dr%{(|c#N zV7ZH6rTzZ`#?vp?PRuj%M_gH3=h$bC+DJ@qc(TFh)_PG&8$9P58PL_^ZQ`MJO_3ZujqOHpve3m`VI<8zA^R+u=cg^-`(HpKMbIDmvd)2EH zzHlx7im8sl?76uH#ojkIO>SLz?cg)MQ@ggyzW&0H@HfM0P4TCFSKZ%7+fO+aLLpb!FjZCYE2PmZl$1I{1E%*@TR_(ahOjlc%!@J@{zN%w70> zYU2^<9flhm_I*C&uxPv6`dYbx+8XAs@A67sx?kt#r%CG{3fAoFw|QQ9?$U~B&ox;Wa#aOzj}R8sQqOH!JVv~Ivo<8Y3|FzBap8YTRsg*n4MZHx!^(Y!Q?4($+!UHL!*JK!rF$2>xBc~H(=U!M^V$0D?6SF?zl-ti^&P*M zrB>MdIB%Z!X_lG#PWw;wdH;~^2nFqicldaDC941fgWF2%L-qxg@tJugsYPjt$*JH5 zcx-O|Z8xERaSHz%FEBDb&6C~#^sFcEmq}YVCuBFN{4LO6Y7*1z4(}52(Ap^dWdHqr zflDmBi_%)N68{C1V?LTe6g`>w0?|Ng$ad))ut@BejGf8UkAf4W*c zf9{u0^$(Xk*ub5?%SY{M#iWeW`YZpC_)myxyL+E^QEbF5`F)JyfSQFe^^Odp&XOo9nW*;zpi|DYRW9$LaT+d4|s`{B=&Zk+Vv+p#3xN}`le6D z9}n9qmrSdCq53d9^6{Qu@xnV=LT_yk+qvvw%>FW`wRHl1e^c+Qxpa$wPxxddTZeP#3sd$3;=S7QcPu1ToUo~yrtrc3oi=W8$+F9FA zcT0No|8MX2>RBzSC7C|kd@L^Lc&&?R?U`@V`)ERWW4G%6V%{j;NgMq$4rN;v@as;U ztF0dv+q&?x2BS&M!go8PR@yDRcP`b2_1zX*yKMDiUxj`97H4MMSkAGR%cAh$srV($ zk_klyuMg%Q3;gWh%@FJRh}FA!vy_$8>}9KXSm$nhv9pAI-@AylY^J{tO=bD`ew$;$ zjSVS${=#!wEaPkR`*tk(8Nc=37Jy5ApJU*R8tQ+03tfSyjaz}W z%ini(q`0(LVuUC6iY}0yRw8`n0Yf#ef=cVs` z0s>7Rto{1QS7u9?TlxQI*X~~mXee2A)~!dXaMH%STT>?QSi3Czdexql7w_>(MX|5{ z_rf#b_ImX&&ebNX4(t3kDwnSPa#8DM{`2Nuo$HGe>3^iAXhcsw zp#89fgZ=KhHVfZ%+tw&~OrKu3Vlzip_Jk?AVjp=key2G-kvISPxXr`x;{x`R;x;z- zryjV%aB|0;q7^bc8XA_8EV~#@{+C_i|8L}*eAE2r9>?ltpN!gt{@>!x96A}VeY9g@ z^|VMg!}Xm#Nei3Bj(V9LRd40<61knJ;A-gD>R>lhU&By!RZ3-yU&9Ie%2yHPj(QiK zG=6v8dTYg@)qmgoDT$E|?2_Ei@WH80azbUDPTKjrJvM8e8E&~5Rm-27Im35>@b~Xx zx=XwYFMVwB?MU-}-hD#A)oibWw93lFR?j0Aa^X{*WIaN%>*dY=sVT48vwq9Dr%OWb z`y2G_XKY^ZiQJDNPfexS+Yan`8n))M|Hri0_Q`jDNz6HY|IG0P zjMm>b?(&rWDRFGt+}|^9S}p4L^_|YNqi)NZzB7_hTW|I)$o^HBtikBKf3s5H!*y59 zGuWM^eIB|Bd%Bw@MMb6DzILR{?8ePK7F)K=o~D^|^LozTHM1q>Mqe_RA-QT_a$4h# z6-q6g|Jdvf9}V22=J)r|=3b{jN$EDPiJ=Nvrb|3RUcJ%#o-6X{)~9t3zS+cQD_GTA zuUn-#r}<#Q)yE91>wSDCR63uY6t#6i*c#_rO*Lko>>T%b=HIhdXGSNStadTBci)yO zT=q8T_tyFUm0Be7Hb$;~|L)wvqPhN|0!tdco>{fof4cZyne%J*woh1Y@^0cDG1FJ& zr;l_>-xYpYx@6{8mq$Fdof;)4Di(GwD^Yf0eY>L@2IaA+FAeMZ zVsEs8$z^5N6_zVI9wrufAN*N)^Zt*UQ`O6KDpoz%d70har zbu8F(Yw`CW?qd(9%FQ<1eZ}dc)Vs;sW^%0WGV9b<{JCtBui244Q|{2jX*V_>(|+73 zJWJ26_#ws(=9C-2JdS1)PSF1nO-IWSUV_V0pPK|jg$olDLxIc)aEYweDg zjC0a%dmpzFyYqCBu3SJ<%%n>$9nm_*GF|~qF$WS4^+u;{@_n=5$-}g328xO2b(mE9 z&9+bE)U3`|*Qm7VdFtb_tNB{)UyQQc&V7%{Di*}wQcO7!Sfeq;pz2Mb@e_@Gwr>nRnQv}WbpIF|#qxX8 z+1!*9fq%;0vZ%fY+;h9AP3GwLvsD32az}svOgIr(^WTzD^+lk}aiPP#k0!qL(OBOp zdz9BIA^XA>qdOXXmw5g*^tC>8EA+Oxp#N6D=#GY+gqMWvw;hssBKMWbB!140JY2B& zho5d!?agOqMt3yoPM0+az0tUrYMhD6@~w#;I4O?8CWkH{RJkk&Zq zTqN6)g@3*)8hl%LGNRDoj8D$>q<~A7=8g{<{@XFx*knC*lo6OLwOfsON{L^#z{`jG z`x#yPcWVl;WC6cT1}@3+ui1d`kLJPQ4C63X6Lw=cUefN zsrA3qRrYuDNlU9MO8wm-8!28{?EA8lqg=`Rr5D4yZL@Al-RKGVT_F6cR64U?sb$-= z8HK_>B6cS>+%#z1Ju@w-x$OIz*;8LxKfC7mtp2Np_1p00{RYtn+Ap_F49Ps~8obh9 zOX=SFb=k_U;SxIRHH&r#xp(TXsmnHxcW?Rf*}(5_-|o#(i`Aqy{*JPr@vM2u>iNFT zH=5?QcI&=j{jabjC}7FyCG)3DOA{#FI8ov24cj9tuQ+!xE{?sXxM7osB%@n)ZoZWB z@65%1a_(&fM_x`VotV4kOF&V3kk!)Ev)68H%Sn}Am-^c5QW1N`Yk{>EG0S(IV_D~K zy3z5p?5@a#Px*E}^o*7+Um?#OR3D`yUL$efrrvqir@CINVp*m~83@MQ(K+<5-F<@P zpCd?5ANnLUeV5h*%;|cy zbE(hnKA+bIN|LY7_Ti5We%8M3rLfEOg1Q5@lx{cdi<>X0c+1oK3(vPpNfNocb2-d! z9B|z*Q7~%L^}{^6QUCjLD3P-fJ!XAI{uX+F&IX^ZNE9M%5F#i+o#n zwz`&BOj*FP)AdTr?1kGp@`SB59PiC~=m1F?ZiZZ0EVHqwD{Vo&T5ltnL#$rhX4MaV<};3129?=l&t5 zgOk^*A6OhH&wOrLhRv&HqsUEsC)RQPe(<6yW`XRQvodSg?;5<@%63Kgy>Ld$PTz9- z6|L*n-LCGrx_NbO+}@?RVvKE7$?Areq}DSW+_CM2)l{+dxi9~(&%d|Nh)?Nj-uJna zKE|C|VgGRU%hgNXe&2M{DDd?LlLyxV1t#m<_&vFz^Y;3QdzRicR0zvc4q}M0=4Aft zv8Qg^ZNFsZljWyRp1S*B+nq38>z@Li^)f4X12bbH-pKGLppj%A%FDr_wUxWE@;`{>w4?Yit3Y} zWQ}B|2$;?B(2`RQ%fFv#=fIhGyCdZVXOm)~gU{r-?%mvP z3QkdJVeeWTjkWymxjC`V-0JzUWYX43xn@R=+4uN9dAk17eb}a#oqjU&aPPNcG7^nt zZ1ZM5O6gzQ^0#O1UH<6b?bfL_Z&KdAsJL=B_Fkc%17~4y&dE#3M;3hQU(7W{VEeXd zPi!40sPoN!Zt?rPg2uu;UtQ1IF4a((vMJBr$Zp+mB5T`PAKi~7r;|iM2-PPFF`L}m$`X9I8Kl5zXT}7|BBSq#)lsU zD5+apw?w2f7m1ynpImR`ds6-R!S5$tYLqQIr=$3L_wL=dpUgUDZ14F;LnYHCMnP_p zt5bW5Smi&7eJUm#9l}-X(a{k6I7&@_xt&9*33KNHzTP3%wrCg zgY0e((>@*6_!{dq=jR-&!b3lQDi$`_3;Z;>saCFbzUO+|Xf$l*Tca5V)6W@j@J2B%Jv^FryH?}`Tg*D)?Fc| zS|a_kAg(;vVK+mi;Wyo-k6i_9gpdCfbn9oF8<4;*ax%%T|Irkeey*}~ zbBc$aQ+YK$}IN#^?-}`P!wblIjS1v9;UmWly z=+un9OdsdzMn+5*0$qbIq&wvPdUC0f>s=DBmgJ7W9}dZ1R!Vt3NalWE8TF&l{juAR z!x~F^Ipme@Zx^u;Ms~-)=>xilG*rf=$Vzy=QTyrnNn3{D=gNzF>saq|_GFdVuA6(< zxvhzLtGl05f0s&EwydJ_5{C32NA_M-Oiq7xxPoCn`~QZ*=ZTL$DwSNcEy%IZESx)` zN5e79pyPNU%i@3!JL~o_^Mv>Oe{Z1DtdT0%pce9wi81}%l6N9Ej$TYMV%>SIS$;XU zy2J#@xxE=WKTevZ$o&*(PwLUNusb{N(}@FjXQsTHvmrnwLf1)tmq~L1Qz6TvGt3bj z*4sTQ#Fq(p7D~9QEbHHRzDe=yf=9aMOs`$}B`ricyU;D!1bss4m0j`@ezJbh;-A`!f+p6j%LThLE@%dX<)s{SG)QZ^cS2`x;;dPBCY*2U^=zFe zzg%EbqukQe+N5>yS(9fg2KE*=>#piCQZb+XWX79U$9BFhUjowGUi-vLZ+Y#YT)gGA>$jH)sec>m z*_YNHl0IVj;`&y_q6@p!4R15@s=vH4E%@9iC0;X=q#O!JmW_5Q(&^GRPsO<1joV9Oe8Lq&=eevn zs^RVJs-&x-0u4Qg2cjIGp_53zuX;cKI?3vYP{?{r5A~3=3aW-QOC?K zkp1BDYwq9YKhM71z1n-r<$Le$>ABBwc=p6k*Wcp!`8)104%~0vt}kz2a-?|H*NHm~ zm`?w7dRTL>-8lBp&p-2REiV67oumIdfp2=^zf11tC#P2ZyTtza$Pu1*zodC>>(}i3 zv+m)EGrXeWdC&IAx=%`2$FNpD*mKvcK%N?(M#mQKde>`LJeQds+Vql3diCe4MmJA{ zpZ1EkI6rHhzW?Mo6_ZxnufOp8xW>0h>$W|Nv`(J2(MY6?e}+kmTx;0G=%vPUZgBBm z4B=P*x=UE;OW2!q4-1`!c}wJd#Actdh*rON;#hQZ5L-vs&S0K(6BI96Y`vG0@}qNm z$4_PD4=Y$_zq^;Ck-YBSVs(*sv*LJP-ni0felumZ_JpS@r(~tWmj3v?qPem4hGKfk ztZO~Yp0XZSzusVO_`1N)}bIoa%qZ^Z)g48vwPjz!6gsS#0 zsF|h99Q>|f!MqehuRAy9FTeVcl})Yom4wfdE+a$dgXGcxH&GJ*u3D;~C5tm!&RM0!$aB}RD9>KV8!9KO=oV;=wi~5w`X3p4g%;;tE zBDNiiZJs>3zIJj+p0(#Qg(tizf1kXK4k{~tt@1g@ZTfNhi~}KkQ7bYtH4lb#E_lj4 zH75J;9R2QEuec>kbbfqwT~~J|wDum8-qUy~pEENPFW&#es{VZwTOgaw>W=|YLI&2o zy1w56PGyM5A56PZ^->{P^p4Nbphrb3rV293+%KK>Vuyd+ti&fyx1KKlzQbXOYsQL` z8}t>vUDNRj*(wokGz z=lJJqk7qn&y8lh_f0!NT1O=ld8y~OBJirkX%FN&krisK3Fng+XEZ@hCU37=mS&OG!$1I|{AP3(uoe>YCDiO$gf7|!eTDMv2B-BU#8($uC2Hm}vROim@sd4k?do@Xf$HpkleSLNT%&y>e$zLj)>78r+}DzJtyt$!fA-cIg|*su{;yY^sJ8$7 zB@d%ttUp)it=ioD$7;ddPgivK)>+1fJ}GJ4@hrtq{IckSUBWr8eViXzg)h}i7K^*& z@A{-Y|D3+ReVy(0{d3~y-Jesp^}OGDfBU$ay*qxNmile-f$d4Xh0`|Mr5s&?vR+Dm z4u(H^<9aTC|Hj!*X6y+yRne1Qnd|cXa>c=I(|Z?bC>V%3f3p@}KJ^VJZ{`~oRqG!` zN|WkcV(;5N&p#s&x-Rddlf3?>@Yod=b?$FAoRZ}I@pZoCjjY~>eEcb){+(@kZklCl zt_XLT|K{DfO;Jp`Y?k2Z+M-E9cg{5a{2vg%lB2nQuENCkI`J*<_tmB5MeMb%{M(gl zRhY~*{jH?$@`>ro&uJ{!X5aRaVezxP&$@}>McTiUyJHoP|ExPTU(2ZOj`~ce=QcBX zZKS6qo@+VwAlOGJ-|htCBYmz3(I017+OOEl@%K0DzNlID;yd<*{M@r^azSq0c~e)B z>F%|nM>P}JZhTeyEjl%0fr+_tQ_<@c7xH8*Cb#^l<@vkm{W|-4+rLHG{|kRT-&tE+ z`0e=3tJ_~+p8Z+5cJgd7|B}a<7sIOVdwbgK*|FzeRaMzNE4i*4I!$xLB&Jv9UyD^2 zd{|o$A{DavceJ{})sU7OfBFtCx#gL7W7A0%hKs*jFEa%$ZEWFMzb^mwu`0vOYp*}A zT%x{o;l7#qle5wlr)^rK!#U@4)QPRJr_+k2Ufm=a|8Yys6kXe>ZOM}Lr_F30=W%cF zR`zg<-qvxe>{;jb3yVYBJuh{H-S=C+USDtjmcFneanI=mp<;Y#QzPT+mdATYZRu5A z)Sa7j()`{N>DQG^m926CvzB+LrkyN*arJWA@2Xi7v!ffUmL{~7-<|jW^Y5Rj?I#Ux zCvDXF@AYo=AMO30yZ?HB+t}NDx6ACW?V2+tQ}x2!da5@{O**wUn)l>Sy;W^TYTARH zleR@JXMMp`d!MoJ=il4MKhKVzDLsw1?d$XUwd~CA6K5|hI2rXtp2KzW6!kdQU8*m` zCRTV(3RPL>v$ku=X`xj?$2PBse80+Qozl`>>Pr}J*SvSr-MH)cB00Bxs*9$X-QN@7 z9W~Q++Kok)nU%*PmQ-u`igcIop8Vl`r%fwsh5SdYEz=CDvm@`%Y)kgq!#|~@w)yk% z_w((`InFIUTCwNQ0~@Ju*5`lD>GPf2)1KS(+5OrhtG+u)8QVT|-eFiT`|xm@4%^XJ zLAr-ro0h9RI?2QzkPxe-Be2NqRO^OijsG8CJf5DlG z<*GW@?VqB!|HyVVS4A=NqQ#ys{&$D2Sll(c&?)RzhssKJ#&p4D|9WnToPQP}{rUM} zXUX|I?Q$}QI*#uuSa`^PPD_m-^Klu)He zwYAZwmM_k|&3XEy#Nk7(fx0F~elE+rqPObIhUu@|cbMu5$BP7PXqRgVdRWxH=!cYb zeVV2*%ck@=Exz}MTvnWGeza;zeps$^p1`4>A9JoG`5ez!DLp~<>7lfLk$qFU;vQ!1XPxJ=e^kNJr_G? z{EG19OZz%y{@QB}a}AcgKNZ?1!Irf>A}$0{{8r+?wT9#{q*hU z*6rP8v;FzKWpoB z*R3Yz+KGy91m86-n*VK^u*U?a_bb{e_nEeDB@7l3h#r)iye=_VAhX^Nfta zr%T>bLr(Z~i;H&Z|IEtYyrnYn>p4$pmsYmm@@39xdU3Ur1LF1^c+~Y^vw5)5?5*sT zFD^u@Csa1@%$w3xVA)pjaOI?a%SR0JwQecz$v&HNF|XQ1y{;ow@RPSd_s1p%6O|%M z%YdbiSq`c^{9Uug z!I|}j+m!gz_%&`$ULF%=_G{DKZ__-2PoB4tc&=!$`1s^rR1(7E+vtf)(f(5H717b2@3 zE?M(P=z8N(ZN0lXH=1Jui#2by?L00eA~vy7eC;1ky>E8*`!_tPXo@Q`jaKCF6^};GGDz_L{Eiisp~|Y5?xbtv3J+1sY`P-1#dmObR+njYE#dwDb{anIB(v` z)D*tC<&Bc{q(xqAo6gF9)i`}l?OM0V`o9%9y?m})UBcHan!y;-{`j04U*EL`mhZ>@ zMd(c5A=10f;G4=$(<4h%UH0ZAra!-Wb4$R4IH&cWZ(RJjrDT>OaZ+mo8sgLj7LQ#uy(|OrfmPa$HoZFV}J6NnhqqKit>ovs&w-G+V)Iw&bN6i=Mp>zj#RJ{4$3NcIAf; z?<|)+q%E;OmVJGg{MyGAta5jkNV8tr)tT;NwQI@k=&CEGmRG%&luqW=*;N%&cB!T{ zIq2an{%cZVLTaz;7_M*FU=aD8dB>;LwsSk=ca-YbaP9f+7?b>NedmkzqNg*bpWCr~ z>UGw2{%*^z0Gy}{5DK7klNBa^Gls* z(#zWD+w0RVW!%1f(ksV0GyC>QuPW=ns^3X(+ytIG{-_jJ$=EZMeKp%AUhZ-e&-e45 zYDyKY_^czh>tw=f-nDN&`1)3J|K~~*x%5WgWoA7$|96JR`Ty*1U!C-F(TDcGEqam4 z`{bQUUjKS^IgYJV@X`FT<#N?`J#ExW`&2B~y({nwKUa3Oq#?(x+WAMm{C{hUNeMsY zyWBUn-}fe!S#+)&2#K5g02cYY%91kVMTWA1()C6@8xuMpZ+gC+mUBQ>hC>2 z*c6%XT&6AcO?uEYDOFztiQ>lMZH%k2fo_UKJn&UL0w&?vlToubxp^)00 zmcjh>jlylOIq@R3=Ids$i>R*utF->ltYcaG`>r}lu4xvE`*~C=ERElhTkVpXFW)q? zht;pySVi|(>aAL^ZsnW1vmdMOeQm>VR!KQ_&x_i*hwfc@edEd%A=&Nnx~;kbvByu_ zOIf73?~lpLKODZReXW!1I=!kl;w4<~Hr;dBs8ua<{nlc;#EN)R=JIQc4IceoCw$(E z=f^%BoBjG*AN;o3J9|$SGo!twX9U-^rRM)Niy!Qo8Y8$Mbqd4z*xXMQ3wFG(kGdBk z!IwrQVi$};l$Y*2wU}o@%nS^!>0I6z7A>T*vor9?{{Bs$FFsrR;+c2Oq^kZJ zk(qJ)ZC>GSXN=jmzwuNl5SE^{@z9~^b^nVwgiTsEglTa4F)n|=t)UyYC3>%%h?bzH zq|P%-gP9IWYmAljWSdU6u&xf;p1{_4?|GYNJ7>n?j`p}37v96$H9elPxFt#jUjtSNkpnYS@>KQs!pI0{8E|M+8xm~Y+ref{qjzx;9i zaDj`T!t@Chhq@<)WIL#wKh5$`E9}&+dFwQaZ#pMW*_gQO>(@k{^lNKl-%d+mjXLYG z@fPR#4Vz68KD>FnVx4^Xc?M` zFMi~C6!Y=;=CaqJp4%5c^!K0Z?AG*5;^Cyl-!@E~ZgXS8m-X|ec&t-=yDfT(z=g*? zSNE*h|93Lm-P3ocJBCYfYM$0zcXsu&<>xdWcm*c|Hesr5JQXI&D$8BzVZv)JSbtczJ|I zaBjCv81KRpn;euYo>>1CoVNVIvKPxtvWw&{e4ph0SluLZotSd`c~+gnuE%07)Hbg< zSABb9{emiurNXTH+BJC&|95^nWs=%#os|iNeFir6?YZmb+OGQ=TDa_sdFs>kd-fL; zR7A$6T~SI(^HcH`zj~HG?vB^{w%YHz4fyl!F}|7D!TTvMN4Ui2$=Mr+1UFf+N9CS~ zJtE30spq-B@J~C>e242v`Afw#S<)wG-8kZUnCEBmg57s}|GWD8m8OQh%=MOviW1l& zBIU8*wAA94d*(#nn1Ax|tbG3~wlQn3PjUHD&s!KOF14{G)BUkz#F22Z{Y<-$Z@cKm zot30BCvjOR*T@n)4Rhf_|)y&Soz%GV4fdx_Tm6)5BnUlISB0B%Jn^@gC#{cciM-QC3 z(a{zAru)%~uWP0C@7&n%M8s7~(o!T)pQVs$8?kH6+8L_VY89hU#Tp>rAIJ^|Y{b#yc;)nXQp> z%DCpD&UrtoqQt)I;j4lhize zj#HCdy`l?a99k|-Y%`WUP!pV@oF$N1BY%L~oI6r7A>Qlg7PgfQ;;H9m8uR}=!Ldb( zciWK_qLXYMu`XaKnIL^7piuaz&GR%?Nw1D0T&KLI25n|II$;U7=2p&k;VXO{Vm{hz z72>_j_D@(;^8C!@bG!ql7B~Bu{@MQM%#+oee*{Ip1?x}UntL*&$BWTcOZ%~f+pmA$ zfBxRh|L{+h8UK0tf40@;QP+w*u82CL`1= zjFZ|?HD9+6C#UEra2#8^YUO+vu^W~WL1(A0`Dx{}_pY$EZ1IhaX2}y*hG_rRjeXii1dCP$-)eG88@C|1mQqi*?D@gfV8PRynw2{T?Vcb;@=!t4T7 z?be2AtutP#hGn)dd2+J&oZo`qUnb0Xr~Y$e`;uh7o4ZzK9ZpiZ8FE$i;qRp%{sy&( zv|I|DvtBzXcjLOGmWTEMr#zi;^Oz?vqT@$?L&S8~&^({`OJzLrpZ_neCI&rnk%v`=}?Rh~* z8}0;yD88s2(?Tsj@N6(GsN-sy75m7f_+^oCx6*>uDhDHdlHTNSn>CkP^5;Lh&i}l) z=i!>i3Y_>}ilv$=s3-j!hxTSPpVdV6aH*(qX=e9*$lsPu_*rv#ck z?oRnC-Mg73gSCY7Uc{DH3Gw&tw{PBkyxp72_-AIAYS9AT8%MT?cQ17o?7h8a;YMxO z41dMLzDKq)d@O8iUj6ThdE13BxvjoFuAPsjT(K%?KQLv|mc-`M!crW$+|KVmv^?7u zcJfEY4Wn-s9;YT%#3$-MFj_sMRpFOWX4jSJN6xmNzI|N#NnxeUWp17gvaIJ#SeLnl zo{|3=dL^fCMgsS%yPe9vTg-cOoX?0!Ji2#j&Kv!6=O468Jea;q>uu=4TTOOLgZ>I zPH#f|Uh!7m5%m69xXXHl%R$vb*;`=}`&HM*9F(lGy=$~s{)CxrS@&A`bm`S)w-dX= z_{wgFRi8TcYoYFQvrpF&t)!yXyk$9F-2XRHR?_PI!M9Pz^*mh!u048n;m3E`6ZvmreeAYvOZ4>K{U-}{OrEz531Lq4B}{`t$am{o49;Eq`gOP~PNMPtMn^ zdc8o=XFKQRxI@=ml~dxqR+{bDcD}spK*W2Ihv%;I-pyPao|n>R)Ai=H!FJv`*LgFe zd#4qBU%v2{zNk&)mjBNJ9<(+HSJs~WetIEuO4P?+v#u3=-I7<`y^6K2xI3!+an;1A z!=c+XbN$zyjOu-P^~;yE=xayLt^HT}e@Et{{22DSDt7h!Du(U$T>oy_d_4M6D}VEW z@(uIyHrI(8|G)qB(|_mpR;S)t|5~!1yQ=E6)=%VP9D`QR(bn>xrSyl1fgz0zv&{^t zxs&sA^YwBQvwK5w^Di3+{M+O4liyu)k>-)eqq9XcZh3P{uhG5L#Skd6wD0!Jon>Oy z$rHalwp7oZUgmlzNc#7?KQ{Z0@2lo{{-!N^oyweo+>o%Ab)O}y@*fzSP1w(TKvlHz zP(zwmcKyOhF$NbZXRSJ8!@f#P)BW%q$-_@=E~%a4@wU2PrGB5IX3Oju|1GEA;wU?8 z^TSH!yZ*7i_msUi|CeGbbp70Te-n$(M6HyT7~=rrjGCW@c9Oh{H(y@Nwx#MLZ}Z_y zvG`-$Z>Ro_U-w-;{#a2TM^myxSVNCEPtT^;D}!#iWG3oORVnN|JlSf(YlVYHe;Sq~ zKC)_P?vgmamecq0R?m~t(;}Ceoi#hWV$#yQ^vGqKdOgarXKeYsSZMFNSx+a;%1zPR z*%>x(*J7paWtQTcr(emL{yn?mrh}vFYMWI{Wm9)8UhF?3Z*yp>+^r71Kn=IEjhBOD zuRk;{PI-gT)HUh}x^U7!AU#sAtn@^N$e+U~k= zTu*e`T>VWbOhc;M^y{Y?PpTKJ}e3m);GSB7Y{Dp^P)-dW`coh`>n9s!S=W?qV zTV}oOG*^73-m?GJ!6nUC&N6c-&aiL&Zc)2?@72Ef53;4dald<~5Zz#}eg1*f?W;0& zEAlrj-ZahWho@rg!KYJ28I9Ane^e5!*m+yv?6qx|8@-#KZvAgO`+ps0$cBid>327Gr5kTJ_s!4n z){V8dR1U^R1^k(REL=c%sxo8fBjK z%{g7RJ9?%4JV|TM$;ULOUZ{;+TI~1i@tK~-wa2d&2!v^zEIVYC+PC`m?(&|E%T<3z zNq;*kd^^1+c)!lFIPmxG z-@9(t@62l2n|?A`*X&!M{9V73?pstDORxC`uwUD1u;;0;L~idoM#-rw4l2!?r(E0i zWYIZ8;n|{5>ipspCgolWl;{am>)T^F;fvh&d&yI>^tsKSM=nU)lYE4uSL?g!hqG~4 zRA)#y=l*LvN&&0c|w!& z*BDnmY)iDx;XcQ?^Xavx#~go_FsDmCj&NLjh+kulk)hK{3$te{z8!OlEu7WA@rZ0- zl3>6w0o|^CQ`%fj0gr!DVAtdtCjSu0tz`UcOfm1Uyy z&Tb3N=kiwNUfTbYjlHg%)n#^=npKUn*eavLTAr&iI}+wS{ydX8!$)gj*CHjkpfjx^ z+gn7!ovpH-I9&3u&(J&JzGb?s#9Ni7N4I7tee<2wc=4v$(-zNX>(#DH@n7l8aueCT z=;Fn_xf@?R+IHj5vu}OrpWe-lKfe26+=ccjw}kCVPP%DEG5ptk@-Mh^$r5Y5KmDgS zE2hO%Ja|Ys6yTH)M31w)fg#$8gj6`l2O)-ikSSE}A#D<-q1wrtl(D{3@f z^EJ-u;sN$ul{OouGZ>bneAZnP@xplVY`@J*i!D`tr^+?*o#scF~wo?WHWKKx(inrAI@??YPlk-F3irjqBw2mVQqU?j?a_Bx{X=#Su@%X zx0~P1*ndm&{}WRl&O_TO`8aE5?*HABR2sMT%cg7htmK;P&iL>6Y5Drt)_&92trr&> zY%fEZeKy14(} zUU&B-==c4zRP49=FeCWNDW_c>Q!DIVr5*eA>{C*)LcT;=rCQ9lh;x0P_Xl`0vxqP- zFmNz{iVUwjX=zRt28IiqxH`z`$;qHvc57H}{%j9{e=;in4r?sc+QB$!+a=F0HC@TS zC&l~~y1CQa&$sp3hHX0!>!gaCPy6)Pdbfmh!KK&J59>GGyqP|)GOcWSID_!6zKSD4 zJGyox+;qEM@>cY~P5ld=#um2C8k~=8mI$Qu6jvWTWV7tRXOq;K7L5&SFLCg4Yq?C( zsnPRL%cx*`c4TMqgCM^}-Fs#F>S?dD%z<6!ZZ!FiFuF7HV?T9bu0EmD|KGtcl?>-@YUlT`UE8%<9tO)KU| z@|tAxRGllUUQqFcmg~0*cXjr;c6#-7WQZM|c*DX#G*HIbDf5J5fZk_Tkvsv_pUKRp z-UvS7lYO#9MLW+kv^2M%)^KjgLSFt|YI~bzEU>!6d8s5l>Ex`mO$w!(uUynWvi?@) zw2fWk|*Ks&cHkftVXJnykf~ajb}Qa zYSv1r=a-IYPMciEBAOnNq&;WT%+s$qE#9%_@A#b{wU+($!NmCoe_tw+KWDJ1kWX$$ zxA_O@dv!T}Q?I9Q*je(M$=`p%S_5rY$2zXiz$Ke5mhu*Vy|S)p$~UVhcInk$rsmDN zHP>j@l-0Gqs*CqNSi-ky>Q=P}W#?TL15G(!giW8PuN$!??daO(72ggpTCY3DdSmNZ zvx=WNZ@tnXp%U&iCA))5oV(m;116b)MC=^zXmB+_@zetae?ya>F`cuj2c9 zE-!h`O$TL{b$*_+H{XN21p_kCOak>kEn)B3Er z*Z7v+`nA&kpW{=(qx-u3b7mX=l)JRfprUPW&*j(mSL_wqXxqMZ?gcHs9ZM`8waxYa z`))(Io>UBZ|PW~^3>K=G_)#N*5JmqEN!MG>a8Y)*Byl1x9tw>wEy>W z&XGc)<&QIkgtIr>2j=6y{1wBkt9Qth{~b#;tE@^A~os1l@4s6_!ca zs_J*LmeI@XzN?VHnb7U`(*+7n$DLg~=QHoV{zxAql^~wVIid{f+Wm^V;&vIG&J+l0 z%A0n2>zvv-&ph|ocKl4g{UgtxnU7(y^z+Tl_W}<|Y_or7d`!5e|2XSCSFz6)9v5tv zJ;-hAImVow&^Y~P!I!$qQoUpQBK7hgs(Tz4j+9IIlJoWJpVL2UzLx&2tK4f9yMMlQ z#-{X=NfQh_)K)X!pLnKhuDxvjrq0ctdaOlvj()v)XWt9szRd5Ce znCoD1%<23Ep;P4}^tnzy zT+zk5@3g~_sQ9^cHt}=TKl>)yQnJ%R=whm&_w2V!UCIXW`+gemPj;9hT+9)Y7Mb~h zJJ@T*pC2a+*@EI{ah)ui-@3;{dvUMp%3o7sI)a7X3ctz!R;aWo=C_s;;iP|pDwSqUq0b(D-o?YOx zPin!{4`NDE(Y>YTvTJlj%|4W=^Y9`+VQ?6OZUtyAA&qXl~km zH&tNPLyr%g54szaW=n{zYLbXpwscj@7W0WL`(hXt$7sznlxzx4=Dp#mb$YoT%aEk^DnMw&)v2ykk%XSX0VQ9(PLmIQ6zpq&LYt4c62~Xs*oZa^GOJ1EY zk!|HxzSgMkpXw6U-oNdV?;y1zoxwKh*sYTX^Gb|(OR^YjqfTw@Ws4FumT{6XT77%Y zpY=A1?HNDzSS@w9u6gFk-$i$qeQI9EoE*PZq@mYScjVQi7fr~adl($kvp$vRqv|YEnI%PAoIp`%ip)tECaqeuH~Gz>f6@CZ?#^} z?zkT6H#cqZN*lW}?~A`05<8M!$<5Mh52=ZsoI7>pu~zrslK0l@9M|4$v}vw-wS{A4 zl*gmPubcP0SoD0+yu(4Rt}8a~*Olu#@^EdHOqRjqsz!mSXHS)Pb?)KwPe`d^_gT2+ zi};s!KXHXhcfAc5B@Z}1YJG6Wb#C(ue)x(+}?61 znQ>1cpZn3-2X>?iO?;ML=zI3r{em6JFH$T-n*A^6i@dYkr0lM<;`iIq+xu?kwJrYS zn93tD`wdH!|M7e^`Mdv^QR^H&U<5v37HFGV@9+;-M|qr4fPsw=4we z>{R|WZ+*%br7Gk2-Kn)?H}~F4@ANXJuUcCYBqhY0*(`fAZM(XNqx%&)5DDiG#ps$6>B_>a=IEGUbx^*3sX_mt>m^q z`_zi=$PJ!;9RZC=O-JMw^Dd21IA|cZ!&27Q|B`5NiS(ZXw=E8O1Y~lwa3ut}cO(kQ z7<92F=yfrQOI}X>@|WX@k&je|t%BvP2Q79xt3I(?vJ~zT_4KJLXgT#=vv<<0%gWq_ zT$wGQF^xMPusMIdZ)&^5;Jt$9r-^D}$EMx*t?VesJ9XnZDK!fPRU!Eo$!=ce_fv%g z_N?x-7n)JPyZ*j%{qyQS5}#)XsRZ*>&PicW=8s**^Vc#c(vC%O@r$~hF{`)t^Jfa> z`+xd-((ImWq(Z}j`uBBZ7wvnB`sVh#A98Jy|ETaddP2kz$0j+$<_zH!)^h8+d@eJ; z{dzxrd$HxWterIt^AluwLMs_wTz&QW&*_?7zjoE_-xD3X?!JGliA|B&og*nT<{g+S88I)ZZ_IC)AJqt zp<=mUy)SQ{9{-uMZnzfo|oDIlcBTF1qw%ubw9*h0!P{p^#_ z4_Vqt{{u4Zi(?wZ$36Kkv+{P4<~q6PI%T!;2@y%D?Y;*oXhjSE+2;6!pIBUjq9|-Lt6^ z<~1m$Mb1x3*`6G|uxaPMa+Ub?^~TIMcU(+LVpeLuHT|9^->R%rQ?GA4b@ztcu^StW znhr88nRe;ole4jR<&G?3@LSB`{%yg%nG5dy=Xe#_Tvd6Y>f-ATQ^PF&@NnIBvoax; ztlKVD3EjuGvgZlAS~hM=Fc91uS^C7u`nGds>C`(_HWQ})j@g`fGk3Z6)SC<2LZ-CD zP5$s^(sZWxGn#^h`ewI0e$IJZEm2V}?5I|8W~SQP#3v^U3}>Hxul2lpTHlj^-4WNG zFZp`OYWbq+do%oYDO%|U@fK@^MENVfpSfRnXU6(T`xgXOuke%nYnK`lSpItL<)n1!Wm3i>`+ZEhqI+10IPOe^9S(h1cXT}ouh3wbPD{nj8!6v=D z>(oT0a{GE^iMfr{zB|$ny`H<{W?OMW^z)qj**_ibviGXZ*!^mIZ{X#~IEOvUir<7u z`wD*CdAjo=yN>ggpzSA0?3P@(9hB4U6Z+1wZE@vU$;dm$t{&gK<9MF$gs#>lb~Ta# z-=n`oT`OMEmv!{`ye>Y`@UIKkB+siilvri`zCc?2#|Gxu3mTuh1Gi7E4X)yhJ+@$5 z^e>@#0i8P5ds>=T{&r{y_ECE9Q~IRHEB;=+g)?90Ze5?R*{sj>;q0dC=k@+IOQ|fn zdjFH2*RuNsJC?s#bbWHO{snyzIo2YjaJ~C4Zr`@rcQdBy?;q)t3>Icjn52A_^#bKD zqSqpAo#_v<*%=u2Na5_dM;}tbMqgY3H{r{_DQ}&<-pOqQ){NJ@3wwe zv-hsb-d(=Jhd(BLXJEFAT%>C@Wkpbk%>DK6c{EQ>Qcb;{*>hxJTAT6tf;bPY^e4fu za#vJevTl}l@_1q!@Tfb*{nU9?yOk3rg``|suKDp%gT|~?Ta1?e+bI%w$U;@_`O!69 zI_K`5KDTKG%c1K>oY&edkJ~eS$;1j1ucNQbUukb*Qx5&v@QJG{W*@iJx!D)prx^)O zp0L#G#N6yDyt1DZCq7y4EOc3S#kZvjn|JTF3~XAW<7E;3K4I!3)7vSRf>%69N~_;? zvVMt2aMs^RM^`@jGVxpQKF>2EpDikv2(8_@B=pCU_DjW%5&{=acO0Gl_C%%owWi{Y zS4(F8%;1j+w7e0p@`x-?LYI&8v>PY=T9vjXuVUM`|)!_^k=)XXyF{& zPR~c4NB{Ixe~L}C2;Xz9>f!CWN%#7UMQ=q<`(?(v$#K$JHvWa;{APt|xsg1xxVfe8 zZY-1ko_vz(l!+PGZfrsKbfFWZ0me`~Z8 zHIfwB6>wF_dugr_qw`azS+1Q+6nldwZ1}69C@mFy!ph+7Y^%vFUYbibo@i9=)Zc5; z;xK#ZjzV#5#h|J6v!_O|gjDwEznJXwR4MM)9dAYRNk?k`Z=dMBZC+2J;-{Ps7PpTG z_KFH-f7L@S1x_jNl_q&cYyl$Jq?mahpqyPV%UO$AgFO;rd!7{(; z;r@R~%QjERQMvj}PpRG?utrI9vBZ`ga{~+c~pFMqFsanjf>dYx1iV3d0OnzC5=f@7bG5>poi( zr@3u&7Mhh@+C4x1uJ7~j$=Pc)zEpN}h+c4Mon~zFvi6_B?yGku%l$DdlAcp)Ik(R| z|Ng5+wfXUP&gU;H-)wo{)#Oi{m9}%oO}E2 z;;XY$4XY+Q`#JkxVz4Ziua|qhsfACWVDTw)xf-LjOziBX`X{Wq&pu;%EW^`0H#_n| zqfDp5o~RV|Ch)8ll8BE*JHHXX0+r{UGvcp z-^AP6;)kOT&SP(7d26lFDZOfg*Yq2=MNI_G+9+6Um8`nH?6f+)82#}Tl}j;@Npy8=~~bE8)8g%dzppC%swixY8lJZ z6%Rb0wbxCN`24duxb^}=L80{PS4n)eeVaw2i^Q#xup+rK?kY@9NpJ&u`|x zZ1cJ!mG#E)rJ~h>suL!$bWBY-)}QKldYbj7J&*o`_aB|U`KRqMP49oa?YgI%43FfW zajUP7f3q)R<;Ck4HXdqkUMpDi#`nO_uqsZD5QA^86BzWKOJ%M8)@Bg9okMA>+6_KW zaq|+{y*XDy^lCLaj~~w0?d5tk={{>&{_eKTYj=6=;eGaTNA&9Lto6?8PWP)Vd;X_z z-sj^#KmW71|Dyl%+J6@8|4gbPU;4}~-lKjucGDxb*cGSSnKew=t)lZ@dh9;(k*{{| z&TyG*@pnZVn3K+4{Ch62YTD$!@};Tbs}j!dj7{KPZCWzbcTG$9g}&qAcZH%E#NOz& zEPW`};m3Vsx=2>(@^>vaVyA%w7K?Q(7I&7hl~}L%`dtY zv{m!w%x$_StZZ+~FN(4~eY5`D=4s7Q?ddz8Y_AAYSX~)5@4r_%&(n%OYYOYuIGCN$ zo3is{)#p40?l_J$l^fPFaL;2E+rqGVUYB={>c@(Tt-)p7hbG-;Ey~}`yZmz7XVuuX zWsEP5-MoAK+qT;UeYXnsE!i6S)wX%_?wxOQuNORWy(Fghz;b`XZ}WSTK4)9RY^^Q& z7h8DwivC=`s`UJVZ(pasK76@q(`Bn7IWK)}_cv_opGy2Tm0a%o?8Akt0xztNn6R8y zc52>ye~xv;+7sVq2R4W9zPtT{_R-5nvrQvCg?MKEV`pd!ix1m>IdVGx-oFM1Prv(j z@Opd7#;`d@`8Cg(nVSdgDLeQ*>M!G+g3FB$dA|JaVcd7T%S@tqmxkulh0k=3Jhpp>rdJwg zO}>Y8FFI&`f;ankIWIc{!+UXDeZ7*RQZtkI|LBh)c?-91+1=1kecj97%Q;D*T(K`{bGgUg$JUQk`X*cK{$7%?)c4ux^fxDe z7;lT8`2CLcrQ3PWMgIsoy$gE9>188y`FzVf;X+l%8A0(IzIg5V@$08cu-7k7FMgA+ z-!4u);xoZO?UBpLd4_r&9-6W@EM>gcE#R`O{9<>}St3wLg2P6U`NaiB&&)S-H91*t z-4Wq4m%L>1qr$O(V{*l#mT7a|WFE1*o%JETKyi+&i^#G07K%@6yc8XZ%RFnnYQzF0 z!vpkov<3XVyRo?G@wY`9->>9e+`i>*Op=g6JlE?LbuN2%Y*~{2ZA#;&zwRDP2Y0^u zHeG@}W^?%G6VLZ7^jGAM^ieoEc8dxWV^`!J9o$HUcY?z?-8}b-2Ux?pZ8|$*w-c8 zt$Y06Njcu{i8ek<9DeCeD;Lhbm?m?qu7oq=9mA%)=Qjh^y>DkdbfPS0xzIYvwVCm~ z97YmP%f4@j%Ps3&*kqHqa>KnF=jv=)<~+O|ertc`t@YP-zis)$zkh;h@!jvYckaG> z_73Zk8sqtP)1)?(PuDL0owsnx?Nws6(=XqBw4Y;Rq|SZQInzJ$znfcaKmXjb*_SFm zGb-O(D|fxSedq3oyz2S2uA`+d)H`4AR)57B z5Feq?pp~9pC@7$J>4Nw=@y`N><1AFK&6K~Z@Wk^;?A;$l_b!Wg&wks=9wKtANiOh_ ztfl3KkeST!juY!<vxS=y#Jb?l85cjYyKY?fYN8BtBg7rNy~&k*dOlU&%3)mc(ign zUVOTBI+v8if;F9PqSc;#S86B4u3W@9gS&XQ6Y~QTs~s~`4{D1U3fS>#EmHYn?<%r5 z&0qPe$+}&eZnXP#w!S!Yyg8LGE0*K%sg|Yw9nCDB6aMR)Ziw;wXL)eL&&MljWRlBv z%U1vXcRgOb{>=96EG1@Z9Hux~?@|riF}?fBS&OsZM7HRaZQOrzPtWR4>rYC(eBSma z``gto*<8inOq*?f&RTN9R)6yO({Em{JNu+K`J3r{ou7M7fJQ@~M}6BltxoUreUDGN zC$sk6{;6jx{QANlo&_J7nS35BGfA{LQulxJIh_`lIT3t6`8U2zJbah$@e`#izBsR- z#ikpV{51A>%N$zOd9OuJ?bh2FT&p}>YF9GHt^aS}ysReRPo|NIm~r?jQBSL@T%kv` zPA<0XaWfEbbao7IUaI{;jdLrzp}@4O5ypL%FJ8=Cu=v07ixUzhQ`pz84;0;aZ0_5K zuT-)(9y@g0AvZgYHD}?IZwGQ^_?R=e+n59IEK(8=xi9Bs%6uT~A4k}wNlwABi)7d3 zsEA#jv6e-~lyUywC#m+EO6qhNkNY0@c)B53cEbZJ<%839nta*!&7fe*gx}L0rylR& zy^@rcx4z%=;_gBp*VliS8Ls@7yR}42Cir5=6@yP=|4k=$-(`3pZcxN~Rk3+}JCD~1 zhvq9%bDVU`W!@gRweCn#)$A({?ray*Pejzg7edgG8Z?B9qox$oqg9U z--2&JaGh4e-2MJl>$~@gl+8WkBj@-!S8L}hE0eNNZ^IW-vJX;cPdvHIYYQ8*v7i)B zahP!iS6x=9q zA{lt>*1AQTmY%q(FP|_c{fxWs=ZSf7?~j}{n6=;^ zCuKS{dH1c1t`7aVOSjl16a@O*b-KLM``~ufn_@Fp$(%NE{T%X4;>s=0+?0U+w^E9t z@{@K}q^tBleqwrM^ZeD9oZlW%*j{i{H>q|06;a+R=I8adw0(MEXVW5RD?d?x%G5g1 zn{QL5Prc7HUGYTfj2iAf{gdXl_1tb+=Q$aDGh`Ib>9Yi_&fD;IM(V0tkzDz+Zv0b@ zYy1A|=HH_W(u6j=vX)u-_+?xqp$)a^l+Er*kmL=TI{%1H%*%28>N8keRx&WHSR$CAu~uHvf@@ zNNt?TzvinC8Qq$En!mAjw%48I*_`WmV8vT5O|H&`Gt~;8NLc;({dKGCaYeN=UTf2C z{kT{B-g4vm{hv7hp82aQw>5hH5Bru2yhrU0pK#Z#bGJBogRxccD5LV1hCg3E{Oi(m zyW8`KciBHHy9HAWM3#2!P1>TSlHL*6Q_VcJFNOVGSJ9UT`ycv>Bp=~0|KTGrW2Li8 z;VX3sR~`d#*8{C*N<{zNaxC(j{PT_I1k0$$GxqRr`O(t8fI;JHzfeP>y#MAPtFvdkPqCHpNRq~p7O$s-T7-6a=8-7Ze|zIe1#KA`E@<(EQLru~z2`pnqxdB0S< z^=`#^1;=u`3aJJ8Q=VA9`@h+{SnRRwyOTAOO_C9!S&)6?nm}#o16ROuCeyGl#9adS%3|wMRddSw-s|^YcpDqB!tnGPen+pY+gFfoKnforO(th^2 z=`rQ}FU5XTotRm&tLn-D?YQ;rVQ<3%Ckhm5U!0qFko$bs4)!D8w?DSp;qWryxT+lgc&z!}Q~hkEpmm(>qQPRU`G(W>e7b2mul;Jlq(h5N zmovY4cwchir&u3j@$eblD>#;Ld9RqyCEwe0UE!q4-mD#I&KwQ%?B9J6yz=-fe_VHc z>8|hFZLhRXyddgPmJ=eqTxroP-~Nz^ldh*8`o1?@gY`mfLrH`EQEDfM-##BPO`;apyPj+tvF&Dy-dbdr>U^=c-KsOIAjN_F?7Yu#cn z{kTgs?t4dh#zWbEobNx#yx(xhTBrTmuESFf$CR7%?-Z?1`jLHOk;s}^Sw*Mkp4STB z`9C7B(_TM3Nw>(`*J<6o&aFd8b@brXcaa4tg?`E z>&A(fU2bM_wb&xdg#p#r^AyEO772LdGy4^j3;k~<&$aZDIqbj4_7;#Z_M7N zY}>cvt)+C`b^mP!X`vdIPAYuXYdzlYp>5n5cfw97UO|n^*G@^?w?%KCXo%X}%HQVp zA!}TAO;w%y!;hiz$fCZ-{T|0JZ;Aeobonl*6ZCK8XV=3l3=BsEF;DV`6y4>SdB#TZ zx#f_xT5H2E=0OYagISdg7oFNm%H=0i%y3F?m)xeXAj{pUt0`H*+Ed1|QL}#kcdO3F z0_Mx|QcZ-)hM(58R#DQ7f(-e7loC_B@8TNC>ekN>}JFe_e) z`x006B>&*!8KwJW4_SP?Ik9wBZ(6e9?6qy&4=QJzou>Ue^^?h-%&msEBJ(Z!C(pL| z`p2YFcH6D^wEs3`?^3vq-#@qCexDs*zFYIxm=ALcn!adW{~WyO`9rHo|Eu2g-u3wK zB-7-LU)IAokH5{c6PHhJuS&Xq`-o)q|MPNR5_+Dws;#Mu+^;fUnak7H&_7En%sx2N zY})FNIs2mcc3XQTTD){?%H33_sWb=x0tJ^iVrQWmU3BHb8X|7K9h#Y`7^#VPWyZ~T;u5dsJAaA zyhNK0394UudaU%+!?SILON;C@&N7s}lgs`vBh+0dPV7K zM2hZNv0^coVaR3Az#}2iUTY@p(a3U|e$+RKP57Fs@U{O&iLs`MPt~-l-7GcI^-hH^ zNPXMI#&tcs@8niv*Nx9Nc7Kstab~@t z7}GSz2VR_+3X>Z`#der;-1*;ipmuJ9)wwh7nH$BfetBAI_~`t#6B?Cy%PbD`rfvG7 zKU?#|*EB9qlf`l3UiQ5)Q$i+e>UuP(dZW{uIQ6o#N7nhR*?&Z2J6GJ2>w&4Pb3=qT z`Y45W#kotmt}&iiJ^94cL)Qb{1VexQuxwq?sM5?I_Tc*OsF6Q-WsU=}DMpHvxI$xh~ z{nc8%^eI=u#KV2!N()c!s_6VX;i}KI#{3P7nB4;|evHvoe!b*Hz)!a4w~u^3ByU)> zTs}l)|MUmETZ-GmH|;hlR=5BEep`V)PuUKqRE@xt6Ez$gf68sqoII!Xh3$_OcbJtb z`1J%m;tQTk`!>05>t+3|*`C|YE}ZmM_;f;f>d*I%>?UWA)gxy7LHFCv&A7xnfq{Wx z3j+g#8rB(qL;)CIoLW*^pqG?b;@WG=eaJz;<+sDX!xQg`a4B`QDuhixrF7PDhe~$L zrgH7-<;(xaJ!UV^vk%6I` z33Ht;NOe+vesPIja&ht0{#gHJ1Ch4%st@f=40o?d)F?g_8gAw0l9grpO15#4Z;ayN zZnb0o^_mY(yP@+jX5RP5HtD8Y*XG}5daILp>Y?)=ubKx|=a$4L%?fzdT)cel>r30} zafl)%`)vB=_zOK zD~cV}^f@tUd;ZnR56jEyR&BM|k|ZT0e682~$-(EluP~XFPUDupB7O0x-V&`N*JnI= zGShj=k-%5Y{DH6T1*hjT$@QeCg)4fkTrzE{)l;q2UaP&hh2P|u9k3HTmfSN*@qSMB zM$SG7=O#^On`LWPXl<=uc4t)$JA?Gbb5o{O8qYh(>G(z>MYrS||9_-#6mj36(>Gsl z#bF)>hBqn<46;~49bBDe=B4Xpl;q~@je1!my;Jbtd#(MeG)u zULU?ZC$W1@>|L3;^JO>tS~#-{k)_ug+OhnYm=@swY1a3aTzj z+SY&jBiU?!*eT+iS6oN)xtJ+V#j8u&eM2){Gx@Dll65wRPM1`?QMB`o{{3%L=cy~L z*|JkY_NvkO6wCBIDa-FCY;Syg!+q-2of3R^X6;a&{9XCGa!tgW-nLCMHZMK%=Fx)9 z|1bN?ZWAcl*YLUi-^Rlgde5IargL#|UO4;WrQ?m;FTb&~EK-<}t>MJMF{ z>UjI-&*yvhZ>FTS-h8{{6kFhItL8Yz#4APnZlV1oLbFWKu)>EJLI&^-o=#2}^xluRili5|=?Vt7g`*uvOQ3wzLWNJgqz@xGu;2QhCn7_pBA6 z-1FAHICO3OvEpVKn|rIeo<53u^1)LotRZX5_7I;lX$5)=k<)@5yQh2IH;j17%5FJR z>uBEmrRVCct-_xAoXhsDYP@{kjluYvsL7GZUX1HDavg5JwktSI>-<%r!s7E=pG=OC zhzZe*jGA_1dg1Fg4;&{;J(ATj-m*hdZ=LZ%eyeJUX6M!J&buXQzb(4Sdc^3k`t?N* zmQD?Jp6_?0=X!$apPx>SA``yt*uC@Eg*4^o`&O@i%s*Xx`+Pn9Wr7ItdW zi_EOKbiEVkxt0&6obUcFSNzuiTTYQ=ixVik-G) z>1zjudg+vJRT4RSxgO~6mt~2_OAy+)_nl9zmJ*Cu8@K@pQx8J|ZZNC}!zkTg18O{!`Ud5!3`vhbw=Q?g# z__5?!=?kNa^S|FLFltIYd{AZL$4}d%Zm#fH+*Qpd{hswfBHN=KwNGON-?4XOK1rDK zZGPI_&E1bb&z^kw_1f<%Eheqx@+gsx|B=1cI_8&0$8P@Y)r(FWAJ67zKN>v6*4}#8 zUMrdUimpxbuFstHhwIhX|2bFJ9apb+vF3Pb^w?^d{QR^3Y`Ep>YyUreV{Iey#o5Pk zPgcYAk6C;%zh(bLTDSl9*|A|;mAOPhtFfx!-<4Wc%IbYV^RT4R6XYl9GUnXVvFD~j&7<0)( zo(2OI6W-8?!reS?{(OlL*lTaMueRr*{I)lXS>E&geC_vW&t3N)zxb;ja(=hAwB1$t zKmN`o&#Y5R0}S>qkco@BEE&4m$LE!0mT1J%&@S7fQq3Aq>XSuRY}v@QV8@|VPbV8N z7+qc!zQE<^o5v2pnWm!07!*Fw@mA;^tRn4t|r+L*jy=naZe4_8=ReXgrrgW_H zS)7!}ZX{hJsZ&%@S65wESz}?hS605Rs^01z@6xOrv&HHKzJRRIzsG$yWPOBDiQu)BVK_oE1zH zd6jOre)M6|UDqS(I{lh|sA{a`#>l7Zr8jR>Id0JI?Zh;d=>~&`W94F(&y&RE7YJ{d zwkS74_CraSzit)7qHQa+9%VH(G+o(qvksxMqGY3RU`gE>n*X`CF?ufUN_Z!f5rEWS6v{fJfbDRhG*fU=KsERPg!5j{P^_g z&#wmq%nZMIsDDZ7>9l`-Q)rW;kwu;S~@n~`F%ip%? zoF<(=j&T<$UoYOU{jh!=ccs|D)vTNJwpeJh?POrEjNEu;>h~-BhtxdIM146hRhZRx z{;J$i=f}+(LlWZ8>WJ<7FaG;W&+`W#Uw-`|cIeNq1?B&1SL=!kE$Y1xk@;p~%$I{= z3)1uTORCuw1 zuKJWcO$JP*ErpJ%J0`v`&uPqUeyxzY`2G5`zy34`x;#+wRKL;w=S56|i&ziaO> z2sBJ~WfNI3)$qbujWyzbf6iRNVzF#a)h_O$4F}9iLp5^?wTn8J%1Qi6QOOKu@YZJt zn^#`RR^GU*Op=A+Z2RN~oA|%HX}R9M_}b#%3(s8S==D^X%U*HJJx-_L2lu?=1vek= z?3ya7AD&So8$6S7=Y$t!nobS9;c^yv`NbQ{J+H6-)V8h2((2nyLETH&qNm+GJNwwq z?uV<}&jzl^`+HKeTCIK2s@F$7dOX(ue=vW~fu74Z(_Vf^4O(t;<^7vp@viNW!4FI( zPs@3FG$81ZM#Bx4;)E&{#eY(@bK3TtQm&XjLv3Sk+=rrfY)YAjZ$#|7YHGxL@sh#= zxh&OB_S+LrUG8yDjymF{t4!kyw9ouB9HZhg%bb7rKD_Q8+LKJUHdDM7M;Y*|A6g>q-@%p zy}Rc%1~^~!dZbvo(Z<50<OWB9lABr$jjuUTF^-FRWuhu&->)!*l@92a|4Hg7fO@t_AU zp1t{#!u`61$!_VbT??b!t^IiCKX=-6BXDY~z|XtwcP`uteE*~=$~L3sO~&?#GrT;l zb+!d-P3!s?ls8{(>GgTX)^oq!w!}23O5J_>^nm|MVlypH&o^EX%=O9kmQPj(*Bo7z z6qdTrOTRyxWADMCEXC3!KjXO3#X|Ku=31362ZWRp|H`(+OKYw3ky`z9NuTCC+l*<` z7B|jc=9QhO6`JPKb|5}ro#&hVRer{k43~56l;>F$De%Z$>P&x0B&$XHoL~w2J8P3f zMe{jJxleR0Q<;0{#`dduyBGR&tQKHQJo9>+e~e?a1c9Z{XU##zpnW+K4H!u0FcYJ;PX8GUwOxl}rc_-ihd$%Zi zcDuC3yu5;y#wHI{b9%1{sJ3lmo-QqB-k|foiuYbY+nW@I<4lbcJ9<6Eb}yT5x><#l zqt()|?8CdW0=IX~ee1C9)D(jmCmz1Yn0>?YNM~Br&)DaWgaVFz-ewv7g7e3+U|*B| z*YUS5UbTwIJfMCo&1juBll%g=udgpX>|Npzb+y6f(Cf6KZo_$U!m8^&M{oZq><5_wDktS<%q^O^=TA)foG`ELk z8zc9#s>h$*Wi_WtE~9(FzBWGLQ>huL%gZzW?wH9Y_hFmAf!@=-1@7+WbIzA#Xy{h; zDKizfGsgruy~uTWd6?6pC1J9D!0fW97WTE%cV1MPxoDcj#s7*&cZV466yLRHrIMn@ zWjkih862gH-}?XkwSKy#iG8-hQTuwnfcSF{w}`Bf2y03|*!xcOADhPRGha*d_?%T{ z?_zuRXs7S9OOK|MT3pQhyD7u%vv@*ZxenhXmq_tr|H}@FU)b)HGxw46td#i7LjBO( zS+a%`4A+(LPkE<1<3S>ha*DQ?YpvIT;3(Hu77s6!{!Cc1o{qD-7{5>YgXV+&}J-6usLY@kT051%1HWum)2CNrGGzh z9}jzRRl7?!)V=Xh^wNnb2VQRau;q-Y*5;x@&y5^c-XB{_}zfq3gxL1Bxip#dk+t#e_YG?jl?ew1w(Tgl!cuC7hvNGIU zn1NxnA?83Ls27=>pIeYvlv$jgR}Ag|t&Pqumf1e_?>nu(>~EH2x$8`}Ra$DX&F7+b zpx2qGlh0-aY3`1WR$C@*%)Bu^Z-M8zf4^*>FOq+usA(M?sCp`6*>9%rrSEo%pZK_c z&(EK44%f%+36+k2^6Js!*X7UCv&uF^)Kt}Ni`et?gWKO95C2+!RjS+;vFC5*w{C8Gx_Rj5v1N8AYs{=GKTSO}KRLfPZ&$rW zX_)BNyfv%6mglX#zheI1V5-JW&sk+( zrtd#<<=Bm{$M(;v{e9Nw=9{Z;uJ2C&@p-jvP1%>{GcWCooxVP8rRLtuw8b*lm#k0o z+{E$UbN|1p$k21@*}ETE|C>7N=>3(;@7GoTm>ZS1x3GHigo0Wt?R6%MAt8Ny>~Nvaop)Ty=`^DQ-8mTSnZn}w!VsgX?c0)>RW22+7%~N zmVWGxoUqD&%C{RXZ|8oxs{Ej zN$cvl9kolX)18h6&Xe$YT6XhA+V1sh!h27y-D%i&e&w};GOL$qUCF&_5*@v6YFyY_ zc~%Gc%QK8j*)y+ByQg|VvYVw-EUD!6YNzViuWatG+M<>3^H_1u$~T*P+lxMX?bJ;9w!Fgdb|2*1r zws`9my$n0AJ-bfvH0_CDFE5D-JAGd5Yo6Wx_A{$uyXSB7O8$D=?fO;=ORmIqE^~R- zd`fKo%C$Jr;`%b_uREixZh4r$-saGt;j&v}{pmHI8#4GGPCS^he`jRnu?v@0tkL52 z34Lznx-5U9x3h%UZmz__#RgMxKqMLW_De!*Bhq9<(IEmn5WGtdbT}`skvJ7fyuj@4tzBa zRGvJ%9(ZAeZ?kx=@v}Lr!tNZpyN#c_YVv;5W7~aK=9S$0wD9+)khHd*kb^%Ii&fmB zmS1lZ+|U&Kw}V~L$33%t?X2h>&-RGldaM7UF~{=SJNpV)Y6&7V}Ewhg(5eb)qQa)?I(+Gwcjp_ z<>8F8lMP*dw_EH0n{t}2>?ekVw~Dtv>s{X#%H5tT`HhF^*Oa^iQa`G{OulhC)OCv4 z;@(V&e`ar1wTGs5Td_D+1SE*v)96jz*{QVpDzCyZh3gv`72cUDtPOO|;EOc(-F@8g z;*^^6nrTL=X46(`FuoN@5|7>#T;Md1b<4YCs{=C?zS{YO+}d^aqcx8W>pHtV%by<2 zypeo0sgv1L`h={P=o!f-+ot>e(%i2POBX-5$7a^^oh^NxbgW2>jkCov7u6L9kl#9{|nLoUv?x_tk_jL=|DikdyRb}TrLx?xH5~p=U!B;GnK6^>_GXx zs+n6)pW1b}{`6-f|7%yzzIo!bedn+2MfXnV-?_f8g=@u)ThpxMQyYKeOxVkz%IP8` z68}_#N6n@C$-|$2*rs0Fv1Oz8w2Eh1i>elX4i#?+ym07|?#}}PcXV=|9}sNOT_y41 z{LfXVL>A6#jh@bA5mdwPBYDaAk%x9zO?2B|?$1wmb^a1$IJq{!k3%5+my7pmrwKe8 z*wiYL<1S4)etM7B`uc3`^KB1az4{w=X%Elp^4p=?oi4V-rGy5|&r80SCd$O!bM>@y zg@S^3q4bYeGmLF(UK%~hXXasP32I1M#rXTt{R!-%*9{`Yt~9$@Reut_D&Ti?Mf|n| zH=W0tQw~n9(G+1l-__8h5WPOCB2VG|4JL!u3%t&2csaJ{G2UCTcFF7t*>753wiehZ z=J(FF>b}Rgamv|@`DdQz1oXWBWANEpZ0%VU%kis<@Mmg z>o4-&M*TV#`Q2=lHsjh9Rc8l_YUg_`RtF1QPPhj8GdoyMS>s^wk$(ZF{rrC=m3jeI zX4;dMm^VyV#aimhccrFCQt4Cs zQzvycH%0w?5~;#;dLjdt_KToLdyZ|7ys`M*!jGAvS6_2qe&SK{Rq^ciMGJH`XmqM9 zn(4XUWSNS-dgPR#6N}VE?T((S-C{lE`r8{{eU2Vv;V+p|(m&zKh1rG6k2q`Cd&$Ze zWC~4Bj#uRDTGd)M@79zX5}(rVF8{+kDPxPnl+9YX>}kzK`%5)eY|{S7&#j}hNMTy% z|MQEoHXY3_XXIwL?z|PbUvurLZ4pw8f#I`7QkHsGx+G+iPLg zS@YEM&Q~J$o12*iO3xR1;AOSw%!ztl4ecc1S*g?RGj9mbovGE75|^pSv$dpr!RW7=+k<*)I0G~4Tp&fN0AEWNoD&9 zM{-r`FFwieb64}cz2T>u#PaIjhq?oWjy+PUj>tR8BT(D7U`pnRDf?5W7CxPGY**(d z=WX}ie%;S5^Iv$!^EWK@g0BD7JvF}m?YHM|JMt~##sx=%nAGnVCNGJ9q|(O_%YNzD zEb-7@ZkI31LifLLGA=bP5nQPECI8)(_J6P0y$@y2y!6A(`pKo{s`AO2vwSzj+$mSE z6fiy4cdpCA{FTdxuAQ$n4y@pM9ncx~@T$+5uLqaRHY)gbV8aWIb^9js3fF)2jo$N= zA?S72+h5CerM|r@f3VGR#d>u;mG0$dE@ilFdw0d)&y?~P?zTH4uW#qPtB}^E&?@*u zYOeRXV(Azy(V|N~-&}d~nOpNFzx9iY?`Ch6{=M^A#pXL|2H%+e39RD}s+~KNb>&AX z9odVq`LCYar@Yx$zjj@`?72gWtfJagPgOm;tvalQMg`c|O44gcC- z1uh@nEq%JDHExKZ|- z(C)9!@i*pYo?vszJ{)hW-IllHNP_H+-rxy62SPr~$;?bxeXwi(>Zb;ow>5V@&WsVy zER5S3o&9jyM)Y+Y9>U|(|?2GhPW`CJe^AeSpZwU*m?^$z&;0fNfA`AWnKpCBoz|N{Gt?JtdV2Zh z?*=zsmG`{WFArBqWGoad*q8Z~C#y#F_rt`gxq^M%i-X;Ya!Zaa^WUpuxBJcR`fq_Q z|AahqFMeOra>PbvdQQ&Y6Ipy)POaW0wDrh5?n1YM>tA}7+}YIrqHXSh1S^|aUl#Y> znWfkMPUR?4c9>?R8HUti5Vz{PW50=Dm+wYi4~~``_vG zntR`LzUf3fEM(hOoT|`t<;=R=sL-7P;x|rxm{4yxRYrcn+jXA71;&R0c5Pl)5To4u zB<7iCYoc{#?7?s9>-JCnWx7MzDy=vW-69HVO8|8Ji*?OtPa z<+bOJ4ezzSq|0&hZx>VPkLT-m=WMQ5JgMSz^3pH07UkP=e04h-3+)Yje=;O? zov&z03yku8F10iEXTY)Pxsx4>KGZ9$ab75=@846ZBW8JL+k^stmEFgRw{PMqH*VNh zNPUdhziVBE26)58Xh^U+ImXS%;w!N1 zje_-7oYyrb1RH!9@9W^wTA zF4%nb$b~h+!0H?b8h|ujCJBSbVIdK4W3^@)b{Jsq}x6{K-}GvMr~I zySX55{W+D#NrADS7OJdS=Dyih`i19QZr$wo=c)Xc|I7$^`z~N5?N58QtoD54m$&tf=$mJggQZ!D{zx54z3(~Uu3@Um^Y;}gE0ltM zJ^eAoR(5Ze%r2Fk@kgY6?z(zBd1%kh>mS_GGLo5bd+ZTQ=dMsdlX3CR2{zdQReOa;oMPKM)(>+^FzU;U9IsfKK z_ROA=xV4dqyB2du*173npVp2CX453~!oNJXwBEkl zZQ1XP&EJKE{y$x@h%@xn2L0r}hDqUjuN<#lT5h#t-;1m_E-L*i7hhTtXMSzX1oyag zG8{JL%eyXq$n02U&}W*r>%wuXD5ij%cUB+eS6S5+-BS9O9d-5gdqJtM+a4aR`s&8~ z_sYvn7o~fBEULb}i9EEM%gBrK_ap7!Ti(^J2)O-Yn)v!xZPIb;`i(g6)SYwKzV_*& zM+K^C-2O}c%DH9AO!>r=X3o8d@xsRivUz&Pi`Xl}!)L9$boc4(7)$oaN#zP(yFRns z6T84`zJ>R4?#hFEjwyVvJ>04!rf_}HdLHpFZkcy4Zd`S{ZSl=^Y0VvK%Jvm2?=8;# zlQ!SYmd9RR|Iq*M4^M{wXGaXWnaWMldMM5ooh`_~P+`EpponG3L2^-kadCWZeoARh zDtOdwX;kjy+h&vgt<(C;ekW#adD`NIImb`_I;OvJm0g@fB&AJ zpLcJ6^`^+~|BtV?fByMB`~B7VdH?>Ne--(y!tVdWzc)*Yw(%|8IqUrUckedsUT=JT z-7|Chv-Q6ozEwT@;myZ8?bn_uYC9EvtFoHu7sn>;_4!xs>plBTz8}1DZ`ZF)MXupe zp)-zMXI{pa+~J*O6P?ViZLElTtLv-RgT<>=LaTE8#K;<@v-P2L_$Uf9RBg{ME3 zzw-0*bN_#?y4w!^=zgfXd)3EzE1NSfAGVHe`MP@Z^7=oIXGTfyj!Itk{Jz`6>uBxUc?Skh4Bb=i6Gy}GYgOM+(gYF?gfA#Q*A3NP=L zI<=&!d8x&*msYH3K2^F_EX~UEme`W{VfRdSU0pbT-S#Y*=^I~4-}q#;Vrgz|z`Sp+ zDrcVuF0P6#XG;fU6gmHWYOaDAJ$(~3sjZfcJWzOF1N?( zX=_(kINf#Znx=BOx^LtDQ$D)87G#NwEZe?TbNfvTk$L;}9V}UUGB^3bNB^6T>)%OL zOj|g00k`Dug1C!U?_BPlaAQk~^$YIH*9)RL-1N@JEstyaaI5{%t1M>rQr!uPd%_Mn zcoxmRq!)EJZ|eI8WkRZoFL`&1U*=prS0-L(S4ry2cNy!oVy`dTE2N&ynV)lYhnSsc zS9D~7)y);*i{D2+wEA)CXT9CbmCKF4e)X~ay`Fo|6w|r!_w`Etz5FBn@7=?v&wqR= z(ldTPLv3ZL^))Rib~EjmT$Lp!=O>pOnv!ZccS7K_*tx+KeS6q$>Fr*8(K6ZmaKyIf zi#Dh3*z)0!6Z_gj+Zqp^FF$(n!C9S4IsWI?lzi3tm*g}rmgnQlDbZ!R%|hJQtQpJ9 zBKS{udl|K5PU~Q9xIf?T+AJH1z6)hrKKlQ=M?B7MLJryl4<5v8hS#_cM zHh1aLRkweC{@pG4@9wmsKzPr(c}Ye|F>B=M%1fbnDhg ze`3GC;^4H*w``4KzQsj?VlPg=&-r-n{&B^R6P>3S$^KDEwD`8YZNgmtf-0SeDxaBt zLMwJ~Xqp_G&1^4aIiZ{JQ|$YF`>$|Jy5PvN;117*b*dYG#I3qDqbbNe(^-MN?5#S} z6xJdG-5b^q`lg8NYi2WK`(tsZoueweKJq5Z8TNPkva=*vcXv5=+Y=0^ALTN>w%!ea~?`=(Eb9|+|c86DR$Kekrw(00iI>XH3Yu)U5 zD>Pj3=8wRf{F0lDixqZUm^*ihX#mdz{%Ou(?2KIwg8P%7%PDaBJ{NO2Frjfl%BER1 zkKf)A$XEWm#cI3cnu$K*cXAKs&yW8yTmQFa>IvlshU{C%9#yd~l zy&T;cd{)+PD~&5_4P3&p`R>j&hUw3Wr2l5$HCZCxJEPe+{ma9I>Hh4x|F`b!jm$4N zbK6Bw?(f>-za0N`PAF>K;k#WpFKyv{c8-p``Z>x1;-8w6nPwlYDLq1UC{Ytbn{vL z0Off>**w>5|NaeFbWCZ7my`X4(@Ix)rx~w(zw`4$k!oR=wA~w@>4gTkzLvURd1IsJ zrG_tVUsca7U2wzobL9M42kytVCbn`+He(AtwXbY>y7f{?AHPf{=71c=n;)KgTcvR| zG%OP6Typr?xg}A)M`DU+I-iSrulJQfGILt*+w8d5;J@t!Zk+9p94EL*WFC5QBq;Nd zwBhWWOK0U53AP4(RDKqzoaf`Uprl#+&GSt?OhS3vRW5BVl|3bpk{EV&W$5c&Z8v|3 zUwOItbh>R?xqVQjK#Vin;aj;}7w-qRwXU7~PA1rtn=#Xsl7*TdZ1v`TPkL#q_2!Ogw4zAJ)Hf|h6U}zs2p6z$n_WI5GC4Q#b?@&Kr4W!qdg(XwbkmAjAD4#`_lk9SXsGKs0beJO^`JGJ_D5#!^%ae>Bc z>&{NqIyE(>TKVbK#;olTDr+ZRk-561^Tn|x=6;nrX%Ba#sF$8T+x+FI&6*GC-AiM4 zFL_LwSK~K{wbnM-5%ZVD%$OeNZD#^`D%y+exn^>)> ze!kywVp_15O;eDrhZtQ$Nx7%{ohSBpog&&+=aolO&gWMM?k0Z-+mvH4Q z5nsLI=&@aV4#rugs-gWmIcIx*ispVAJN3b`^9@XMC+&R^YAF7&ohP8w{pNw?Av-ro zJJ&9+620cWH~aq7Uw`|VYA*jizcKz_y|$3^@{bM&&uXRk4>e7*DR-XDJF#nnfu>wkZsL!P;di$zSaGG; zRnu?o9j>M9FFN?e?`-%rvFbC^0q^IV(q@0y=`zu|fwgj9x9|SRdf)qOzq6lu68>th zchL0*Wk>m<`u_Bub2{>_giT?gtlUi&=8z3TbQ54{8R0e3A-FNGsJYCUV1=AQthb9 z)Aid7)?B%8@^<$9i^7YpuF&5o#541h?n&+BYWXjxPednNiJG3*x@Al8s}t!$zl&uI z!xf(;ReyNC#v(~i+kW!SHw$;(Yi3uqzTs^BBSYJ&`1M=!9q+2m{dhGk%KR8P1FO%9 zsa=mfwU>SU!48+x+)uM|F3Dbva1mH>^}76`OI9I0jM9%Rb*$fJiVB?%Epc0Z=fWIG zpV^TlE7Iusp1z$_r6;E?&XElMShH}M>kzxbmQ`(Ws?)ny{P{2Q|v_2bhG!j zxvi(lN(x3knOyT*X~&{neIHJBbqY@?d@|uD$0e<2v9Y?J)m2Y6M2r5urCi8&=ggD? zZdPYC%A#jIig8|M{bu*AEB&HPYsK@Dlm6=%MjAc!GY@GfxN_Jt@=(}`Nz?d4g)DpB zH*H}nmwxN`TdlORoTKgC`Kp!A{7S2GJ_K8(JUT2=lWVf@)+M3eev(4*Tvjp-x3A9O zJLkLYR7IeV&WS~pH*X49O4fCq|FI+3VxPf|^Yi9>Kl}XU^WEakD`#c(FMcc^^Pw+` z_mkhM%J5lHDoVvR$2z9Dyx6bJ({3=|eD^w?A2lltsvV0lPIycS2Zqs7u{Xt{!lb3s_T`* zhSr_iirP-5Pv`Tg;rFe3x2o$6N36E^3!kZTTHn|A2r4uk@%!pO-8iEO^ zded89_V6v;_vMrFU8cw`l`U7Iue0uyKQi06hqowce{m<<Y|>n%U7%!^und>z-@ zIG#l>H}>V+F%0bd7#=J6CN;?L-?`Fb7oBvhw3Z9+^jLbj@LKQoP$jP|8&98Z-n06Q zl-a_RgR&#Ws_#<2EP6M>Lqsc<=}~~3T(Lv%JHx9% zF>fmwm!A!`KABhXobUXe%aUv&QwtXEc4}I_)i)2f z#6`7~J*?Wkr`EV2C#5W^rPYJCf$?;GZ-v1Zua{5$a9rFyt?xkTx7T*peVJz}&yo1+ z=C=Q){N84Jqq9O!9{l)qIHqVr`O;@wIX~NM|NJfQYo=a%owa*?km&i}b9bh$eJSwa z)z9tslO+AN?tFC2qJPh>uF3HyZ>-kNT)!=?Rp(kB=dF6xoc+5dxi6dQdETGre)R7$ zN7Lu>E133uTXFB^(SOlLI`UmCs=s>K{D3`1hXu z`wyi_e!ueljH`xIOUEI$mFc3}75y2{e4is$yVUa2=8A@|YE}Hvg zi_*DQiI(kLa(HvX(`!c#P4L;K5E2vh?ByX{opL>Ukbw3*^wOmPy5;`Y18Aeg`^ z?a%w;Rkys?p^!iQJG+;aOx!KHwB7a1be=sE7Q9?PcX_mA{p%io5rKd26;?-D>X-9t zKH2%LF|_GJ>Ict6@6&yIbM!CP#pG9(F}*$?w0_;T7>2~#`=y`Xu1MtVbZY#$%|%Ug z+sUWXf?euYC$#_XEtmc`Z(Fs!h{#-@z{`4<3U+;y=C<|=(hi<|#pfqevC8k=d0X3- z+gJYCeR_F+y}I$izrQ0J&fHcE>A&~Nb9v0-?j^rX#O^ud&9EphxivRn*`eOwhBxxG zX1;jA8pjdMCA{n9N%56hpQcu;pBIeVkRN|x&f?!M&PFccskw0Gs9JgER{5%%{5xYr zg72MJDR)uwJoi_z`t3FMf2hamT|MseSNrYGoqx9TeVKKmuj<#2kCT0B4RTYLsva)c zcJmyExWM`uxAhtg?PA~PaD4d5)h4mIz>?czS%l)d6M~OoA3AY1o~t%|@Fe8OXLNR3Taji$BBb8dfj z28R7c3=GOxMru+LOA_OYONvU9OG=AUi}gw>N}fgr=HE6Gs55`?|A6h$P8t4hizl#d zxRm(%@HRV<>K+I0k~O~5SUmHxuKay(9kj@$Yl+Lva~DeEqg1ZRzVAD({C@Et?=PJy z9E;~Xkf^now%f$fv8S8q?wb5(3KeGyr%e>Fwd5182$|5b;*KjT*GV(4MMhr2(fhx9G)HD6acv6xp=A+BlB5|v7(V%<}J1g5mlSx~~gnb9%ukxGJm{=9^?K%pb; z23~Q?Ca=(W@VM_u;L=HxB`!;f@7B;3d+~jXN`lPv7thbDdU8#$xhP^&(ch7((XP^- zF?;#%mrEv@biL2s-XH3v{E8#DFkq2}il-#2z$>$}f_=$i)l3Tmj=q_Yp6S??_G{XY z-YGXknvP8iOl+c^|=nC#C|Dm&jslMjD ziSlhj-52dQ-!g05IehMZf=0xBap4?^!~Z}0HQ;(+v7khxu9(mc9kTEE4zx}=gD88eR0;A6QwLp}Fl0q_sblmhRi>o&2I?P2@#4=|@84Z@!6XoSFY1 zf!*<`rRFA+g=@E`%5Gn@?%KMbeJhw#Lmp@a=c>m{S@=5aWz_?*`qbbr2|MMsS|+<5 zKD0FSvQ<*hkM;466W;%wmG)E9`Vx28PW2LYC%3{K@21Z_Z>|?rx0ZX0-sisc!B4$k zpRswU)myWw{?U(s^V7|QSecjJVBNa5T-VL;l7>W!%-L5)Y;i|UxvCW1%RPV3^srjc z$LF>=7o7Fp-k&6*dizGtg@b8pPARGUE)h(**&p)m^YQLC7Vhgew0=&qgnidLDNhV5?rY>x`a4%!_IZy`WXCTfEM&?Ou7bAo#SW$NC8$q@!YMTGZye zePOF(=fqK2RdMs6XYiZMkW%fG=^OgD?00j${HH}aO}ckOx^+(N-jwg_zi#S}4r~aM zU%HKj-#O8n+ijEX!L?u9ZCbYFgv`5pszsA;+poHk+(&ummab%APl(!eZb#g?+frhd zjTL2I3z=Ga=9L=1U(EGA)H-L^!VNq9qLPnk^1G@zZu@iX^wft-?elipO{v@)@grba zUD&12>N(eMuRV0)s#SIFyH~+tRr;5npUU!`qo$C%>+J!i$-fR*YA;)+e7i#_bvOI@BMn2#1!DTwJ-cjHS6zS_oO`Soi$%K zS|`7po!ICzbE8FHl-+itsq0Sex_Ypr?9KIq`y-7d+w4p?rIpOhVx8MH?Yyh0@s6qb zD`vK(zlw@z?ap$`O_Pm@FlN5;?9;4`{c|tg{2zSQ!zcV$d8F~Rio-Y96IRXi+c#Bo z!cnQix^Ft39BBD<^uZy?t|@ip7n##<98Eaq|5uAS>0;~8=-_pi{yObjbcXrSsiV99 zi8o$pOTU)zNG{5D?wNPbrby0SX{d4MYX(n;wW#TVes&X|N7q^{1E)znb2(Yn9CEYE z+g`hD_K}%UGp#?mW!B^7EPk+u2xmWbAQ&nlkQiiiH+Hfq|C7ZD~QhB-CwcL<@VQ*sjz4Kz?zsFuy*t+k_ z-la~lezkvo{(5ha{UuGb_tj~$_hzaRncq%q%eB7F^(-imy~X+YGYz9ujuq*-yuxBm z28IcbPrcNf@!hue8qFAKm_xje%jG00YL6HK66nsd=Tj zkcG-eBclCpdx+HaPx)VPjbCJ10`uPXh7hMMu37?9OSI=*>a^`l-)Q^p%!~yB|KuvT3@pl(WZPw%$UvX}d7X{Q3ON4^oPl z-m9m}KWN=A&9b<7{q2uQ&p*`(=uG#n|9R(nnxKyzo4osB*-0Og%r~4{apC90?mdh1 z*gqH-oKoFX#qcA?W!~x>MkDQ@=v>ZQ)oc@YMdr&NseXO`%Zf{^I-ySjp`%)%uAG~$@?*EsVC$4ZUd(moCe5s;WCi{@{`R~o2^zYo8mzg_v ze?YO-W4?pg`ArHa?o~l%%LT>9T}C9b2ScX&UIX2 z{MzMN)e@$@lQ|OWV|u*huk`S@E1fps(wpP=F+gKd%GI|I4oYXraBGJ~8M&qip6T_| zRN>A&Fw~JWkBHJND%!g#=kh9^ zzia0y>E?brvv8KQ$l-vzp9PNA9&&q+*+zEyuau5$S{mrrbXBu%rHTKCHwsrK+9-Wq zZh89N9VwPSeSfv4&#l{Hp}%Rug)McW+b&zK7L+jVo^W%gQ~dN(M!AB6sFBd_e)9%)NSe9AXazlcZumz*P?$6uI#xt9X0pd-l_8LOxMvQ z*28ae6NHw&V7{GVxG0|6)i3Onq-{pC`xLch(G!)LBYN7;dz0g z(JUc;-~2V&7a#Xb2(_3LdVBpg?H-Go>Y6{dg&+P*v{|+;NrmlcpKkqvm3_K1@9S)p zb&mcpW1_Xy^qb7nvwdC(-0!yT)bWf+H5V6)PMEP_)*b%3$kd=SIXy8UVRq_=ErR1W znk<)!ytwGkd!!MXCK~PzL?z5#k{e<=|S=QcaFPJK=G|#T_;K!p! zpQc#to3&@Z#eBK`e-^g$`Sj2Im#N)jb5#8K`*Uv7AD15%WSye8>>FFRK}+rbx8C*h zi-f1$is4?|t)t}4crI*f^98*xkFOqmqc6GZ{=;qG1+>*VE zjZ1&D2m1tEpR?fZY~SnotN-rXX{@r-{nj_OXW72w`2CaWy%AE5i ze!Ih#$XQpe?Yw9gZd#zS%Ii+wp-rK@l26X;dL49FrFz|}SxQ2yR~vG&uhVe4bbiDC z<4Y71e+!kyo{iqoEM2f_vC_kPYd0)Vd6j?8`rYA((6rR4N{@N`6nCCmRHc)9wrtK# zOFpHYnNure7G|_QcgZTS$hjlUxc~Z`%b}T*`{i=%68yB*J-u?`r`mMQZ3(-!Uu9nZ z_f6o8`p{GVm^FXvEDilCzwyDUS>lqVPP^yqsJM2N?L|sj<%DO4&aecgatC})`*tvG zV)A}PiQTd+oS_d`{Eb#MU-5nKyI)DTGwwxGm+hzYxU;PGhe}R8TIRCCW7hJ3OraO* z2mVffR41Cc+fp{hpZMZ+t?;YIMA@~<)yG(>72X8j6KcMxoUbh@Ja_x{d*!LhSAM=?X#0`- z;vJ_tQ+riKyZG9Ogw7kse=p}x))7CoDNpKtVR8SaRqmc^o~@31t*14)MYdlgc3yhx z>PvQ)5*;sdY(3KI=$GghX5Nt{!`dGPatc8@o#(4>EjcpV^ntDhWanvdu{u$I_9{FUZSLUgOERo$s5wToPkNBvb zTDv3W(w)iTYR4O|)=NF{uXH(FDu1q}G2E7^bbX8*%hUbryXMw2AS%ZO15cfgCDpG( zSr`~%II*8(kXn(LTac4#2wqY!H7pm@P5qa5;Qzx_jFp)&ntr>@ir+A-Ojcn0lw`u! zR%etkaoP^gMPBn3Nx1&|-M1u3d!1p9TaxFMyN7o_pJ!e5k6{2Ut5_SvU{-$|bk3Te0OL>9VgiY#%`p5t5LXJ$Uqs)T@wVE4QwUY;52Lm&Ia>dJg-DcF`_gUG z@23c+i;8cU{&42n;E8WkE3UmQv1UEpsu`*CK;1p_K%%}}K*Oo0T zWl87TxGLva7U!|zgyi@z*PbBJwmXvVJR08B+*!zKbb_5(UQ8v5!^UDs#+CzK;sQ&W zGG02aEjiX~T(MDZ(uFhqU73Xm`Q2La9CwR8aevsivoKEI>{a3u$x7V|(%Z^JUU_9K zx@{qqleY2Ewg4%KDSC`2MAvJ)osl~8fl8%~Ka0{*Bl8m`T=&#llesU6Ulo4Xxbn)w z`t|dJv!0aqKkAV*jt?<;7R_lgS>&KEuH)Qr4rA4{?OZ>}=&?u?MLi2SNh5YE2q z^eOMIGk-mZ|gm@tbO;~ve$V#&19{b{^bSy-^c#@{rBqG?Si&{HpLoq%u>AY_RH@pKfbu$ zQ2!gh>bl+)SDeU{1J1FW@5wm)URhxmR)%0Uq)l2(IUpl6Ge7(X^wDVOi1Mk%HoKw85 z=ZcGRtxsI{NNaiD_Q{49O>TK!SQ@rvW=4qI{$m>)wMD$7Jl5#2UcMs3I`_~_(lQJ`AiwLb`)$Ytu zH11r@J4^c2(XLs6w@=EvTlQn)6O+F`81gb%YTsFU{e7MIq<&Y4^?#)DsL{YvCxWZE zrh=V;fkPPcj2>`fy`mt$s3bElJw7=nvA8%D(r}*|fhd?3F>c+vBWO}?>~agXAa!T% zEuI&4YWzC6K=sxmuTCk?o2Fg=zTcfVN!R+^H7U>R&hP&|-7#D|dG_yBiP`vzUk(4<3DGP{JeQIpHX6N3~Qpq z&-qWjl&qVw@nMh-Q^KXVw<_#!onP#)sr<)&#(dgr#|@iRvm}cXZV1nlHJX|`&w4A{ z$=ve{?suooj;l&M(<3 zlCkrdPW`qm)7jmpOi6mlziV#O(>qgi9)1vA#IY{iYsrd@o2Cg%-sm|Tw90bw236ip zK^aS(Ee~9^%^zaVWyTtoQLPooUmjPgt>P zLzS_^>>RZ-#YWre*u&4hRISNw*~)Sts5tL8^M^(Io1SgE#LBYXQ*qYnB8~@NCQb z3$?UzN&-J!C}(|QGrxFm@8fNrGoEd2)GU*ob#;nTrq|C!_8++Tel+UbHh;ZQ{^S4h z{_H<1O5TdS_2k&R>C4*9*)sm^tuJppx?#WDsJNg*h{&0MY8$L6UK#5(bEPV0RB4&z4K7tg)&4=p*6q|5S}S8k$d z!L7GnqJkG5Ejkd$ZYJzsB*XaBS#iZS&kOyYmQtl$W_rpWS4{e0GAW5i{-?6fd&kwH z93H}Fm=aGg_SEs`Jeroe`I}91>9Z+#Y$pD>bBSj3ci1Ht*hBE zSSv8$bfU?IqiZuKOmcI&BT*2WQ^sRq9w@ubdbRbT<9!Lf57M@NUG#RH`Wx-LZw;oH z9zP_pAXez4VCT{wcV4|-t2F20y%`%eGQ00B7hlPpx1n)X<^S^5k2-hrI$v3wvv(~P zyV)nsaENKs<|#!7=FR%a_bSFvx5e$}ZkEb5t9>ojF`3^FD>`g7d*bSkV&@z_|9o+< zO_=N18P+2q#qt&=MN?Kx>6cY%$zGaj)pcj~`=)tT{$9&x?-Mq3*k-^pH>oFMZ-$hf z_*>y$SF&e^-%&dJb?x;K>!V4%i^b$OR5u7+DGri5c#L(?Ec3bk;SsB zJpb2zvA7m1BmR|HqEsiDUqZS&cKH;WM*mfd{(RM05+ZXZ&yek|DC^$b4g^gL7k_>YQ|{cwm*hv@q-1nhpDw@_uiO)#$l;%QQf_Z`GZp>mnBzZtMB= zWhK|2jd%WD*prd7E6(D{q@ovRKL7moO;Akg`?kGzuS~Eg$!K5q-X&8nW9IU2%K`$J z4A<$kmEN0`CnMLQ)MCzUA`!oN?hc>NM@3n(j+$EaHS)YX&v7uq`i!QVp!Dv47EzJq z5lV(#pM&JMcYfEuA!EE-=vElV?%N9;7Jcu&ayKmM)2r&!mAY@G{uQlzY8+!BF*89@ug+d>-mNfm((u&%VsJ*8r{=Dhw0-ZxgZ{D1#eJDmE zczyp7qb0f79??r8a@wpLJ1j4$>WXgpdro`%_2jopv_8)0xj+4uc+pBxt>R3PW1XdD zZw-9$v4mBd0${! zVYp<%yx)%lpZq^{6^K;nPwJjx%1UTxOA7*Y}Q@8s?PJfc1=AO zY;jxb@{P6jRaKwvo@@~hxnL5<@zHBfSy$MjUe0r7&azWXl_EBlYH4g1lP_C%R5oGq z$3JVDr>faEO>NKU{`RtEcfj4KitzboyB7KUf1SU7?V7I(BUWGa@!*}$pWk_0KhEZ_ zW5{lYf1LK=+05KW-14R+ZePXu_U4->KR?gR@LU_+u;)iz*V;KY7GIwJKemJYt@;`B zH`lzb{n=+?y>MwHf01vG^&`#A8>^h-LYgo6n#fE%x-GO+J1f&D#?>kMWGK~-@&u^;+_))r^6~GI;E4hyLs@7A8p$8`M08;*BzZB(R~Nj zJvzue;q1j%J}GM?i{Gb4=54>d$p3i6c0K9n>0cknyb8_={kS~g+u3uLcM41_rxqqW zPJ$`ZH!Q!PB!g6MdluafF?$bW9+F$dK>XTbP6`EHqy|%k{%QLpb z+|Z2wo91aTXgyo>dd)@ahbLCIIlJC9n&EEGtdlA*wdm2OU%P&^OkTg|#!bavPdbmB zy7|t2>f~0I`G(O7m!JF-J$^pqT*f7nN2^w^==>AMchE}JRK3V<>-0Z9_j*cYmvjG| znzriYHLLC2>qE*ol53jpb$5kb{$78Sp^szPR#~4DIyab0g;Ec;`?rZcoH|SU&@q`) z;+FGnHZmV`lMTLo>#dx?se^8dCVk}h^UcB)6$_+AAzVnwb=uS)t-1YUqTE!a{ zq3b*E25t|z|KQlY*{+sT)n4^ZoA=X4_V)5Tfo<#B=UIn$ZB>?ZaSqyi<;u2&Cq6P4 zsjN9N!Re2SY-1$f+ve{@{|$tySPfa2>NXp13jV6H|HY*lE|HmD1>1i0zG~QYZHbwu z(=vtN>755OEuV(5{JBu9_-N+i)jL|c{jMo1KkQh}+;b!S&SSxJy`*J7+KN2GpBZ-g zY1OTLKlklLmBcUodD*WlzwUeBS1hvhBE#*Q2f4Xr4g@UzvFf1Sf-U~d^jN2dID=A3^W7$lNh?Q@4?=7%j&8!Zl6^s&u};9aK} ztfMtu)1X#({;G+d`)+f+idg(y+2zRVlS;vdc-216akb-_XmER)o14t3Gy8rCwiLdc z*xvPFO-JG>=|^6>5-+Wis`)a1`Hgugb0$n&dnnrWNX$pW7p~8=o2720`RJ)TA8PC= ziN6)Jk-7aKlSj>-78@fYKFP2A68`=D`_C26{<}l`b;gYgUNdjlmml)Vc351a&-_D7 zcG?`@C$o;8US}jDT>M^{-Qc{pOUG&D7X6_9Xz%Pb-4cyYYT_oS?f(;SbaUa29a=t; zb`k}_LM3aqJn6cbDBG^Es(Y90gO^eam3Quy3iX~THZTo$y{KV&P^Rzrt>R$$zB`#| zk1vGfT{V#cO8GH zSpG0>5?RUIZJ22HwxjT4qlv@zT|1ah&6aT3JW=D~EN!lx=V#O}|Mg_=ou8BHt$Iwg z)1SX|IAVMET!FShZGp&l`6;q_ITjz5)X&VhbxS(H{nc!jLW?)WGhd3ms@U;ofwb&e zcHO(O_mWt5OV_4}WXmZ`Vsp@0;(5s4^o?!x(N5=;j*AZbHd$ob`+Do*K$SqwE$+5I zX8c-v>GHbmn|z8t&R~?fFYgJM*({C;#4iApW?0{t?v~cRIo+ybLRg zns{aTHAt4WfEGhDsX8ZNL;4z`nck&7PHBJf>XqbO>;}{h($CXR4|$Us$%!? zO**o>H+lc*+UeT8=*g;Xr=-UpzBO}g3W{pIu}iZ5d93{oxy_Y2FAlRK4~L1mZ_xSo zX&oakF9X951?+Q0nRzLx72vV3tC88omp#P(&Rg}TT`vDBgR_q6Gtutk zHr%~+iz|0!?$?N*>|N1if8Kw;Q+J|>qj4tx?yVxM*A~D3UHIAU;bP_Z{CJO zVXD@(|KD6attriO`OD+InX}~P%WoEczCM2A?~{qM=IxPu^PZP0d-n0nU2*Ftf8Fcy z(zWWJUTwLNtWfLk_LUo>(#%fg+Rb?L-tdoPbf&kUo`khNOZBoT8{d>9bBAsYFIu+q z-iF)n@*cgv$C-Zl-^0SfD-#owBXwt7ygAu%(vpAqW#8YOxfpTcXT!%!c9LK6H{Q1Y zSMf!7cJ3O3a<&}Z;%FPm9ywbnmqmM~bW63n&)-p zj~&e@+O{$@dC9@Efg#IYmQ?1mY>r=)EBbry)SH{`7{opIDNz0x9AoAceeC9!cd=o4 z@v@&iwp>X1x8(i0V;5DY^Qz4|Zt+w&?baHG^1QhmjXPDC&s3_-Fq!zktD$w`RGpn_ zVPC8Y-{14S;obc`Qjh11Mp0F!T7+tL>C)|%yy6vp5 zf9n(`W||%A(h8F8&U$3oAN)tI$^srU4j%?5h>aNjH zV)}cmz5VItpbax8e>(Y~<5F7A*OZ*koYLpj@~4RQAAgy{bTKjJkLuy(`KeiU(`P1o@uYt`zHOBXt3FyhGe26)^{#DGeTV$Z1f#F}HTHb}F11g9Jtx+q#qx$mT1(u-)gPvZ zK2U$n%EM56ZlREqi}a+zWdcf$j1sBW1D5zNKI+v~dL`X7Y3He^OYM`tmtS4Dmmj~M&b2f0_QJa+k2*!Cn=O6b?5Vg#;kC@0_kl-FNrmp_b@UF4 z;K)9ybF3)$p~rOnIU#)$k8QoNYWx1{W)~v5??*S@aQ?GQZ^ibf>vLDcG+xR)scR9k zQAmlij7cmk`dU_O@UC4k^En&2Cx~|F?0cZ{n)l&^Ad8+!fkh(SGR5KRt}J|UghmTI4V9OPG{dp9v;<{m$-nVG3q?xK!udJk<`qLXm*S%rWe<(DEaH5<)z^(?hk zdc-=4ifdm9S~_`6W5nMb{~l$Z%Stg?)Mc{t(Z88*XU&t|pJ$&L6_=K|<+O6y@8;cC z7xo&bCrsO8X}SOM$N$bbC#Ou^5Vf{7PU^T=s*(GxnIerG*Cij_-+OUmTJY5F{+R5} zGd5RW1sWCA9{X!k^7Gfl`TvWXbT{clURnG7{pXic?t1f0{%x0-^=eME&&Qo^H`5p& zdP+};{eD}vq*h_h&T|48k`6NGIGRsdPu$P&r$Y7hw@J32cFrm}zJJ*{k%PzU%VU2W zKAd7=BXhUh%yJrc=0)lI`zwF)m(9Lz?x;Lbzez{^`1#nJ^8rsj>1}vl@+f9vTR>us zOK%nTlA6%sLy?xw(>Kcg>%6-yEAZ5XnAEvbbNR})_X_x^bhj*&vENfaF*Z(3G(PCC z>ZHwK)8eZxLIW#@{zPpYi^hm$*KD-aN${H`*^ukXOv_pA`7DK3#m} z)2ByEel1_~>FN%7ReM_xxBC)59JY3Ewf`M;?Y#Z54f{V{kmvZl(s*OLP{WIv0+ts( ztl4@XVJgSAd5am1FI>pYRekqNxAAdb+m16Xk2ORloMDs=$q+8I3iWG}ZxWqR%#fRC z9m;s{Nz&}SjArGf2OC)ret!LCw{E2MEcO-ZB~E)6mb?mn8O!XFlbvwA{qmcGif2Ag zy7yMp@yYkYPcF=?RMV+{qqD?SG0WU*g5w-po=%?F=?A6OsEghGmaCPRU){_6G4$f< z?4{HHb03vsIl6DfrF1*D6}g@zb#mYS{t*>DzOvbhuj%dk+{s%OMo#v4;x*&fv{H2& zs~b$K{_fRa%W7O!xFl{1!>xJmD4abcYn7`UpZ%v`?eJs@=Z$atLM+3!=9A5>l?4wAQV*EbF%-RzdAofHOJiAp-=7LGbB;CNSG?B0H#NMYY+YyGMAIOq zAIs0RDE|^?x@a`{8`Ct7L%eEFG7?dcjHv8<^{3+9~!OtIHNU_A zQ1bT;!Mb<%f0^!kdT4?C8Cmo2?aHF{g33$g=cE*;i#>7GnA5hc_+s~z*KKoZPVboI z9;PcrSoNx*|)S?-%CY4(rSk6Vu~6y_5CD zxuCWuZ*`kE7A)A5?;X;+;=KzG z#67kz+tif3`_M-bOa3=8+irep@a6u)&cywtjkzbLCTz6T)wvGq*Zb4PLuiZ zH`hIU8f&)Y(voBQ?ygsuUBkP$Y*p0lpWDM-b{8>MUEf+Pk=$st(U9?;-0s&NFVBSL zPu?fAi;X#bi})VX-WK7wYcsoFmo8KiFIr)0T@~>8{R_p#uNTHIFg)@$U+Hu8@`lVg zx);Nqb)E-eymk zW-w<}veXZrJ=3Ni=7^HIp;s_F@4dj4*vai>HXg@{SMGlLV)x?v_ew8qemm$yXMgs|9DMSOv<{s`EzvrVavD8SGFDf^KbhO zzyDkd?}|zJZ`{6H_X{`6x^3Q0FYnHkKKJ$ZxrCx;>u+Q$$UL3)@J;Run>TCXyVfs# zns!d{j+M@oQ`Y@+xHhJ|ziZ?5@(0uTJcUQg94r@l7-cqem5 z$vunJ7uX{9lrm486J7Uk`XgO~xFr3x@^?yj|I0nrw0=GB+imT?3$0pCJqmEtFu9#y zdwhPaio^cjy>`nM9G_6PaMs_Rs`LvCnhYR4CnMYgl zc5rT&j-Ff}%eq4%ab4xwn+(fxPL#deE~}B@81v)ndvm!$>!%wG|9!V86)Hbk|62H4 z`LDc(X~#dTEL1zBby7KIlT%MG-|O1j+gBuHH(gKHpI?6XZ7Aoy^C6pmO6IP*nPFb} zrmrlgq@rTV0XZreSLGkM? z7M3n~`o{SDnR92(75tk1x_$N0<;SHvN`wwSZa=+!d-#JnRrij+UvKlis*rcT&bxbu z_}|TZe)o>`ad*EZrDh-ZoK1V2x37F@RCRaxz1_1{2Rr?Ec;@t0p~f<2S*y>Fl@FW` z;g&7_&HTWucZbldrHtFp@7;F5M8tpV8xyPb`!D-XT$8BmBztzwM}K=ufx?Y_U(Qs1 zUd*gC$MW=B$+~He{^a~IXOGai_VNs8#j2e}QgdQhjgOb^{j~qV*X;OHF}t%jF0!p+ z^Q-1%%fC10zwDp6&wgH*X}{Q?O=8w@_sbb~>iCpekI(H(=@Lp-PBc%+U9H!*AG#fp^FGUbQaZil(uD33+2Vvu4o|`CiAVp0luX%b;JrogPt+5sq>s|(2J4k36}3 z#7{^+;i^fyQr}Z?YW|Kxw)a0VcgRF2T{eBuF}*rbwJ@C9>gjARi?y;2kGh_}Fkt@3 zQ_-~i*>R&EZ{u69h%{gJxoE%s+OI{w?k~Fc*6V`y?(?Owi_M>CNAR`@Us=pO^^m9g zg`@83Zadhugo@Xk%!>?;QZv#?+86%2^yS5aa+Tln%7b+!=PuT}p4k271blRUrApSbmS@m{$Xoa@#mOt;is{N{?bf8wjsbIZF!$xtmTY*ohnr})x6rc)AzJdjg{xkPFJz# zLjR8xO?IBxJgwr=3H{@{l1jF04%k}C@b0qUW!`sg8+8uvdGUn(Ska-f2gQ$zW9}-* zwX2JX%bYiw+{7hOH+hv~P))1Tic11XYU(*F4DOuSE?LF6QQ~i$IOn9JCDAT>8fUN> zJ^4K0vEI??ECyfC2&ve7G*l0Fm6~8UWBuP)x66~fm}h;`((B)POYemL3hB;|F~;^{ zl_|y>Kl(MlDBk$%(qdgE_Jc-`|qcB4}WdnZhrdq@7t`RZ#MZP?{ya5SNAt7QEhV3 z-bbukpBz}Z-|8^;k7LVA|NhmSueU$lGwwJ)>)A^-d2gg|@?;q6eU!=+*FWvZ>+kNP zsr34Z3=jY9-}T$Ja_ueKWwU+9DTgJok4jzsZ`f(J=C38&3*Y4}a=UU~X;nprUR?Fg zq@p&@_o2LryU7uwcjv!v%Cf8f7kT0St&PX>_e!;%d$+bm+5FqX(5ak_tJd$I9DDY; zKwRv4os7S`c{=p(XQk%sZwxp3wzBl}uSIPoOH(dwSQ&NleO1siySa{)3%||_4S(}6 zZk^r}7U#WE4`tq+U6!QxH-6*u6DxPG|24<&{jTk&4Ig&#I$z!3V{2I7$(>boZIa@y z-$%55-H*6rawR>|)_Ku!_tN~Q;k$Uw8ec|5!IrowY=f1H}86|_pJapFa7))PDLB=s#Y{TLFOm?ES! zWzHp6=F79xXR0m9it8;8@LMCrHkCIbLD7H4rR7(5Tz5$g4~|;@-Sc|0Qj+Oo#opes zX(jx7n|3{qwq=xAqkPA_IHzyt7q9a(_ivXhKYsD;!jl);d$ilyIp3e29&F;X{ej%d z;%Tn;nxmGqrx~$AkF#oL=ko5a z^A2fFX`H$G<(KPRujP($ut{hwzByf`smr;!%}_Dp+JWx&m7j7WeKyCb?U;GKdWY$} z!!MThGMoL7cIdHQv&nMqCQbvckYycwQ7&7~R$HyPGs8p4&{V)V@N&27nq&Jq&h`W^ zoH;$~CEq5eRHNtb>cs0$IJI5#dk|-L@W=6qA6LGO-1~|3-N%c_wSBSlOl>umbU`_B z1_m1|1_l)@vwnH0<+{oFd1a|Z#hI`Z!RJQ*EtWn$@$cNwKk~}h1t#sXfAQ~h_4?{GdyP|;^G_Fg6qMWTir-&% z*LcURZM#4H`tsz-Oc% z*Y@V?|NJGq`PMD9UEf|F40p9S^0T=;-p1x}#M*rC^1o+lp7XV>m+skG?)zn-(R$gq z)irl!mS&v!EReMO$G;nS&ZVU*-zPSl-lFwq2hY)qI_9eb+Md0d&$IpW>9q0Y z(z?w@E9(DUzWK6K_v2)nj8hvp)31k5FWq#t`Ty}{AA+LpeqOw@saJZtobIZ!g?e{W z6TiP(8*5gUU0%redtU7R4b|~8(qC>~?Onb1La5E2y3nn@8oNSYr?#~l9X@-_J-8)w zd-GzShmTf$^cL?m?LC}d7d&%=+1qO~@22eBmVNl#wz|~QpDL<0P0HQ6@79bBe~zxb zl`(Cdtws3E_4fbo+*oC>YisMygAuFOWm?R?pC~=&W>MgB_1Gg<-YU*04L@nM*e^`h z*ZXzs*0*1IWA4S-huKe0{QB;?-j;X2R^@dx%|Ek?bNBYGK4t&@etf@a*7>wg|CXoz ze)8`rwy?Wm5)6e$iynWWU z|BsG!Z{7_qho-1CKdbKZaE8ERDkd&76AgS+}z^+XO z?CE@BVMlUG&K@g#ayNX=bm52f)=}#U&629N-uQO$>*qY?ga_;guY2D=vd!jPO6X1f z=JnFyRX#z)9qas(@!qqHBiHj{Kihnvq23NHI|R(RJb=d zC;wXYMbzhB1^ad$g+tP7nXlz|*RZZx*fceIdgJMe9`4Vpo;F;2FnRIH!v{@Y^G&{R zbm{FILd|QoP5r;M_)d^yLmBt>U*FNSswN0vtzk9&tra7<$hX+1A! zRIy0l7~_h%9BF@#gw0zwvur+4^Jxl8w!F=T=j-R{{=Id1-}W@d!ke3l3)vdD5?vmB z77A8&Rd~00s?V#Go6jyjx-Z7h`frBOwu(z;M_-;i@cG@|r;mEx`H2_v%)MEt*rUa; zcU!OPvgaWkbEmB-t1{wRw{_3LkS($|by|N~m54sG$#0z|k&w#MvFXxLi|ZXuVxBvf zPfJZcX!!QQ!RDjl-RvCiE(;5s|9;<2>e55`5BIn8pIi6;^TB$G;~#Lt+=ntN=08^qQJRc zPi>CkOP#~_dS_~{weB}Fczi}@x0u1LlBKzAH(RP5Ho2X4 zcE0>X^}3xe&4BlluQ|76`cr;e3B3%+!Ja&x;OE63vABY9hk*8T93H{|JOxGuc=W?p3(%hdL- zB^@8FHtW49R7r?9HQAG8*@P919ug;t){8jq`h3&n_LCDK*=~Z8@BW_Rls}{B#uXcx z@ap&liRDfmC*6`Xl90MS^5WqvPVjy>YfG@&o?#+&Dy5kJ}+zYJZYoVrq=O_WnLDA z?N1b}Dnz-=MSmx^?|ZhKv*7Ua$2v>4vVyQ^~KoSB^ijxUpgRiuJP_=FIGP@2)m)+1yE?Mph-FK6@Aba8JBv zaFM&{@@g-)2^Y9J4y}DCpsHgSw7#=5_L#EMDlfSuxxTGcW}o#R1QnK?Y;iWU$O-;= zQoVOi%TmEWjyWcW4*f|uz4a&e_h--QodXsxxNjY($sj+IInp=X!YyUB&4MElb9AbQ5CBKqIu)CD=UjF3w!fGm_RmW7I8xl!<{sl~fIB4sXr(Gq02n7iRQ*J}2H zlR>Tpr+k@9H$^qc1*@G%)>!v2(Km>5pFUhKBJ1U~WZ?s;vv)KmObfYogM<0C!%wjX@(D9d1tk)gCD*X7 zFle#3Id9$)kx7&K($}u?S8Ld)!;vbll09utfu79PWbXFOiwqp5sMNe`I??V~7xZJs z4prMPD}v^D921V&Sl(EBK%4XGndy)0%@@h&O}uR+sSBxtjfZv@0fY` z#GiP0aF)7!I^!O#cz8=x>3@x$4&^M%l$URhe000p(0PS7s5IMJf$2V@QrZTw9qG2g z3xD4;Dm~j$r?teA<>rb8DTi~3%QUXHT<~&tyRUF($Bxu<8baxgq4k1R85IlvX{^z& z(eIt+5U5out?xpT*)|Ec z%Gu3Rm=Ll>WLiM2Q?09g&rg4$j8%-AE*xk3Zs!%>wKc%2@w3=ewoPTPy^Gs#m!wFl zpZEUCn7-%cGu48bY@FfMS`PxFj@7Mb3cff;q$6Y%5BDEEt#jdloVw4;XNoE|WvQ-m zlFY0TOe@?NVZmlm`Z~=z>YQ4}_N<5tDIWiXJi{JL(OM>G{bZm2q(y;k3j2hnF6LS8 zq3>;MD8q97)!bXNlXrc8bZP3Q2Ma9owP)&l4=mWIba1tG;QeI_)qfSHH$B|ecq;5U z^Ye|iM&bKzR;d+unW^emq_P`0Pp-bc#Oz+i(t;g&r9nl4;?{1erGcBg*UOeX)_A?N zcE+WSGX3JZUCRAEM?YtrTB^EIEl6I5)k;!1FQ8XBxHItgH`Bj|%zkluE~{mpz3`jW zmO6cA-y;HhXH?x_PpEkPX5Q6V>#u3VZwR@n^vUD#v0TTOuNs+e8+jU=IWF*1Y1>e` zL?t})%yOBmI-W_4>Vnn$i`P65UHQqNd9~AK zPd}ORc*m-FmyVsicSN*&%?HUaXC*PKZ0VD0-_Ke7ztt@@wxja0!G-o&&ja`~Z>_#_ zBL7z3tboFGClf0o0u9_>e|z@CW`jV<(*NzJnzwPL>Q@vUJDcj_zrN%{vGiXpznXbh z<0frCqy6ObvD}8G&sO-#TRqnUD8+t$6MZCE&Zv!iPPwvMbhVfP0 z7OfXI+>mN%$^N$J-miPiy$z;E#a3FzaoC1>&COh@G$lo_S@WSuuJNavTgsNLU30g3 z<(2)5CV8*~c|=&)T0R$8DX7>SlM!_NgPe@|do_lKr9G4Gyr*>SF_44fBGuLs-#pQkn7yVZATo$}EBjWMu)!ye?e!cdsYSUyk zt+~42c}HM}SMQmtpFa5KPVHMH(sZg`Td;Du`su|li`}>u%UM5HI-fLu|1%?T*&`i0 zPTW|s{J@Njd{ME*dAY(b-t4{kJM8P)Ym4%deqHb0lX2B!`|&gF*_TWg7`e&v^GrFz z!fx4r<*ZmAyI8`ez+%74tMiMjuJPrr61BVGnSa!EzU2Lmdw)*Mx+FNm>`Sa-Y=6qT z61U086V|a?dqjT!m^qm#aLe;;H(z%8)#RIqi~7H+RER4&vrTEy<(3tk&cRRKF_q~Q zn#rg=`!{#)iCnMr%U3N=O}LeDvxD>UWt)8u1YgWZJhE=P%sd_yu5IrP_0F8WaG~Av zQkAIvE_=ZvQoooz;@TA2b+)r#`*$>V-h-S!8vB>d_cL2o8P98|=y7zymZ|nU^^2FT z-lTo3*^9ZK@zP53>u)Mp+TZ@LzH|KHFXx*_W=*kw`9m?+S>308n{doV2?kaP%ZL7L zSEpNwUpuk+NVHee>M70~WqOxZb}HQG&SLN9<71el7W^ilJ8G?CDnl(Nx8|0O=Rb4b zzV%X}h%M0C^xIlh#k0m{Z4Z9=dA+Q$TJ!$usgUnwOj&*7B;}k8u|9eBV=c;rlX8&67ewU&9_wtKU3thG+lI_v^E6YWu!aTiT)5 zqTnJXxYnq{Zq5odpw8~Y)cOH)>zs!^U>#s zo3a`$cYlX!mB;sa#bz2#o>>(4E^BFf;n`V#6lSHo_vn1Wy*BY{NeF|i9 zNgT{E_p=t%6gkXb^|h0)M_goCS%7(s1?z5^@0u6l%6Jt|uBuDh#4$MdH3=f5RM zM^2NIdGV2@WX65#zmij4TTWXm(_%9Fb;NncD);YEQ#Vg5J>fQ``tJ9h%Y2%0eM-BQ zsxMj_BYN=mM#(C*U29d-X6@Z7Jz?QSt(6Cjnj}hAzInrbjIAD==hkugqK* zDq#oMU-aG3dv?TQ|?1d;O5-;`)uomX(*-^n*-T1YRB3S?wPwx76i}=0VPO{~)ID zDsBD~FRxEX%x895lKyI4a_*dB$sq3lV<+v7u$5QWf06kq7_diR=9K<`E$J(pI8v6C zH)JG)tkCER(w}C&wo38)a%Z(}Pm?sJU znkF^7X=>S|x&l_CU9$79?Yq>?A!6}!R_MD-pMI&O6~`8TzcIVy+><@pl5;1lXp7qW z>c$zP$;lJ%+jQ=~dL-QHJa1;M3-77ove!O4<^7(7wMjsH`gwn zP5&|f*sT}p#wx6KMt@EJ|Nj!K7579U?q7BEcHi~Im+!y-_xQNod>-9!b$R=1N&nYv zwEuS?|8K6*arbv@d&O1>-f(-nvPYTd-GR!Xyu-9zFS86O1?WvKO84xpccg$=ak%V)LFC zi#{`?CO&1IzG%JcY3}FT*Nl~YXWjSdJmK|2@{-)j#T;i={#>#^|JvINKVNe<7j`zE zm=^5vPT{WY#O{F3dxE^V?Gj}^_b%~yoj0p>NLPIrw4;00j0`1-Uk}{g?#kLSCFaMS z8Y>UkyImUGrw&`o`8jxAx!2<~#Z~pRdso-v1^aH^S=^KSYDw0ihUr#$@^6yzm#w&x z{p`)!nOi2V+!1l^$wZU4`LU7N{MBPW$LJhoEee(UB;;V-&yY{Erlr5?kb@rjjF!}X3m(N=QqlRV-m+!PZ#?R(>l zq8&$-%p_KwSZcB%H+GYC*y3%mE8c!k+srr3%44M8#^3|>~@}99?R~tF7|%R z#wXlnhc~Y-@i-9`+c)!<-@G+3{!dk6PcDpE=>eMr8iqmlacWlV~$E06sP|6=T~!E(;}ZoQrD9HBGk_7$(3uyb{r z#u`z#tv-bM!@-FL_3a+BR7vFMn%b3F@7C0r)D&uM4#9zIOg_8@e z`M%KpwRW;|$ddMdn`$Oz=*hmC)$U}uJK)FHz^xlaezWEafBigTc7joC$dqGOZJ0J} zo7vI)@YMO(B}Y%Mv3>Dt%JSToPae*1vs>v9-?=gB*sqhiCJF&7o_`88sVxXGSSFU0 z_t^54{?f7`5WM%O`Y0D2^QbG>&<(Mv6dOvfC-6Qq0A4^uo z>sFLYXg^VZ$m)Aveh-It$JwV2ZqfGg8@GLHny~Hnk4cxqFJ8Kt%YOCz%6TXG&;4q$ zF#o^xMclXLQ;N9SBLrpmpI?@lc&c@O)LVPo>VI0ZinregP;_+o60ckN_wo7o|1Xm| z?p{7wd+wTz_uq#Xx99&_qnvl^82j|=+n-zJw8xuWIvqVDzlgak<~DEor|q|%FISJU`PjPMXUeAvurWPL@5uwcXPTWn$>o^=>9T0q_B_W!j}oI_A=j= z@V)bXJI6puo6obfEULxee#Y&~m%?2X8d!_ z$~s4l|Z}C6>Bb8yr+t}K)MK#jTU*0s=kGos*xoQ9A^I0D+ z$a8-_{`^`0|H5PM%T03EG`9Wx^XuUL+2VPs=7nbt|Nbuj=hzJn>&nyTzut4(US0L= z#lge&_EwJ_e!04>`Bd*P|LaCU4WIpK7MCSInak-*%Dz1QW$wlQtcYDTpz-zlkq`RX zSs54(3SvJ_4t;#Rq@rYQxNrU)Gl9L*ALfC$DehX4&a{P zurS)c&#EgnPEmgESmmX;<9Qe9* z(X}L*8826EFuZ*2fQn+LZsa9VPQ4`ECw2K}?`ge>^f8~kf90n=AOCjq?KJ#4;qS*e zmT`4<_HTK`HcHfOydt#wm^Qx?i)ZE{D+%E_T!ue<+-lAri|SxwtXR8rZqYqH#dXPx z%)aEzNOokuUXX2awS0oT-?flX{-^R%m(-V8){7-P66EIJuOk1oYw?A&%sJ2JZ9I0l zvT;uHC*M==Uq6t(!}oE*`#PmNCtFLiuHEFCW~~3qqpz~)_ZqiYowT&&HzuDo_gNJC zFs!z`SnZj_?@R9<7he?hPupj-_~$j_+csypU9I`$V-0%eoP8Jb=eA+pvQKuwU*Em{ zpgQOGZ|QmSk00Ouc+cENyj%R7E?S+5N+cNLhdoq9emSZ+gg4X)nPRc%7r1#c*jk~CuePVUc-8GY( zmD}!Tdaml8!LdL7jqRh-xKMtNs{9LV3-4UM@{z@OL&)CA6F)slV9I3K`p4ft?5JL1 z(59@Z^4FXyw=jj+vRvpB%G&z0(QTI{(@J#)<)8qgQvcVgUM>Z9&U}2e%~bUFejndy zufFA4s7rPnU8XLn$WX4fX{$=&|C+rEGEYhiSKlu>Dy=WSz@+#9?{lfG^@r8XoWEY1 zd;7oNpHvt39hcj9rUuG}+!m{4OzN)HUhNXHKDwyJS~>7ssLiQu%bO-lS~hFZlK2Oi z*_tMa+%<+i&bhi~hc$y$|IF%QG5WT{Zj!K3h2)>&8`F=bFOp;47x-YOQnuCF6Zs$Q zp7vO$UHv*OY4WCrJli(q|Bd2V_WV3k2E*Nk>9>m6C+aXo=B9l8@G&^x8%u}vtu;~J z`?gzMnfAM(_-OBuUdaW|n0?$IG%zjuz)~D>d|rS3^G$bowl~fx)%w!>a$>sb#UPb9 zb+4K=|2<|(PDt9%ZY}8PQU9z&-!eF7ZTh(uE8nY0n)B|w@F;(DUU%BJS=PIQ`2){9 zZrO3={280LWXYw`M+BCpid@jMIJPKKM`q)NK+QiN+fHcy7u*$@QDgi4dcf}98WkD# zNlk1!pW4c+n*F|W>)~=A-Fc6XM6g@6d5Y~L%P5P zv^z4*&+WGuCj&zWj#W|lWvN9u`HArTk#i%m^Kb7E`YWgKzwtG<$+u$@-z>TNwp4~W zcakgf7S9W%`J3klMJ>`@v}r}q6nTwb@xOw<^L$+-YrT7iV_bCTW z@~0YUi~o9eDp5oH>$1cv>-S$?Jm>t4pfgDUBdX5)Oi`l|7QDR|q?_3{taozKuyXy~r{OGdsOog%KQrl-uTkjZNtNXj_ zf4o_w^u*Gr#eWL}RIc4W+?-fqRW*6TYti}3Hy-$qDIE05#U#vUP0&=%WnS4zDVIOB z^qg$DyWV%nB)!urI%{tl1T2(jO}h1tr}p<;PC1ue*Qp!|DN1Qd2aW8+m$FWK@S93rcX|r_N?n5A2&lsrk`&3 z?c&UrPA50SWS38DekxUVP^>I=)zcrXtcK3###u7`!{vJ$NcgRMp ze{#&Rg%@%T2khSZ@y4q;=4mzi{kHU8c~Ed~R!Zc8poc0A*{2r!%>1@{jp^MDyOJ+v z?#;;O`Bt`CAnwSsKM#+dnX~!o;<-0i*ssaW<2-V2**WILCD+zy>PEJ2JD+EE;bcj{ z?#H+Of3Gh5c=lT@-?^hTP1UOy@7GQ^yY<`Qgb&%vy)K^PzVgSiEhmkU?f1=F&$Di; z@_FsoUp_1dUz^ePD|+?0vK(veHo05w6FZViTNZw_61^U!ZR;SjTe9e! zuK=T+fC`Jo%u<`OlamA5RuqeLE=$rESSDSxPxwmelXEXGfAhB4Q^l5?^i6vvYvr_q zjepP7t?uDriI8ZGs^t6s!l+}WcaWZU#Yy97SvC9ub2_&ySXgQ%vFe7QWzW-$O>Wc9 zsv9Xrr)UJ8>})>s^y9{6zlCC=Yo|9|lwb*XC*=Kh>zWHot}gqu#PadfgPB{Gozr>W zIsIMO_g8lgrDsJ&>6AY1Z2zB-v)jWvJM`m}XED!f*f093iaAa>k#D(a+54Lh&VMjG zm^j5XKvvGV?xHNm+yZ5BrO!8f4>9q*wR^p3>#0a3mm3l$UA|MCJ)`omo#UJ2A#j2VjkkU?4i>H#t`O$)%}SrlQo#X z?|&L(t<|XFrFeeDqz@`#ue2MzkEg|&omA8{@cymVq^mMt!Sy10U=O2z9}lAQEy^DX)Lvu>+R z(C2oa|MJ-h#d(V+y_}WGSgX{;z+R}!c)&$sMvej7z6Uc`UJy%u!hQP69Y!-zE!DaX zk#391g`s}hni7Y4J}iE~JLA%{%fee^qFtquX0F?H@=;D#Z*-DMOpaK<+G3^fQ_(YA zpHE>CTK8tMK*w`=Fa4d{RIZDtw1!MgzUy&ovr(d4cs*>|#czJuJa+Wxr2|DT_K zefs0syKUEBe~j=q*l9E7 ztZatZiPj4H9w~UOU+{7g$9>u99>1QQkSvUDvtIDI{O*n=Zn~S72RU7nyx?jv<=UNn zjd>Lw5f7*K>|%O-eY*Zc9@nyxl+G2L1)poDoe_Dfl`j0^j#$sSTg&|?z22TI4?mW2eY@)Y4G%1(}oc~^Ujl6#-K9W0l;(Z^KIuCEZmBp#hH_3GiJTBd@}S28su*$L*YF+cjr z*6s@9wW*O|rn6X`CO#;Y={64S33Lp-o)9`S=4La)Ch7IovD~aXFWtDkQ%>$Ci|*q! zjLXxU6NEnMT?vm_F*)ZS+sQlu%iXT$_z%oi%{|4U;CWcMq~J)`+Kax%PCCzX_Fhj? z44r3ro6|sdC96jHeNpCZyMNBV(w4FL7o+a&P2V-|7O04AOp38R8rsTzmdT z=)bs3^-=K`diQ)x`hVCYFIOn(zsqeq{abHu$>eP%FIVjfxnH#Fof+Fj(<9%EoMwhv zrR?Ot6?jE--+2=gNpW7@Ly6z!@-B9K>YS{rd5`I$aMRCR+nZwEOM`C2)t}DGeScc~ zor%IEjfox;ZrOJ1ds{a#`N|Q&=L_B{wO?};i`?cTQaEFaey(1ihf2z{$9AXn4lT=S z@-w)8#k*p+{I4;E_Iuhw0y7GrZs-ARIZ=dvhn$&m}T=# z6gWFGG@MvHPiHOr9{nr${Y_SfApNrC-yhm!>P|k8^zp&XyXgy0imzX{KCgafrS7Jz znccJb?f-oF=H;?{@x|lM!xvv%eLMWo@!Rw3h0eD>UwrX(`Nc0kJRYQP3YmIjN>=Hr zy47Frrk133d5K$9V;8j0t>Qd+r1^VG=`yjjm)Jaw94wzH@0@WkKKZEB^YgToHD z&U1HqRIEm@VnpyE~uj*2BmUbW2Ihh){s>p-G_43rv@>^Gy z27E8tdFpD4%JQVOEWP@nT1zxcZPjOo`_Jc^r(2?!XBL{qrPv)ZWoBe@#?+Ht%hZ;g z3*NYGSCGlxzRGg}H7!@ILno-N4l=#Ysy5S!(>Oi;d7^R3y(?i$PQ9}3`S|(%Ow*b1 zuWiJ4PMW5hm>DR!amxHF(*y-q``ptkd_LindD5b3mrIv%O?==VF*kbi5?x=n3d58Y zjPYf5tZA(=t4^P=IKpYt?`Kkb_YljO^UTk9w&w-NaKv){;oSc^wIOZNj1XVrsn64F z;v$x=imNwz)NW(;qpD_0$mxiiY5K`=D(8GZz1)5)B+KgH%EZ)iv78S-UKn49xLUYw z^2WzJ_U{$7PI*lUwUV1Y^=R0<0|&XS7BAW~d*6>Ub@S~aL&X2h+`*Hte?)#>-N!4x z%_NUrUT6C7yW$FoE%&VF@oO&lW?`vd_i2%jZSz`%%Q`2fow_Qd7`JP)@lJn* z$uZmieAwG3wEjR4?=27V9_A}>(meQs*DHB&bRKD$y zR-3Go@1nse;mntqcf)FB&)1E9W=WA+^Zhb5M#p6^%-?_Tc1-Cx z9W`CD`1;fAtD63O_NK35KTK;h{Mibe0#B)iJXfdXd~wrd=X@hnhJTK=I!t}ixeO%`|d{m%_NUK2{zt#L{ckk~mn zCu-3`zFj;kb-P@I_vy&}XgMLFv1{72O<|1@e!;%06V2yl=!Z;Nv1y7%P$I8w>!b;$ zvdf-%Z8$G4wVnHHz@FptQsQQXDb?;|+PBGR;_^uz+qgm`-M!M6PTurw!?h_r6?XIQ zraUSB*SPDg(kamwkq;J2lxtho1ql2+7{(J6wn%}evpd2vTk%!Mzhec`^YXqp*eu|D z_j^kkx4ZiK`NCZ1EdEx6SAYM@c>BqN8IC@G1X;9s_Np#r-E&8c!GH3FM`tycZ)(4E z0-ifR+Ep()PM`2@-@USxfqr+)dyZ?H zy$hP)A1;1Z*m}-Abtui0|?W9*taA6VY|Y@ETj?P8h5ukuBY z-TLj7S$>#1HSDdQxhyw*YxMoTeyh*z49kztTylDo+7h;=`wK;HeM`5wx3Jdc?SIjg zD<-QZ*yJsAT_$no;@x%KOWh`2F=+^W>Fn-$pyhwf#3Q1D!`l-y@~ho+-X3Rjmq?%Ci<{++NZ2_G6Yr=j(5eQWF(gUi7bB!^ki7)WhC8Wx4A8B@2Gt+|_cs zNx$KMPwb_uLgszvyx&cqIJ4WO{q=-pTe;XS%1oQJMPpjwTBYj4Qbl^g*SC0lyt7QD zU{&vl(j3pD49>e+e9=s}q;BJ< zvt_f>E(X7eGvztVdx>}DN9XdA=WlJ3PS2nIXhYTVT&JdYVp+Siy#CCcCbE-}KV@ZP z8GHB2CfRv?Yenb&*`6D1w}7=xqe|t?bc%KdGL&Fufcq(4)eA1BmZ2QKW&t^Rf z2;nl5kk&KXdumqB)5CAKsZHC@eg9C4(7hPBwoSbiDVM%~SlG|?@y#LM1<#*USaRok zUNu*mAb&4d)vEg28_Co5LIro1-mZI9oLzMLhBB9Q^0%p9i=J&Yo!Q8@<9&J9zlXnm z{eAo9+4S4;>+hef+gJDX;qvR7x4*x4@7uFuM=pJvU6xlKss6L+m0(_le$jr<1NJ|P zZ`_;L!6ebFrx2s?lX3M@4*9!A2jeQPaw*yr1?>3D!17k!L|mao=q3N3i%y=KmMgwV z_PMp{Wz2qA9T)H9pL5FD?l!wr+`4^L?7OqwZ)2PNTUThF;R#q6P{#R#3sFSZ>R3QLuE$w;R&O zAN~Gk(Q?_A^^)RExBHA0(YqV+WESYhJz#Arc%Pg8J&%XK%7d5v>6JTs3ci-qH|QOG zsXXpnT=Gfhvu%5{R4Nwmpb5sl{TopW<eb-<_@>)nH+Mkd7JOuXwe2a z`Hc-{zY0yVPE}|!=q_Zd371)1xvk{jo|uCHYl?X#uP=7&?)j6#E|jXhlKT>y&Bg7r zGR{Q=UNGPH_@ahpXLR{4iB(&cy^nFfajAOB$Bv*Y6z0>p`;*Yrgr+?IsJ83<)Yq~;)0`XM#`mfhiyab*93Xq-S$ILv9vG7$3Uq1 zA2*_(^Gt4%*13)_QAQpH23r*d25Bt)oPx~cZ0NP$N27A{pKKEZZKiE3Z9H=9ZRYuX z3p{J>n8lBK>YeQ_EEL!h&$G_u?I!h3F3-33o?ZVwQ}OGz-9>X4JiEVTy$?G4@Qm?! z8|R;|^5g#$6#sv}J9^`%RK<67zy93bZvN=W&zgUqPtX4Or~9}5k?Y^@*J|5&#+`Y- z{r-Fz`MGQMtk-}3`E1(coH(^(de6VVfA&5vf8OL)|F|=Aw_APne71S=>&J^9FVc%-yZqYvOQ*SBhdiB{Yk%j(ne}n=V`_fA?2ORd z8*}hd`u`5U^>0l7R{z^^|Hr(r@c8;m*}-QY zOfr5{n`(CTPkzLN zXoa5h+%0;KL;bqf2`%9;%ltJ$bxU2c3O=2>%=}|r=}GA~x<#=oT>b<+T)AtT+cIsV z$KeM3@#3vond&uLHr`5}xMJzH6pj25on?`ykVMo4?@D!!PEoCF`~xi@e;|v&41s zL(3%{YvVjOZqll^UGpv8ckPaQfezRI|9trFTb5p7k5BMXeW|Wor{$MqW?s`&pQBf* zn9Cq)wxlOwYtDTlr2DRYK5(>j`dV4NiraFcIRyvL@A){#Lg8AM6Js!A z;o|n>F!sV#*Oo;XSFH)kohlP~G5+8r|F;kVoZnaatD_LcjrtT_=yHwf9eJpRKn3|&Ul)Vo!&A2%QK9;8lziDE% zoWIt1=cFTz!G4_uvs&I5_#Jw`C`V>vdw$MU;}!V~>4mFiKKIfR);r^+ynCYHi9QjZ zztg8PvQMA>=T4+hpLG#mnUZ=@;}K@lP@79R{hBkGo8>PRxgE@3s8hIV*^^QS-kA^6 zEi*PW+%VTPdz2*JbUL&b4P&N$qrHP%`8)=QeIREs5QnvF)G#Iw+A`(eRL zMN3+_UudOny{l{eR6yv(^{wYtbOkwII#Zsc$7LfXQ?O{Vy>!|R0p9jb*XL5{j5!P3 z!v(H0RI5%~6(q(~bt>bDXYj&XVk!dcnhB6jHQ0E|Eo>k^9*&C*vsd=@osu zPx7AcRXcsC`S)Bs1-Ea1^EReB1?^Osl|6Oe&GfH^?PWWXYRf;riHzqGV@~jXu=tEY zK)A`1X{%y1#9VE%K26JAv1{4&#l5%VC9;C2nu<++Y`e^e(9}`~%Sx2eNDB?d{Ymh3uC^*#E z!9&=?H!1A<*(IB|U*6AjNO7G-qSK!2fRjsiZM}BGdqI9zn;-x0!^;ldNx#zAbd~RD z#$=HRAw~>gUGMd_WXmpM)hIq2^Bo2eH3tFJK(>jJ$3k{0m_5FC zXhp%+l{4l`R;UH}fiiD{=vR1n8v_E|BKRc6s4^HIXi1EJrNIT&ZxM<@JqPxy3((w+l05g6W*fpYS(7(w0k;B z`@(D3{VleL-@0>UVU+vx+z+oK8V)Zrd?%spz+{-GwVA=vw12CBk;yBidWKupXX+X5 zZeCs@oc7<*`DQ6AQ@CE>?!%l(+ZRsgE%g6sEOn~ITiEvLyp0~)v#kHdlq*^G?0vz< z!LzHmOncUXMK*KRy|_Qe(WPL+)=N_lIc!qj~69sd;Ps(YZR)w&@jL=xqttbpRzvh>;7kVzSDmZ z8{F{to2VG$)x)j)%l$+v^PM~Pf8OR8KVg}q{flG#=ML??`uP0zi!a=M9E`|TZOh20 z`=}QE`ry)%3`O0$`y!?9#(ne=IL{XsYU6g7^}$jWoZ*!j>y}M< zlW?%gcapMS$=SLBcd^*o9;vmzmMU6yOybiwnCCX(>V~Xa;fW7JJ<78M-+Rou%W%JL zf{XuO-GjETLr(Jc=e>I=%fFZ5VeikZS#hpADtFAAxB5eky<6g?_?f*6{!d)gU6gdD z_T#%pPfNf5Q}&GV{=DIfjpyrME$@ZcGk%-#T%vPcH7Iy23KnEh_|0V_@r}3>+UrPX%d#Z6uWLE3y5!*pYgE!&WQ?m*PgGktF3G7{?7rB})bx~@uc4?pv(%+z`}6LebB`sS zd66(LdDlM;)34vA?l`!ATKd-VO(%|?@BDEp=}FM}|5q1?c$#!}i|d~gE?l0oQr5qM zL(A62+OBEe^4lwYp08jldC?Ra{{5V_l7ew&g8iR8TPD4aiZ0bZ#Or-)C*$;sGdVAN zMWspXV>UB=wm(A7xq9wg;YqJ<%`KU{Gy!TtwJWd9NJ~8a~`xNA7=9Q!tL9Wp_3R-en>}Kl4fTa3=GU!=|4$thie_&(iqt$#QY? z=bQVtPgmNOsg!qr{@63bK=<0S{Y?pb z<9@$>zE3mk;G5hJ-#*pMSJ`91;T8Sj!mo+FdtMeOd@$a4OKsIZg(GV(&J1;pte5<< zf3C}~b+#6r^SAE5>^^thktlaFyN`VJe=Z7dytMkpybAsL4=sIudw%|9tb6wB=D~;G z=S}F0OI43s;W6|2NzLvLM?U{O@RxJGU93cKRQ=NFCCBG+tpD%R6SuGC+vJFxHCp9+ zUv7JwVtd;{#^=%Dmo8mC%U&Hh&Ar(pf*h zeb$65gX-m6WOb>}H3fQJ)R1+hnCVEgftk)SCG+C-m2&RU)^zW&cscUIecfhnSwQaYpdUo%)+<76Te3e3fYAWyYo*w(A6QeoqYw z=4#H!EmBo`^6bh=?&QcfzD#w8zHR;{WBK$8AA96fmERRpUinKQ&w^IXDsA;Z~4y-6={Ys~z&e6tFUo?rgFpdwjI@qJI9j9HB9oJIHM?N0vr<*b`d zsiWZ)t&k_{dft_+kT`$ySPGX<^A2x6g(SZ3ygG{h;y+k-Nb}j%MrG|#JsOqw{+Vg0!? zGo0V<%bFKB^+aw*&&>%UZOpPl$E*Yv9xMEGSzY?|nqE7m*m%7M0svqFAc zQt6DG?k@AxHR;g#`mhC4Ub1M+++_3P&#f7@8)e?gbt^D%eBmnajI!Jt?0=*v?zQaO zuK%WjHy`h=7tH@<$1ox9*~-pUEQ_m%zI)s=AG9c3 zx~gTpy+vwd{wD+B@c)Un;kct-Yf)|K?;h>GE~Q z?o7XSrg-1An%y@xFp88kT`E&+XWr+t)cwfp#>6YO7Q0=Z+*u65 zSo1G(&^axrA;1#O_8t<>je%%=7 zujw04qZ(aM6#miRRFM4&d=WSJnqi@bt(TYDwuaAkvKDyFs+6`F-Q1+W*lcyE;KGfKbJwjqbxlZ?MeKT9u(kB6-=}@P-M@K${<`Ps z)Bo??HE;g?nEzEjzugs;i`idQ{PW$nt3Oq*8gi%2ifmnI@umLPJ$sSvtfQey+`*}W zqHo?lYm5FqFJrFk*9b-Tnb$uD#J;(^aqk^Nx7e6P<-Gze+YY~ceWRJ>@7DvJr(buw z$NpgQw$Qk$;m9HQX=04h>njJ!WCM3-6&fFkFbLjq)Il)w_gCfz7dP5fO_U4W=J{7i zvQRjaqiL5wl$8cU>8eS*<=+HCTE6tX2;B7`(fzH6$(k=W7UV59S^H+w)vA}r<{sC1 zKFvvS#q!lYJNfQq%O)i3y~D@0{msJznNsG8OEM?)TfUj-IPpvvmw@BTxZ1hUa+CDNL^HPA z?`Mhqxg9F@r>?oLUYk2-XI?j>e$3L$)R}B)2^%-rr+&Y!-M?mITvn5uCv&r+&U?h~jabNPl6E=m(k+vqf2Y*XKCVi=AzOT*U`1Xt2a|@0 zvB^>6dZ$lbJ7+Fy**5RyTA}N~nI%j9ZZKi}UKXA3!SPUVlfY!}@~NKFO(%Wd`_0Ef zC;0*2&vN1O;_T^h`qPv-mQFKwcX;;wzmaS9qK9Q2%lvm#_#ZYo`S5jV?WN`U^Hy2D zHor1|)uJQ&K1+Z4_PhBAW8un^0u{n-9D@H(&0ct#Yhq%PP_My)fP&rPYPUYE<5PVDCnazZU0LnnFMu18Ku9^&i8T6%Il#X`i2bJ+Bm`F z+`5;wv1#V--ZD-Wl@Kg$^4l4B=?U|^RVERk>bLT&GE3VJ?}>V{Y{}Ehw)goy{f63-Zx-uGwveyQBzhcu#L*IxNwt2}w~xpsC2hEhQW1{o|v!bO?M8OgZ? z;IrzdM%>Q3?IBbvzMy`^3&jbEGq=n=sJ8kBlTnxPM?W<~ne%MFRkoZkx+*>CY>D~W z4E_K6mhW0Q`)!J_vqHtnb?dB3UtO}R{`BkcmuK?f;#)q1dWP5k`}MBKt9h}>-!D0{ zmaWf^yL@}L{k@C&CktoA?UDad-Q4>9tcCCN)2W+krb$FEF~9!u>(MVBCVz_NSml>K zn|$Yav*-Tn@8?#&^_~~=I>#|M*z{CZdRFQJ(quyO7H$R9}4n% zK6@_A-)MVszSiHL3E!D{|QW^f7QBF<4>#GV)t(k z>D#yEmhsL71`9LQ=gr*KqWC)2w&kXfE z#@2Xvvc^SQxw&h^I}BfoZvDu4S7*oO&9`~-PinoDU}Na-k=Czp2sT-8KiJejJcPF- zat4Fr9}|s$2S5F$>Z18AdGy)S#PzAAl3~dij{S>TpWgmlDrDm5`N${R z*e!$GFY8<8;oixoFMfRa@w3aPB!iv1b|~4*U7A(Iz`g73b;ffEDY?@OL{=^+J`lR@ zL__S-K#sjlg=z|3{@(wKMAkiDT=zaxa2{9XqR*ctW~x6=k=o{UpwM$cF7vg0jDAxa z-7Tw^dW)?(^i1nSA!UiGi_`=u;T)Vw!ei@KoPD)DZv`P6^m z7i0xrd{^V(VRX+*h@-tvPRI;SqCmzt`19|J&F9#JVtzBcJ@+Vyt5=}Ed8wc%VsRoT;c{<}Gf3EbRv@4)5vXDb)JGtuFRcB#=&D3qU* z8)2Wx@}aJCj(1zZnH}$sX}xPnnSPehLo;UX`fFUwuROk#w#@mr>+sdJv+D9S*5w&= zZD>Dpv(oN-*U$iC&h)8#}$+9y%)A?q|f`DYmwVxBU1Zws*thqNm5<~Kx8Ez(c#ks`$j`o@ykX(o zuD*_}C)<^3Tn}b@r#eq|XUJQU#^uVi+~@4YsFf13iTh60ule`IV^z*&o~Y?zro3hM zMQ-1yFj#yMTXm=I7ix;?V-u?{{X^Ft9~#Oy+s@Db4(8Iipr!;VF*ZuD|oH zIs25#Wp1^h+~8)3vFB6v`KekB zhrH@VbMsYnVrNUtKiKFwC-bm~jok4(8@cw0NoM(_GmA3>W}b}95;t8v^A5ji$>tkV z+)O5fH#bk8^m@@+VK0H+hqY%Hv!Nb%b7+LL)3*v{?} zX1W`7Z0TC#{WDYB?%oJn=Tyk8%RMK1%|RKd*OOEx%XlZL)*d)e-I4TX^7h}$c$nEW z0t8PRZoXGt=O4@Zy5hwZ%D>5t5+o4k`wm`InD7h7zZ{8#sP@OHkK+7DMM)Z0DG z0#;~=ymDf+{dITx{k;|6znkkHz5agRU$;F!|8?ib?G>2&`QeB5bp5u&`uA&3^4Hl{ z=-hi67`7tlrH)to;pywGuk*`u{E(iy%4g|Mr6aeO_JmI9%1^bt-r2FqrDpq-%8*wv zdt!B`Tj~4mPrOk$Wkoc5vPu0TyT{>MXLN4$I`uR3`Ahl#Hw24UrhWdj>hn)|D<{?P zxgYN)|Bzm--ao(Ynqc6nw40&n3n!^el?{CIaq5Q)R?P<|{Fk<`GP$@*gWcHlXdHvV zAI}o||9?)-KavuBYSHzbd6%9hZWHcMVQcAm=I^{{-|neD*G_u9U~Ro!RGaU9g(>%P z5+3-7*tjrqEO+vEwVb|4gK@5g{}BzL&oO@MnTnpL?%X56cm4I(1Wy4rtNFabviy%j z=bc_7x1uQSF;xH)Bxo2z0-TgTB& z0?Io%9-Q1Ap?CVCK%L0q2=z}@Hho`{W}e#pvBG3Yyi57QVoe4yA&w2)b47E%)TYcU zU8inzHT%eFbAk0nf~uUJ+3_oajs&XJ#jX6Ic6Wk@lRT^Z)4M_9Mhi-op30cy_3_a~ zWy9E1Lne(C?PkS1_qn{6{mxam$2cu`E)$#9?8=71kW(|yiGE;swyJlc5|fdvvc8<1 z#M+<-S2aSfPrG%_-FW6f4+G73hI<<;Hfnk84cPC}Ar};rKYy*5QF!6=U#9g1LQz|` z>ODEH&H34c&FXk}#!eO?hX-fZyZqh$XLZE0T~{{xML#@~5_zg7=7Rm)*UwXDu0FYH z$|L)i;?EvO|I7Ks-x=|P;Shhr1m*C#wO3{>b^80q$*`D7;@&EjpIQyv!ZX`@zE8Gj zy=tZSp^!sP+FeY^^P@w}^o18XIL|x^VR&K@?wz%o%UVi@L1dq|qtoe4F;+X9jk&(9>ePo#TYG1;x39g%bt-M=xm3N0mdq*K%`&Q)8(z72N@|H3&Wh$vdcQ?daKX!#S3@6YrQauYfJbAZi_W_6SpL+=1Nf5$5eKD zcTf}S##fBXG%l-l{A<~-cEP6Q#OIslQce{|epnmWPYj;A@e`+YSVzpW3u6DoW*hpe zm%N(Pw|_?hUwq7w4aZK`h&Ctmur(hn-F{t~cjaTV4R@UmEtrs zc&_+k*hBtDs`di+#dowhmEKFN4ZZli-7iGx^5f?(S!eJj+^o`z-2BUPXRQackZ-`=~~&yR`kxi(D?!EY@r;=3iIFdVFwPb9J%f zISKn&dk%iIIrG%WzOgf**kP?}LPhbMz!oL$?T41{jALjIwNbbE`eeR>X4>8Mgrb)! z{5z^`K3({FuP}W}V$>W>7vG&N%T%}6F`nGwJM&8`+qoyaA^a?w?`4<#`FYPV?R)>z zH~%Uvt=YV%Ecq|+XuXD#{(%#&JDIMZ-eG)HLFWC|nBQ0R=kd)8nYWMi>&q)@Kh!^0 zY&415%(lnC?5uL3L@dLHibMApoj%E25u902a%K(xkN-V?ZM2@Lzb=c}u%bNg$+1^* ze>4MKJg4OMNVlxZonK>gVbcXg7SqU;TWs1nx9|vb1c}?c-d?=dOE^IKsTR9>v`uxD z9V5H+m*zQ*o40CtWH$86w0_vIeMj%5sdxIiUu1pSa-q}hwxMX6)J-oDE0&BiM>Ssu zrSCrxBY*zhjGL>MEevD75|;6DLIUHeJzG-Bo+g+bP-V!9_jR^NNb~Oe_aN-ab}rKd zfd{&~7T?w|U-5YPMVGVd>Ra4D@Y^=MJe$t?!{p%S`9Caq&aqsxZMwi;@qb>YopmzP zT9X(f@dd2P-#;{#A78Ulo#kD{1HAWuNvX zx8RPDG_Nq9#*f#lS4MaX?29(4$UP_Rw@7`WG3xb;?c zCZ?{+Q~B<=^-;q&N3{#vR$XfCGGjW(aXj(#KarnpwZ|4t=n?pR{!HikE!*C3HA$P@ z7Zb7&+Aa_}@q6Ng9Sr9)O*~6$K7aO_ejwmWhP<7|sV9#P-S`*O|1((pn81^s8m1dD zU78-p*YnK2m7T}-Uw?6{hTd7_kDgI+kNzLI@+akrlVQWMyK;YiO-|hNa zwrj%dF4Ii00?X@`EwdFSABhv$th?pP--?u55~1Nr#V*_{exQ6}sMO9%Vbia9koI?T=2@uI4G%KeRqyH));Y-ls>oKP#L&m}-`tSl z$s9+{_N94^e|Jon!S_S+#Os#q{j)rbH&;EjFl{7HqZJ8Xm|=g!iM@Osbi zyXV@5$%ec67KKcmZ4kmtWtz9DgSLHp! z^%ok8>xJife#&LlTQenS9(SLL&XVu%OY6$q;@GNAPb+`0H)ZK8Eg$yjRca^mU%Ba} zbDd#5xLI!otJt?q%e1a7DC}N(PDo}+qLRh_S2~K?7SnxhW!?WKy)EvykZsnf+5E>1 zVjsmX`e}V8=Jk7n>b z-`n zlY5p2BzHxNb-F^wr#GFiR@}17vgzZg`4zTiy}j?YU)Yo1WgL>t z633&H%Tc+#>f`q%I={b$202PvACCE<`gu05^rr=euli=Ls|eOUvu5$+FrD?6hk%b$&KifraFzRKH=JGFV!hI0|ICZ?6pofJ$=rKhK6~cz3rF++-HJc6 z?bT;VorZnV`>*OR|C+2Ua8}8)Um{asp0V=-tVuDUkg~$6}<6s%&#BI z6v``iFWi*Rd7zR$Uq=BKTB*>u0v6Jx#H4fcUT85hNFc6h}wq(1y}Aj{DA#nM2t zDS!GJR_@^3aP6n>LC>_3yG=nd2R^G^&MrB;qajW5=q5ke^(@mBh3}^>y1>2eOn|1F z;GB8?zrC&B{~}ST+;LvY4%^u$C64gLx+pMTlUcz~)+xlPeSOBY)O7`RTa@c&`@b-F zx>c+0>ke)=vARPCD|tAo?-oZ~ud3boR`Sf_KAqRo_H>+m_a|Zbn^Ie4^?jx@w<;JW zNyvCT);@imhE*cPnXKfnE34^*NoTY#xv~8_-(}%gFVi@Op}v%>L(w5 zUMH3#kahW=*=p&OQ*ZS8zpg&v)HD8TMG2lJe!wUTCs z*YBy-z1a2OXiLkFyE>cgTlZF&?%cXLwl%7*EjqMxqU+tGZ8yCl&rMd{wPkt3YVOdG z;{t6GB~|Uu`8(Ild7{9u&)oLM+WY54;-24{!gYQAyHnF6E#xQYN$=FXetuP2ZFBJArHQ5BCSp zPg^jB-_$bG(My>tzQ9BJpsM9_R`ybf&&uVCE6xduyt*2Cug{R08p>?BLF~iD&>hm;2FoLMT#%lyO*iGm%aE_l z?a#|~79SE3_W#qTtMfFvb*AlRbL))tf*flWaIfkWI%1NUGIcGtsm{IKcW3$6Xq2dK z%e=bRO8t)dhTmHr)ZUa;4K1=cJLhBKWxFdPzaFq@y0vrf;;L}YCgBng0&2* zUfg87buY)LU~T*9mZ&)wb7Yt96lHz8V8_S9c}LIwU%7^1{Ect_sS;O>R&tzW>TolB!kB(zrP=ZZJ?1ql7)=#6OO!OPd?|jg z?$9izlSO%^{rVCcE--H}JAEWG%W8SxrNGXh;zxmDTO^Jpib=gQS3EUi%FGG#IlW(m z-M=xj>rs)YiUwnTjKh>uO=8Ath50)pqdK`NCUaj1GF;ZGz!$qfb?L)|j61tm>{ur@ z!}_>k!M;mnXG30mnYKxzrjLQ=)uCt+9VZp$mV?EM3@gv=n-vq&-*m}p+a$+DH?Byt z?BB4#!G7|?@1d-oa-zpdsykR`PF-olDR)IWV;Qq`uD047kJtq>MgF_Q-H_SZ{+zYH zNBIUb*XID?>o-qE?#~K!d=X!g4ZU5)F7&d2fAC;L6)wJB}Q2ELXj5u|3!9?xzs77|kcE zRBAY$%LqKbGvkm;ykvOi?d2xPQ|2x#PB~Zq(Q&5!+Q_L5rcy<_t@m*GPIw)yD1R{c zh}gU62_@HG^8ewrF1MR;J599BInKO`e`1BX(6m>KF`2JkZakWOX4dlE*Uw4HS%rGc zez>62Yd!nNN|VM?J}!w6L(j-3d@?87_>#6Q{FPX@SwZNwRdTb$F_FG?20?7sn0!Mv zW;}e9xNMn7@?O=pw=1ui$D9^;!?w#fXOVaO$*k)7xnD1bh^6LdGsOD3P1m;hdB`OC z-nGwHCzWX?XBx>w%UiQQX)wH(vu|;3n?G;B|GSPK?Pc$l_OrLBi*f7hWU!m1r0a6A zsz1fFfSr%mY}dX?xxoi_9XM3zZrt%UBrN8KgIr;@7<-##nSPvz@P_xVb$GJk&ungd z*Qu3t`Pi03&-3S8Gv>xF&hNE#YwkSQl@~j)Y1i*F!g}&={J**CKUp{R=Lg5FtiL0s zTD}PvJF`!6b(n{VX^Hs>B{L5rgIT-S)=r-})obtMxmzZrF)vyA^{A^hKaYTL;zr8` z&5kp29jh(2zgp(Xo3O&+Y015PJcstko><1X>0s|3HHMHdx9I|s?V2rCnpebSBnrF$iLKgwH8yRf~__UNWY`@~=+wW{=W z8n54q-EMd!+1%>)LgJvlg_C^q`J}B3_tTQgq?GK=Xik?NemTt&?6rdj2@T?^DrvzroWb4&t*BGYgl~Re_hn3ncMRCoNPOs&iNlY?tE$THC|Kg>)}b^eyk7Pq+3~= z|2|yttGO?D_sat>HpGAYsPrNGl+je30}_%>E2i#83OMrya4= z`EDxZGy7WdnK}BbCGM36wKTMR(wBSpe3&UzHQBUtLz<{}(rM$qS(VR^n#s-hlMtYE z;KG{cDSvFfU0CJWBsy2A&+GmCEef&6&j~h8Wi;74=I zmMnE^Ut_>O>5ChZ^JK4-Wb~Y3@Ruz4y)QDi?c19VB3rl*2YF0th(B9?fRkIppt)Lm zd;13V?pnDMweMK}fA}ZLz}TXD=EJ>$3-h*Q?O5KJxSiL3LxzQi9bZKFmN|bd>wdqu zkX@*8Hl8tUbz1X;ZI!iW_TK3a-hI9G!@dt*8V9P5unQbK8+E`Xw)D=mEjJqt7_5}0 zW$toWZ!|l$)b6!|$DHOLv8D4$bTo?PFHJt)Z_igKIkmDwvc~^StA}CMj6F>|7HnSD z)_U!_==w&l5+47S&qf;T)^Z*d9`1X*{8%4O6u7^bzq4-MciY^D+)nbopQJbh-*g>6 z{dC5qYvCbZEz%?(E?9btn^#fnb}e(i&(^u6GSO`xE?A1kv7Y~Z{q2YUUFW~?KL}>B z;IO*A)$qgeea&4u>zVFq2A3`i?*BNW%={PA6}H+ehgIgMR;6iM5xc{{7gOcH?r+ewju;@mO_NLq|RF2W*W?-6=#B{&6ECWH!Vc&lcN1peq%eKS}yrd zmwzU>@8!2^D9@HX`-VkXRD?^`z3z&|?;Wd~m(M-6oBz=Jl01&({>O#>^#^zCyZlqr z<^SV2j7Z@zCTE4Sd}=KJ?_1re{UP6+96##y4yQBz*gn1^Qn+nqcd{ zL|5%e(gtVG);M>*?3I5fNQ4JoycsC+-@nvLeN~LM)$+u5W;Rn2;n6DRb1#-FHo?VQtC0?Wxd+UJ>sVhYwPg8Y`orfZG~C+ zR5^dM5}T|i)2jUrYx@bVJY56p+li%)HU#bY%J2~&x`|IZ46DLo*Tgof& zf9ta!Qki=%PB7cKUfPtweNWnvJcj(el3OliCvxZI>Q6j%Ni^?6u5rXachUHY>{yxC zHV3Wybaw>JzSO$eso|bsIhVql4!(Uqep}^g_WwROCvMY(4OOf$6X%@LxNB=^HM!M3 zvAaAh?EKfA2Tz|BNaMw4~@80WO!L`n;W}isE+{(ApR~*QxoBr^i z>>7E!pD7b}>mA{974-@E?a+Q`k(>8%@mZ*H#mbI` z`{qfyFC(<(FH=p~Qv33pwvCaTYODUKbt3Y&ii9It7G=Ah@hW@hCGm07gbcN2=^Gwm zt2%z&j+SYVBia+Xi$b`AMdx8otrFI*3`v#t3jV)Y!c=pcK z$0vH}-I{Y@cjJegq>#1jYxg`l_1*eeP~7Q9r`GPV;g?IexGYSo{HxH(5dM7i`*R*o z*m;##Zcezzwi{cPvfVtXIN#@R=8F4=9xH~ew|%tw&|6uVcNwL{x7*IMUtPI&-*gWB zdrux6jal|dEZfn)er|;HW?PZtM*iIKq93~Q=IeaClFD-W`kc$hOvGEtiVk*OJXH6Q z;ib?T|XW3FjXY&>c`i|4;lFsSg!s2{ga;D{!>Dg-;K`SU8S^c zm#Ng1r!9N`DVg`$xwRxj?tcCCV$3O~>ncKtd>bk|mMzJ<-O9FX!PV(oEQL31TfWv= zm+|r9_lL^&t&V@P;|=@w{mIh~B~(9jTb=PTs`tIwj74lAdzSVmoYkM$_b|Xlym+Qw z^W%Geq&Os(dazuL_DqpmyD(!Yqqi&IZ|AJ+bQ$GEuq!;Q$@sW)^Kq~kX{%ntb2+NhXy%=_=v^4jK4hIQKB zcD~ovcKJTO5uM|g`}F8h*Oj?f#rit8&KAq~t0H6AG&3RZ+_A5hw#NR;^~!IY8vp5` z)2{t1AAAqFdj3iDWrkBK>ta?uE>UtkwDQh2x1D~o?)^Gq&(rclUuSLai7m!^?Bw3K zIXv8&t0OwG;=f$~$2oIvIz7{1&lfs-L}}MTVFMSo_@)D2CvT~!IOcqCi6y&EVVd~e zu+9hCtlQ2NuJsQNI>5Wg*u5dhDLD1UK3BU+iwWx&tX!LFcf9q8>zV0wmmI1h+$Vop z5qFiXia-8mQr4x!nYXS!6iCb4?-0h=I8C_y!vQ&g%nz5<7V)%i_}qWtpZWt9+g&`Y zeEJpl+V_2)`CX_%U&wk!gY4vr^_SiMGR7(H_6~n>Z^yek$vw9w{p?f>e7djrdPmpR z+Qp0YY}S`5^RaGGZho;QMawu?H12hxIM3Fi>^*B!1-I#xZQWw*t~)o4BkR&!(_7Wv zs`qcaGdY=Oo#rjj@tV6QQb+wmK<3w%{r+`TKOV%&9W4?%YCdB!Q+;Y<`S*vJ{c^lt zMB4&nlX*kiWUXrpmN>}UF8n;XzV63?SKqlmE=lD$@Q_C*dDZ!-dXv%8mXO>~IaUE%orF&n>}u>VJ1|6HA;=?7Y#Enfa* zMa=duRmb{2+)en}F4lYhz2KcFwI$ych5T*`{=oUyI(UBYqlJ_HX9(6CEiGxge{_}WnpNFq22S4&cbiL>rNd0ay%)Pe|8LKpYM(w$qgL0ca}sR zeyJuJoGWx?&*Z3;HoRIA`wSST@9kN!M)q&#Vg-+;16*@TcTMrUxq9=QTrHP8^Yo8nd)U=>Y}>%GtUk1IW%jC7I}fn^e)334 zT++#L;!OJ+nn`XYTJ8!m7V(*sKb8J+vY;QiuurNs=J$}jUt#v{yccvWX zzV%SP(&&rGU8O(Uf6g$j7wUHpb1Qhn&Q%n4?rg$V#-`OfIWANhEU~PPQT)NzmQ*zV z>(TkI*na07NVcu{(0+JN$Iti9mVYO`+h`IcuKMcqik>6erv!dzf6?x^T(A-uQ*8F_-ff*?c_r@BWBs1R-z`{gg?_FUK3hBI;3^t>CFobxvaoKagE}$LiJW=`G71RDXLZ zm9ru3q}H*;3w|1fSKMuDcef7Z%3r&BhP0QWSy+qmjhNg}L+?X-Z!TEnZjhXOsb$Sd z?ee4M*EVguyH9X_v0}f6-|__ozrKC)+4r4|+3LBzrSAjATjf1YK20@t&$}<2jh+4D zn$L676*uzdd}n+1>$ir-j6*8o&z`N>Y*KoA?mIuu51aE2G0%M%#gW06ve{MawOvZ- zuho8zA7<@P5Z>Jrk{5UM!tt(_fZBD7dZ^t;_d$@ds{ z-BXj3vHpLuazET{m=%*$C-8gr<PKd1nt7dSv#TxUS6|~kL%T*@bd3my zRB%b4R@SNbyf9y`us!0%uCjNJOt_RCc_Msyj@8~*+93wV)mtv?ckyKU{%P~Fa?dvv zKORIrZrm&XWV5b6!>i}f)>r4xC}rnHP-|?4SKT;4qv1$~*hF#5Y&&{UH5)i^aLdbDwu!>-0QkBc8ux zkKp~?+CKZPRrH7~f7`pW(28NU%j}zv3@NjQ^|Lj;+mR}kIJEooKJ-LGK<)P~z0-ji%5?si; zeDj&N;Tl0%jkD7nHZIy;{pj?Wsh^*1;7aD)r(z)&y=Th%=?i>5_HwQNy0+q1yItYb z`TcF3yY{+0{#}n)_B(Bbi1zveSyvCUGB9}aVm}SOG%qE!NVg;-RW~C)KLxyas5kt5 z{%tdXzi|uxANFOQlvcP#?dUDNLLL>rMzI(C%!L7Of*rimyH~rcQb~3H|M#6o=d{VC zxdJR(J?-x8t$yD(_fOg9)NMbi|M78!Pc_)T``?d5wv(Q->S|5BFV8;8yC=Tp7svWz z>6yRY6&uz5<9U%Dv{1O@$W`?pdne95ow97I^HV>u++NO)9>-Z&NbH(e9LC` z9MAl5wy%GBRJ3{A=}@LcOB&kZ4|Z?Q_y6CN`uc+0$6Ybnw;UT6dsf|8dnUGU=A6Bi zlN}n1Vg*jzzHa!z#Lb}RX}$1`xhozwN}uscToTpX;JK`L&ZYG1_tSfII3F)45$|r^ zx_icwIzgk05nJSX4fG@m{js!6K<`t!KC<@P*yVX+5bs zG4NZ2XqdNG^3@eR>lf@kJ;`jv9{V)K>oQfYdp@0&nd%sLC~S8Ax2|Imh=f>mTEcU2+p9oxhmo zrZ-WqjK!{v)ARO&S4Icf1Fx#i>x(?NKiDi)?vUTI@KwrohxMM$e`e`XJgG}l$MAA! z_z{7{`{lQsU)O$mi(y9g+M;DM4)OkAown4@{<~r6g5)1j3z~F~u~hZAcXrt9zwh0) z@4+Ksi{n8r_h?>h_lRF-+Nu#6(LL!ybjPKbDqoJvpE4h9xbjQ-*@Y_?Ts~?CDysZD zmh#8t*Y$gSvW#(8H$P5pD)Ug}c26~Yy-X=MXyGR{j}1<*)VywKUFrW5<=J|eW2Wc& z`Tw>&UAwnUch7-#p6uguwKCkKt&@J1FH#g+ee9Ul9|xh$cVGU_Q=NIuEkC6%=YT|& z=GtVpYMWKI)-#mzP6oWXU|8uR66$2g?4BGEVCf#y{J>&a(3O@rX`|{hA^8`kL+@cS?-kfM>z-fGFKIuSuh$Z*KPT0H`c|+ZJGJC0^HFOz=U0*M z?RPZg7HoMRpv9zmP-KVhq?XpKnN5lcZxU*99u;;~-#sv&;|5#yr+)E<7mO<>WlUJ> zJ?p_~tFNrj3mKPmzddwak&B`3!Ae{Ezd@^|Pbp^E9v9`DS^Z$!1=X#A8(&3htyKMx z(%cZa`r)FZ9AehL#MwozAMJ=rtgF+L(%V^WSV+eM9`EAB|&<-SN<#o_a;A{=T`U@~aus6HdR$+B$VzhaM*v=h=0_ zC*}z(5NkW-Un{cZ=FTIgZU^0_@bVtz?=rWXY5FBV(s8x)3K#C^`K#M{*zCT)+Vm!# z!A^c!QO=@!Gj~1XExGe%Sx3m9FE5n7^S!&T7t;U3=i$XC^OZJE+IV+kd5?O=;#9sX z%AFfdu?eZ{f9~hhTfD~eVoGi2x0ToIf=$nrSAFZ(-_%}SVYK(1ozUv}HBT7pEcUm} znJFKx%#`O+7@zPr!S zjD6<1+uSoQ#vgtkwnNZl`h%`BVH`@&-#k4%J-KSdr8iry-JX5QWA;wX2OX=G!*g@A zr^(6K9h>7OX**r&_`EOq`*qG({Q7=tg3JZ+2KNNHvXojD+i91UDBGWz@X!Ci-)W`J zw|8h=$&+8`w#DT_+U$yZrNR$CG)CL_Rv-SSt@?I}yH2~)&L8Dk*F7_*Em`C6V>v^4 z#cdDuY5QUeqdWYRreEz{x%KFBshz8fg`(^D=6_{77uRpodw#xc{WpD39l*r^0<7Jx zx*!^cMbNf>q*f&67UZOYb%5kJ7)0GS=$JZ6s@pR$FdSoHz&Jk$ro$^SH!U+KwKe#3 z-faVcJ<=cSb>7HH9hfxn+cfb6b4S?)D|&C(en|;VB(r>m#S`U@;sC&<*hq^?N{w&i+lVlRR)nNWvVUM!@E53hvUqim3607R?Pguw&ZnVX8xzo z^*)n~h2l!&l$}GQ4Q;*G?!4&K)+4a%<$9B@Ub}NozP+(#<`eA8Fn)Y%;=!WO-;xH7 z+&R_qK0xu3TWHryg^mnp3V{$u9FFr>p9=a>cF^0oL++ z$)ORRv-7+ESDECNS}Bw$GH*S+tuEN~(K{L5>&WNxg3_IC`(AZXMg|5|CI$v694R%( z)zQV*wKTxd@2~^U9`{r7e;6`ccYf_S!po_$!+mz__Q;9r!nX;}y8qZ$Dr$no+O+gH zGe5E)6clxl)n@zAb*r(A!{24m2eV9f&bXx0eao#SSklGLznfA$W!I*}-j_FG#B6eE z&OHcfus^a+VD_$6tDm3Nk?Bx0?lqjjSM+7RZ4-~Buy)1t1+JHQwrMY`jXmgU6dm*M zoq0{n18b!naT)xzIjOUs%iVUU+kL`p?z~@2lePQRt2c33xNQzyW-#S{ z*(~85VN>Q_zZ#sh@>0)>sTF^DuDIl?Nkwe1H`!Jc5_!V@?P*Qh$tV7vtjW72{{5** z`1_QL8vg4{oo&Q#W>uVySRk!7B}Ka<{KNmsXBKCLoua~k=Fa3KlsgO%t)H{u-I{ueMU-Dd2ueZ#YuX_1WnO)Hyro(qjk z-*Z~BVx_=Zu32lfTx3(`Y}57JJ?XiRU-z<)I+<6rBCpABe7&PjZ@14uovW;8r@Vd> z!~W%atk=~*zO|o^g}fzkZ&hGp$>6(Q)bD>TK!3p-S&9q~~#Jd}2GT z_WzLjhY3~mAp44^VOCo`#7zo4=tBR@|cR;Z@r z$7hzrSLT-%6{qH;#V6?_yG;_gQ8(=$PJ0@D4JG z>`v5RiL$yK^TljZ(Ie5H@2mTkq-c4z^ZpjFUe@>h)1AA;%m3CI?w=eQJt-pRD0`&d z(d8j~uJ#&!dG&mq*|sITw)NZofBL!k`S})s>)EL+t=egK??^TBCrVE=|Jt@iH0a4v z6E~gGV9rSKKWnCiZIsfe*uVAlGO@Fd_)o2!$#wZ@wqoxFS(8~NGk&@(I`nvR$W?XH4ky@hfXGOCtTJCgkn_hve zRj-po*3QzX{H-~2Z!KG}GPuaQ`D@d(RchkF*LHDC^5n?-UVZcG&Q{+e_cE40oY-Ak zvwT9(IqryQOI6=08f{ikIHJw+(5X)3;o=vEcpo;d?&Lbh9&g-yN>L(o^5$R z{o~yUv+Q^#p5A1V{zv|=~Adw zSJq{X9ibwf&4CvFA$xZz{dQVm?OgVXQB2u_@!`*#cT--7hV)z#=rZC7S(DeLr@ln! z;^Ojcx|QrZC9Ik~uH6yn4Gx;1b9C*d*C8>FcDgBb@y%s&{2|=XbjfMsF|W1P#8~%D z+WPBssdsC7+{7q7&)~DVTU{SpPH<9Y<_vv4OXZYr`PNVm3*G5j;UUj&FPw8xuXh_y z?CRNby8IR=+p31BWNXw4H11gG$Tv@+#+hYO#Du-7tLFYWw^6z!aYsy9;KFC7TQ@X6 zzhoM|>+wRFy&uw-f0|u%d%C8=+bI)E{Z{^Pcsk9{=^yjAg@?E^mtKA(-Ex?rXzQwm znT2*&W4AUi7aZL(MSDrZ=9GD70z8AR_whKDoVX(NzkHVV=}n7+*6-?4KJwp}H{X1d zOYPSkv$*CyGs)1JyIi2~$(FAoo0N}jR{h-&Hs#0al)bE<&Rv!LS+KFkQ#s=M&yQk_ zVrP0^T`H*C+9GE1ZwtT1aaUf>2PY2x7MNK*XI|GQQ?Iijec=~-{VshX!O_&}cH+}rN(TIIu5}suFidZ|KY7I>8Oe7F z4-Q2Lguis#=+(C5rOtsjI(gp?D!k8_w)FDn0+xyc@$Wug-=5L8N!vqaVM4)A3%gqa z!EatV~R)|+SkuRRe~?i7FI-#&}N zDPI(tLT~CYyj74o#q#JnKU?an^FKd-eDLSd%Jpx>mY!mlb7?#B?0fV1_L_ovi=eYV zxx0==s)nCAV%y&O%Eo@@kGFxPY@$ndDY~z(>soh0ZL+(Z+Y;-F6<6J&q+(3A%{W`b z*0-pk@2LBS4-Y2?+9rH^agF=n6W%R9i*A*r&DBk*oBZMB!X58Lj~v+e_#8X)s}lj6 zCmV?ETd>1HXY1v!yMM{NGw%A%^TdDp^ziF9f8SqsKQ=DK{_OpEu_?=^i_1TkUw5vc zps>hpe^q^vmArwy?6%bh66@|YBt1Q$xIf%A;28houTTGeyVSW)n0)wf^YN#uKN%4wCc2YPu+^PQ%e!Tup8DYAEk8BI@GMQCJARUWSB{ylKYDP9 z`5Eq0F|T=^7CgNrV0h;Jr#FjrtPeH2`BytCelxf!DEpnWEhg{a681B@WIbY7zg*gT zFGu8Rl=*hajoW;t&FDC4W*jru(I~{RM=N59c5cNvmFWeKH6DEYtGKW42;;tezw>TX z@2T1480w&Qj&skU#8ItDHHWFeWrwN*57pS;#nuH-dSs$6;=i*AVD=X!ea(g$bn zD+;f2i%EFPmLl7BY1;BwLs9Mt=?l!aUywGxeBEcGMHtVs|C&2@ls=B)EL< zOHN*1I?-uX`06>~>2JjLJWv(1P!^jNzvrhGdoRm*{ri7@owl*wZL!<0i%l*qdi$Fx zr+d23NgWZKknrZB%d{U`RUg>CDX#0-`TgX-+GG0LUrM;u-{=o0SN)uR^4{ccvGMjL z4Xd}FH_E?rQ2HEOp1a+Xi`Jp<4`p=7yEebPv7a}^PoXnrcGq5yoHrLe11-uo@pvyk zyD8CzZS}-cTN1v#*?VK}C0W-Tfy^3BECW7&51Im*sK5dy>1a5RMe&S)qi5!!Ir=3LHnX;hC{B)?5m~Zn;+ivt5wm^y zyjLoS9%v0TnJua3df{z}wRlWQhA+xob~(l_ zk#uTqj9#G`c%|pJ*;~dhA>oY2Q&nb)h-&$UzEaTUde3nvzOlrbq0G}gkhf7SY}Mqd z7sAf7#RAvI3N1;`^#4|R=-Jfss~kStzxZDDx0s=pXVsMnoAzwlza==1l{=>J;dYkQ zyZu)&FTc9I_ScaQLQ~tWU*Bu{Tl~MTKyJ|C%_`noJ3Gx52xTnnU3Otgm*2)!$IstA z_c?B_>S5JAvwhM&KdJlnmhXg&_de&?=l@M+F&}o_x#&=s*gvJzJx`lXuI0N{Qm|vO z7E49BT*xG2E!T;GUadL@W7}H4`Xq&DmE@VfohcRwt#o7FS ze)+WUC2!)wH-{D7UVqy5?4$UTb1W09|BGH{+uQ20c;Ru~SMsjWiuw$!kG)sNEWYvO z`5)z@`{(cZ|0{Jy&#}cj<99y}sDFG%Bdcegj@LY6tNhK+*8co^Y)9Ps`#(M$IQeNx zREmFR?04R8Y-J^bHFepo?_DhX&zh@$Ftg3Sw7WONJv-|3?wj9d zY?fB{cZmBOUzT2d%1bZw&bgVB^wu9-nCZ83`Z|t4m%ow58ri>J?{%|%_oD6Lw5qa+ z0xz#hABj{>{>O?)s0X@ng~c_ubEomosedo3#72&tFFxO_=Fr*nItK&MvO! z-^-cpJX_};m=xj}x0K_tty;(n&-kwHLlffVGNLu?Pbw!L+A*oJ>(=dQPnYzCU*z+Z zROKk$)0nKwBylO!X~H!n4vp0o(>YhK6!4u}7`35o@~xUR;u&Z9PJiRJyVk#a-}$PZ zKL;l`#Bv8c4=htsoHem!!KyQYZ>n@#_kMZh)c4wK<-cF8-gSy93;QA(Yc)9MDIV($ z>9fviHriLTL}^0JPm@QvJb#te@U-W>W}E%YyKeJORgP(^Km08=~>Yj7* zduMa#@%ztnOk&tk{A6vUN!qzkn~*I9bJ%ZrJvNfte!b6a)fT2#93Kv`cPBMyO_lsn z_x<`GCPX~>NlwygG|bD1W@KQ{;9y|T#L=k%#}l~ioLW?znV$!4K;I2Lop;DUV2|=g z{_0giD_iH?J)|D;m-)1ccPC5PleF&)psB2h&|P}`(iuy$8_eCZfy%4tWzbkf-~7)arA4MA5IsV z?zG}q`sUiV=VP20UZ~A^^mrogma`^x^R}LdY45Ph>oGf(WZAOnv_!x5#Ttp*g`3lV ztE>q})wcEOA^`4f?R-K;jx#jjL3Z~nfw z##l;z{gIXxC5eUYvr-eK&Nil=kMci#E_(BeOK-LZ)y}$`v|iY^`?vYYWlQ>1HGl5D zU%Q7@Z*Psg+>VoG51aR&wn%O1zO9hjULbrYCiulS{k4W&Kkwdpf^=^oD2ARmSJlm6 zU|`T-W?)dl8$&6nY2c{oop_O}*?`COKKt+X2bb9n%YR6A%2eiCHP!6v@9moF9$cGo z{mH$_)tn3r{O4Pe3vLF#Ua@~?tIlH23?ueAmUat%&NTi0u8Q>sGm8vVT)|3H>w9 znIZJ}S?87DB_}T(KU?|j%dwM8jeCwCKl;PxNAK3=qqSR$HA5fI(=h4uK40}}mfPf* z2ihUC*lu4pu}xXJ?CeY3tz~<^A*DRf-9f8meP+I7WMJrKW?<03;ji@6l9J54^!VbE z#G;ba6hlzYEjQ?3-faV(z3eCK1#TXVjF#SQmD{jZds|X;aE@l%T%MarNxWT8yhM%V_qf~HZPa*>rfxRZZN>Kwu`fjboOw8T^S#GMr{Al%^rPkR#fmR( zGu^%mJ-jqIIL(&dQ`zi=^+g36=fDHM)mN(+^l&h*--_~g6%Q5Z6}uN+ zx_*nx^zE_c@>Y`_3RouwPkU*{{q;t(2}gO|o2kzHhmL5^d}TKYfx zXJuh{ZFEh|kE-Ci_wMR#HWk{qbE>*v%HG+1?&lA>F%(r>wB7lCYoP*<@Qq*QW=EV$ zZG@)#uRh@PZ{my-Cns(4IVrBLywq!F&Zq5NCrhS@X|A0#3xSk;XCAC?p z<{ty1paQjgGUSeE$1pK4XtENWT#P`;r8Oir`?iBXjrkAzHK80ro+&RDKa#p+X0k9> zCTjX6^}ufZ{NM$c(e7T5-xN9HF+#f8=Lce);vh( zn!m+}P2Ya|r3nXg``jO2l-BdU7{+0|jwdtaYmLMfMZN3A;hK@X%Mw)&8T%|R*c-Zs zDcY@N9a~282C-EMOnggM?&jDh6E~7re8b7k$=S_^Jy$+7$zV1vTJSN zB>7Vtbf-uA-RS%-e*S^sOZKZD>wKymp9}ata8xkPki5#_rfJ#9wEAO4{jLvAH+%hO z%jQm*^DFd;>uJ|ktGgy=Yj%7LNMV2dJ|)tkdhUDi?)RtvJiPv?tZ;sPY|WpKPu2GC z-XDD|TV<0}k+Y9*SpMXXD<0>ve?Dl{dm-~Z+ro_(Gv4qtP2Is*qcr7M@4B#1ZG*Sl z9xU9f!%}_hpO;)x;TQdqDJ9yHN!I)ASYo$iZ&2S9Bo(rn{e$~{xr_eCOh3<_+0OdZ zPL%&gjKdS-$y?@4xEvbCWu^zhiuqQT#M??wT9}?tYP|h>i~hU4@%n zIaznDKXp`aO-X*I!Kt(bY1j6y311rKtUCGRlhV@liMPH#L>lA=rBL4D$9e@!3=Fk+ z+UA+yCQouf0hYG;f?819d}~N+ZRV^+D*GCiCb(~#d@1zr``u+6rVFyF8Ipd_Del*Q zuGW{h=j64}&I$I1YQyv%RI@ABT9xwBqfGfpb$=~%^j zhfSAQduCTlYsdu72ZuCn>GDihdiDL+USYkiO=%pA*&7TlYJK?rCo!yO1^&juETvRjOE!mXD=GL z)#OXIEc(x9p5o$AAnTxPschc0DM&j-GmmRcPEOEbqlMnp?6613ZrZL9ns;(i<)-HUm$ojNJ|WBG%SYe8hqvTD z;areVlW2Xt?9IF9f0SR|_qkvH*T_$O`{c?OOrIX@=gptACDQ-%tm!@fiZ(xr{dd@G z#=(ReZXa8Nr%3vqoM!Zixnk?t70xa5Zm?El?Gww>TDj{>uzcwYO_}M>UNcvO&)fR+ zZ((uPTLw1q+n!(Y9$)R$$bR^)tZYrr>7`Po)yvl96qOejpRoNpdxDC|qCUsa-Nzr8 zzWNuio#+0mi@RGq*6(xKV{GnTk2G}pS5iPbOi=J?4kH7D8=lrVB&lZ92K#0=I|%F* z|0T~>ba7e6`PnAzZ4O19OF3JEx_%g{ai@uv^DI&PzxT0JV9(jq>y@9MJ>GkCqEAQ< z=Ndcl&ujPB)JPPnh;CzW4sy+uRQBnY2n;*3D_}vWdfc%wgg!$6`$0?5vVQLbjrrn;CaH{lNMJwPH%f{cir@1n@)?04in$Q7v4?b z9EIvrQ~hUkwFHX=I~ILPJ#<}Um#~Cn|Jyd+WoNhlN&GbXdG5AE$D_J1)o zIbrvrI+mQ^t6RG)Zraatd^Zm~-^T9{|4sAw>ZNDPrvKWRxANFRhu_bd=PR6=vTUB{ z;dN2r_usve5A*ADOZr-|;fbvxtJ<~w_X4h2B->t$%bLA+qxEYMkJN+|kn&#k0!fcv5LYwC8wxOL@oX+PxFkyVtL`M(D3$iIo_@9Cr z%&GfMFVk(f%>5^=?Qw1_J7qW}OxpjINB@@jf>xd3PAjxZHdnttH^*7!h5DRVhi860 zkjA$EoPtsRg$?;;ZqiQ+t{z|YR^psCS8xBYeXh=e65J;|%XcgPZ1) zb6i|L|B8L_>O%I1IcoDyMDlHx-1AKQl9lu3{=G2~&F90j^m1jhVZ8MSyEnD=} zD1WnQX3(s^rK_|z$G$0Dm|6TjIOo)_XC9~ieJhriYdo!E@5h$6%J<2GI??4#1s}~l zjw=4+%v-0q=7^8Ws^ zjKo{;rg?eoq4I*8moEoazgFMWqqgv*Ou>^M4Qb}t@7BL&RVjbvqw@W|{^gkkXEr2y z^mMBSc~4~Xwl{x%@v^u&H_Im}dG*J}55=-syMJdr4_bB1HZVhI`n<1KOncRK9tdAy z!aHq!X4MHV-`SU=v);(FKVYTE2&E1Y8Z4tCr)FVLatZ|~VYQv7Uu z_utM)zTf^+@7^_0r%mmrcbs}Sojsmqx={T5Y_-rG`@F5Dj#^Hd& z%Mw>BfdR+zL}P7kps6=W`}EE7Zm_f1<^*qN-OVMeI%2rWv(0l?XKS zCsu6j(yLp)ukG}U;2nP~_wR{nIjwMl^}gFQ@2Kgfd%u~j=y+_mF+S=|_8hs*a|MqV zs>#0JIPsEM&@8uGG5x($&Py?#*x~2%WA4HK;Sa)cW98WF}hw&z@j?<@EBh z+Q`pK&M&A;Oak4Bl-uvkeaJwd<$dFy_SU8?;??>7`wld3iL>>T+P*{J@}zc!rT_0P z3v79mJL7Lznfk)8`x{zUttu>m=Eh256mq)R~!fp>py5n~buj1JoUB7n{{=&-lfL@GGcA*Op;zcbJiZ zA&Z%TL5r|o<5MdN@{7Q8zrB;`hw``%so}BEx5|~&h$-p!*HBsWsIC;fp~+awd&{rU4AGP$l=_AMsNRzc#MgNclE z#r)^9o9^cB(?3v|afI`%!u!vg82UoD-{so+w*TWW2w-qXL& zTz+%zvc;c2{!X3#p-W|c!s7przFmk;U|YL;`Jy;M*}Gr<1r}cXa!}hwg zIW}_+e@HkSX5kp;Z19F>hGxo=&9kmBZtcFd!Sj8AQ}rwR$ez3P!gj9|O^>-(J=-+D z{o>M_`$hBHTTQM;Ob@ckeSBKs+}R)es7c|^zvZtUGcho{W+g5uWah$?LI`3(kIaGz z!R~HVTP8F3W|`zow&=Kf-E+Z_sYjVIkT>o$&h0i|eN6wb56`!_-UGt1d*nRc=VG+TeYwPq~vwmN_B^vd0=eb`q`~AGm zW_K1o^y1uUc0h#VDNpU$ITy6@w%=N-ywE7JxMg!l_Umm5=NVVMT68yPjZ5@Ko`s!_ z#T=T=j+^D|nqOTmDN%?ETQE?n;vx^;1L(S@y_*NYmrxQgcNVcd13=c<^q<@pJ6 zOI9lSdMG6}a=-TcET^N{pt;nxYpIm)Sze#uo7*!Ert}*2aI!{D-qx!>b76|_s>PgN z*FJ7$Ts_xMEBzePJywHrlRsoFKCpDDWtnKrh4m&=PDc&*1XW8Z_ zWxxKO>Ym&!ddr|V{+RKD8P`5rZoScdIPbwUr^3Bk3LOu(Y6p2ZK3~P0s57hW3R`8< zY98(T-;YQxTa$7`M@hP4r_(#v7YAQFzxtxiY~CH!?~^~?&G}+rtG3Y0Xy>69PYo{o z-R@PgM%BLI?LYB#?6&Pk7A?N7xYFFCTCtx&RD5Uny1+O8uD_Y}Azyv|zPmk>KHjYm zleJJ6OkLW0TYlNbTL~8|j6JgzEv2j$-`HjPYR{SXCGEZa-x$uiIX&L$@c8Y<%sOG# z1L7uk*>9guEEG+szQ7sD{^QD@!jmg*a+ow8Ofk84$lGz>ITgufHD!w(M~qb8MMvM3 zZP1?4+@$+q>B;+_%1`XSXg4EiN&Us0>4ERIum3tpFW@rs@`wCMqF0#j+}RoSWB-Gs zwNGZXne(^bTxxDK|A%+PyA#K6N8bLbxa>&A`N3vRS#-dbQMXR4ccb? zrKG>=;6{P}^IoOyaR{i{aQANL`nbJOmqhgbi};=vJY`y=|3jv(@4@CtQI9{0Yj1h@ zqv3Dd{^@exsvYLvoRoRs#p3BjOB?qc@W|+@ZgCP=;J9$6NWnqwwTTxty_%OCSR~UU z6Vl)q;dwNB#h$>jqw~ z#~u?HLnc*dM^F5If;GrOT_%C8W7oFNma8RZvMYRAS$K}6>bisI41*QVTw5?_o}M zzF_um(>l9uOFisa5xi{j-_s2uj(d_SGbPst_D;+7KDH<$V0&MoLDP4|s%fpCZ#>NH zl~eS6_{Y&``F_(Wxgp|WG1FMvdoz8m&O975G0$}BG2?)VeiQj@LDXWIPje(j_0G2&#z}y(^^ve+W*F-xSx#E`0`lCVcPzUMlAP)?0T~@{PtJux_jxwEjQC` zovo+yO!j!oy_>Y7)sOvfq4}QM6V`pqKYV9KX?JYR@?Bf9)L(7;xZUylv5#j?+jWM1 z^gqeht1R(jdac;=(zlvVcCJpGcbQ3KYP721CB7RS(?U0O?uji)x87@Z^O|OpxXRN* zpPHtL?z;ISzJa-ZV(PyCotyvPeg4NQeczF)i}PE)=gh52c{P1MqK3Je)T<+196R|O z3j;$n520)W9@pF&c0d2NnLr)?g#Qm;G0wfSwCL7bPfzBO$Zc%5A1&~-<~giz;nK}# zprxWmFE;&oZ~bqA&e4;fLhMz9PX2zkZ}vYE?(LwczzXRG}d2S<(8Nz)257aYoJl=4cGRAJ-pHJjcWJ-aE^SlWS0ZRw^I zZmHf-DevP=C&jKz>RWi&ILw^&?aV7buk2Wod_cEA*g!=rgXi+v#R1u+hrPdStK8?5 zt+RQ?^UXHqf4Q&pWItE@z-15M){NcrV4H2n4OM*|$3Q(< zWmKRKh%M=}!Pxt83YODR_G-IOcA0;+P^q1D)gCRC&c#V~B0^j*`|s#XF)CC0ap=seX$Nb>-!*buTxhh|ao|sUg!;ez1C4>v!e$?Y1TC znrtAs#lsgU-Y}JdS{_ysy=Z-LJf=Fj~k8qr0>3t^{Lsca5C*7 z>!Gqo(p){dn{^6mJZ-OetiG+8Vvu#^Nx?10o%2_JeLcBi#*CxO7r#4F``v({eX84* zlO|sb1=YT|dC#bEP!tIa6!m$qo3DGGn!cL5ze8Zc$2)on;%Ba1Sw6MOPQG}NS^GP= zUDBUb{T?PZJnCCt=1_L0e_QqEsL#?tS>GgPx8E%8JEoEM{ND=wKcT_by`mLbk5B7b zl+kneccI<>UFY=w@A+r2|AhZ@@%iWN;^v;$-*o1wh5QNrMP{3OtW-Jy|G)n)dpm36Gn~x%a-<&vZ4ZCA>@dx4pIhsq%5#GHTz>{fi^%Xh5;`pt`H^8f26sd>q)&jTUri(iDhG8Fcu+H6dHpDAg)G0)^f@zfQrJIb5e>Xy_-CT?Zu`w zy4#MrPA-$}a$2Bz>zUF-DbJ%M1EqXU^cXh=c>oSw3ZhjSg zBd*I_aT9ac_P2iU;ad8l+ z5e|0;-0 zbhzjeB>VZ&8eT{Jjxq(#hcOvfSUsnTO*TGx=$Z8ShsS{#Fj;`s}zH- zc8B=P_KlC(qqrCWiN~$UsE_1kamlq+_zo!mg?WlDH?1$Ih6!oWKQVV zqwr%}O4UPKE6&M_B;*cl$vLcJxl>ffbT-48iJLEK9#%g&ZOI|ubKJ3}iGNg<7@xKX znjxHPCh_t}tka`qP8znSZiMu9aXo&%I7CJHx!;Zpm1&1=$V+a>uenpu6@B=}pEdhm zOt9%V+glN}NoT21j0h`N@uc8TiDh#IYznU}KC!o-H%>cc|3TR`EAQ?+VZh?Bt@D~u zMWnBe`fmlk*mn(=GDR%izaQW@%9fF_g;#sV^rc&DOiq0?UNwKwgQ=lhSxYPwz2>WN zD}6uT#HQhs#KPb9Lt6UC@6hRU#CL3B|8%-$m0(JTKjSiI?a0};?(W?Gesd}NVnG|z znN80(U72w?<4D?R8{yzdTTOl)F?eJ!x#yF~>N}C!Bwzb&wSD;P>h7>9mwQwvRx^IL zyde;xS`|nnj?^|?Y$;P{h!Dl7X zXPwyjX?O1R?+G_=o{RFGzHIZ3BncUQ>GC^X89$O|Jv(?&QRnbIzLM0x8@Fg}^9r1I zA;H3|Zuk1qB=h)#VIEJV-2)do+>n`~n|M=6_DgKJ;G>gA3ixlQ-2JiI)R*yCQ`W73 zwRO(gCX-h!RNtfPcW&3O?bqZpZnynEoKjROyZ_JMUq7E1{VVzKE{ z?{D92U8g+pezE68ePga2V$CArJ4B~sAKxjf@JdoqJoBaS^3s#K*IMtdI+CaR;qsBk zj%U5EFS)sE`no-@SFMPi;~Nlos_*KyfUR!TXP;e}RP$`-w)stc((MKt;(x{2_y*fs z%_uqEW~IIJ>9y!r4Xv8ndX5!YFPl^5_at)mCAm2YQ$HIiZ<3o}mz;23&t>A;$`_me zTCZ^2?zKKleDTg*-y)}Mb!ykh&aVBpO=L=`bapE1#>elfW%57kPfNM^>b7u*_V3Qu zjI&m)UTL@XCd2cV$(EsIH@Id^zWQ=+UuV$F;7is8&nKTY7hk_F&PQ+Y36m8&W|m}q zyvNeAlworH@9;GV^8-vnQ+_}1(cJqtJKAg8=^r~&?)1fLUoCN#ZT7#a!F;(y(2Tps zZN-iFh<6V!3R|@G%S%5zS5-g7;OkeXQ$M=0>~}o;-LA6FO|39?#+z8L#)m)7^(0$K zX%(-@T6MGhdvt1v;!&ezY$|G!Vym_oSqg9Q^38v5?*8WA+`HQf_gYuQ_ZO%2`|svT z|I265yvJyZqL(dK70c|cc~9O~+#bvsY0tDHX5yW_U_A-R|T8?tBb;J0X< zdqsHOZN0$04|4u%-THN=?|6IMR>SPU%@1bNm-J=v-}u6>VQ@4wLD2d44MBsw_v1Px zq^zYL&kt6AznwRnkFV->TF^_i4My*8{MNg?cw*|qyJxG9X#H8N%bb6IpQ-W`hebwS zd2(B=R!eQWapO|)W37(4@xhLF|4)^8`=R*v*9%G4@3EK*?Va>UWAC&FanixRe@{-7 zzG4)!zwDRx^Q^l$QI_*Or@0D>&-pcF&vxb0_XE6{Ss+`#MBO*&{PKMJe=jQo0|?9G z7!fQe%FjwoF43#XEC6YSY#?#ZTCa2X)*hQ61_p*y1_lOk1_lPGLj9!t{NfVbq|(fs z6uqp(+~6<{JrCb=KC44CJakS5Xq*h!IO!4Uaq7IjUZ988*)yJj8tZiQJkLITTJ-5V zKVK*Rr|Fljdm^yUYpIPg5Sf0OL-^9eg z;L6Itz>nk%*aozaSbxxhiT)}7H+cQJ;B}+pTd&iSB@3EDL|I-k`(M1dy_5gk_IE$$ zJgC2aceAXH&@R*w8_BqL%D{4O&~*5b5X*aV_ZL{a|cvb9kJ--$>INb)vP5OIwq`P?ajU#5oX)_=Dg+^ z#RS=^Oy}F1e4m)~hR539-%;ys87I4CRn(1{0WRm+>q6Y3-?Z|ima$qbP*a(+E{w7N z2ABKW9PYHUiTN)(w{FNpuRzZ`ZV@ePugyO-^m; z?Vgog&@t<&p>W>qfH&%go%imabH8?Xl77I^*;8g8vaI>BW5>=!-|qP9_IhF4KR>;y zel!2Fczx^N>er6EvT@rM^#6H#uE$+}!r|S)4VqW3{D=wpByj1A#Qf06NSlAx7jdf< z+5F4vIX>xrri$C9n1ULA=Pj!qO^>cT++8IXo6ZUWy9AC zU-sQ)+s)&4Y}W4rp{*ASmLzGv{PjLvU6VOpXRrQVrmb-gGL`zv&08)8-^trHo5@{i z#;X4Iw3Pd@5mvu+tEFxHq%LGy^Qk=R2|ZEWt zhc}Y%v4=LFo0bu>ST)J1V*in2?s7A^(>HZ!SNE?z9mFa(FK+d#i2C}_(7n-bEfyqX z{=FfnckY)EXW6>d=UF;7x9=$V`>K4uAO!I}o{|L3*=MFC{0DO%%M*1jo5F0M!we2f94923Z1uLIk@3ZglX0yV&! zkx7IBcaa5B&&Z&_u&oiq!cl-B8-lIC0cnL8(vD;`wD>{Rj4k>Rn$4IIMW|O|E;unj zbmR6XNH-`M{deqULFf+fW@Q7(urRPNd}Cl>*vJCnAqwvsNxeF&t6ypVV`gAD!i9VH zAN0;Q@UZ68ut4zmjQ)lH1*HuRamKr=Z#E}MX9Op6@4DIeHdSL=;38vlP5(z{yv{;p>G>M z$8>{-AEVMHw)xx6aBp?|`YUulf4AxN2GQoY(`(s&HB1c1U~zR5IPEK^xo+u&30|y% zHVHWy31ybwyrxAn2QEvUd_ZBM8{5G(f&mii1h#3ND%J~A2!3=?jnmovS;eysQA_QK zE2^@iD*wJ}>bB4pYB?C>mHX@Gxiw2)92c38cDgCOv-R1}6U}9QGp(k1x=3HC6xrQt z^5(6|1npHFyeefvPA9rkk0swf=%|#*=PtHqyL`ce1>PUTWX`_lxAXhF{sd3Q@(+)$ zEa)-eiCvMH!By?@^t)zP(Z+Ohu3fS2p*y*9e;7PbX+9zMl=(4R+lC{e;*Q^UnQb~Q zJ7wC`?{gg9uX}l);m_HOXK!!k<+7^YmH(s9R6oP-Id|Fj%8#E*4&^PI{QF~0o%P(7 z#8pq)cHWqCzvcbf37;xUpDd~yWnRL8x!x7C7A;~5p4a^Df@4L_^5eV1icVknv_T_SLe+ZN+E+G<4;NO< z6KUObqDQ*zkM&-|0r53ri&C{J$6I@D=%C+BXU-odz?Tv1hVp}hw_mAu|3*|zPdf%@bF#+4yj zlQlPgdKnXGo3?J3bPEoTK_{E^j2=Ew*4Yg@Ks@QQt1DCPu8qcy4CeZCuip7GY7VB%lzWK{Qvc~ zWA#zXkN#JR+*-Zq(6uXb7*|`cpWPsDTwM{lqc`uv>o1S<_xId<`=m_p#`lOlC+ih- z-$g&Yd}Y1<{RP3&<*y7*J(vG_{Dw#%TlC6*Y*jpJlYX&@f2(Z!@@_N#jx7Qk9|qmX zTq*RsWX+qGGnaSUEEigGGC?!Ewe9z8`TGaWf||O@&ny0wejcw`)N<(~+RDJ43A!sl z%eODG6D&KxW4lX3Z|6yy3)J#YsFzsnuz`EUq{;1eYxEo@OZ8qjVkD&QI-et}Jj}br z+h|XOV9fvOwwSd#H=Q0Y;J)i2d(P6>MyBt0!N=b1Zc1ymeP}!_^-u2L{4neG{r^O# zd=|?8@N@G=iFMKs8Ojr`zvyND#jsw{f<^ljo7Y{byw=O79M|d=e28v-ApI`5!)r0~ zQrjH~J=^4VOnGp``~sWq_ghvcmO0Nj*JiNzyX4;IUuHdB?AO?)-_iEy;a&m3{cRf@ zABcH&1!O;xowDnYqq}_Mai3GL{^5;-LkMAvjEUfHU_s&#*5 z#cJ~qA@3=N%w4W#bqPCr1Qzv&&Np^C-O9AM_0xjvS%PzW;(pC*3=j>^-Xgfo?R_#| z&~A?(e{SkKO*IPPxIA^)&W$&JxvehL+*zC>+OpfDrBUmh(a%)e-K?y~{rGY)1UuJAr6w{r@@N&J5TI3;~bHy49 zQZv_`dH8LeJEv-^(+b_tNt>=ky;D7t7U{Y5yXGbC3BA&X9=7Dh+$%nQd=Y<`>zx(J zO50s7O2}_x(HR|BvRb*`XLL^4-fuM&Z5MUB2rDU(bKN{Z#e$->idn@ijko zM8r*c|M2P0)1N!Mt>Z=RUK4LUYIQCyYk!Ad*2&osvd;>q9FD7BzW4WEi=?uxsmBG| z)dO4|%eHVjWU@T{tS5M?DNEbq`dv@?dl`X&-wtgK3wKQVrch#j`}a>*D_!dhx$F1m zO{p#6SY~+Jaz^g+ea#$)W9?6<&y{%LxVY<6orH1Nxi+JDQ!1xDpFBUxQTopo*Wc63 z&&n-b%6oYI_j$iRetzG{!S#9WB>CU3BVIa-^GHmdxAEZ0HGYX7U*7oYetqrkEo$g$^6WDg1x{vJl>Q-`z3!P0N6kOWB~HJ72s#Vr zoxGB4C-h+_v$BZS8Eg0VyJB}FbvGpQ2RlxY<2G=gRG82|<2TRFmUD^Aj(zGps5~!g zVhmdZ!y>&7%};{jTrXbS~=SME+0{B`N#!flIpEI$7J z)a^F-w(DI+wOd6S1a(} z5){H<#O$qE#`2RrTG!%TcBPTg6^3`yuFtVn)^VS-x^=^qAFr=eI@EPcZCEMpDIxMe zach;{%(Di^Lz>uxd#@dp(vA|n-8cQ{wx!2!PHr~sYOd*wLw--dC#|pYqIi zy&B$>8rPT_*Z6c+(9dT@e=e^4GVyfny#=?_KfMWP`0UK+$ItpAjlsugeVciCYf9KN zeXqVBpI2|Ush_~R@OoQS!LP4JF0bc&zC&$}qwgP{O&>+X{a*Ge>}Pd2+WX{9LC5FA zihlg3cHnGa!Z>2 z%%AgC(JSkW(+`6qyEgay;yZM$>UF}sNo#Y2rle{w|0iX&a@rxw(yvcBSN{4YGM77S zlatxzX+M`ndTwvsA9O>kfbme6`t4wq?oCf!&+xsBT?XO{PE`{Qrhmlj4fJpQeG``UGbzGd?YPa8zuHL}Qg_JViu#cSI+_vKB0 zRH2Z$tH$m5$BM=!&)0mudTU30LgQwR+8^5!^u&`~me)*^UaZhMkzTkZ&&KDx=FHox161EA_#IGMvh3%%ZM`kRkz1r+ z2LIFu>%4UO*%!X|PX%vjW?BmSJ)75Ky7G4S_kg8*`OhyN-<<#2;CI(dAFn@QU*_n( zuAP?7oOu6f;O%WE(|^AG72UFXZq}yT#jRCmludn?ufOtGJ8;U1<9`KD8LsHdc$Rhj zyhp`tIt!&+f}tfz*je^ z@#~?jjiMjt+;X91z0GSXgZ6g3JNO@IJ?QPEUY(F|o1FX13=BNH3=FC`M!kwNLFXRD zm!&3`7s~?|yu@`>|}bt%Ti$)OkfS);#3)P5+S2vtM(iY5iySiJ6l>iQ3y+ z+yC}Vxx6Jo=9jSM)|XGSH&2MnpB1$B$-XD{D$91K2N>X^c|NjYru<+Hywc?kvIa4LH} z(OE|A+9P|pQl^sNtSt{FyCg&g-Eo|iYx#NSiACo^R~k7xrZfv{)Ks_H*RGInw4OeF zs<(vL@8}x$7ws1_YTWbw@A_R^;%wKKw~u#!&w6)rPov->&zgvP;YW@a=PmLp&t~1$ zxW0IwulLLAi~m;c`4qG3_tF&?=CA~qd;eqej()Sh?z<`%1VXojS1ZrpYMb)4n4k`FI;-YYqsaD)4= zRaoOU;WG&idu>p$@^tl_Cn$&rPo~x#42p7I*uFz&6fcpVxal zRvt#}WqsQ9wCxLK?dU%|_4&JZY0LN2ZtvXI!}9<3E=Sf+YZ-icuDZsUxs)#T zKHYVG(cZNOPi!*Wp?B%!n~=>n6<=LfntiKK;z`-IOS0Ei35sfD_ncC%NvJWpRrcxZ zy_Dn&H_paK@Z_eXH696gziw*P?1>dc+sj`_JWghs{I2OmNn#Uk&#&$6XRc41)3q{I zEF*EH`KtS3uNd6--8y_q@TjPBlSDQ6*1LU|Q>xS7m9b*i#7kFlZ7gm}yxnFm z#r9M++hg&qn^$wVH{E*J`&Z)r%)qDTzO~+Tugkvtz0yiu+ho^y$G72YS(A4QxOsV; zGIrAYwz|FZ&4!1+72>Xc_$B$nphw28M*hh3UMbO2=cC%PDoZl<+~YX1b<>XS1HZdC zVq}?K{{)XGLB@$1Os;D!?c5n;$H>62kcojo1xE={l3H964?iHOpfWe`bkR~~v z|JuEi)GNw8)YoXAm$;p`{X%uRgA7xpBIguKYyS^H;R5l8mWnAJSa(y@Yq#9Sb+0e6 z_uXKAeoE`n9?liNMFryIGA_?f*|mF~SORBI2Ct#CjLU&X+H-sVI8OR}{%cVAbe_b? zwep7r*`$20efTgfGpUzN_pJ8|c5P3~-*+x5^WHmm%>3FOW5L63W*wEzdMoyJf7SHE zQ@BoBtX^Hwxog#Gk!$?h1pleKH1ekx-dglZF+7yvwT3h6$rlw{3V4fk|CMZfYRPt7*8l14qF*{&k?i6|M=C5_^ z#k?j1ky`VQ@>1~!T%?Y?J?dhgXum;+*XiagPw!hv&+e}mUEL6B?j<7URdoLC&hOvu z6=;07$=@5tJW0IATcOou%EcDZ-xZsWJ{AnI#o>kVuUa)nG_n)37Fu`t^sLHs*c9QUeQe&XPvt-=D;ftyng z%x5{+wmILYdB+qT4VC!}PFv-Bem>9JwdRguOV(POiQimK39mWBk|~kTy6>@U-24qE zj1nil^5{OoqsMZrsqEvnBca@ZIumrbjelP=bF07g>zKwqF|Dm_yKXj~USKxKE#RYQ z@tm?X8-AxnKgnbL?ig%e(`S6f(AVnQuES;3CC9&63!3h}{MO|T$GX%9Hp=Us7g;@M z3H-`fIA_{9mF-4_bLPmsn02?q^O>7Uroe(LdtFOMpB zS=y|vSXagutUho3{KMDUAHH~TU~8g9)T_#S6(({^EtvN#*|%#uXX(vL_cMxXgU$Cg zPvvl!Y2)Djq+#2;wqJ(g4z5ee4FlXsf&k4zqMOk+i#EHC# zukbIure)faF(H1Q?`-l0De&R+Xmd7>!wF=~p ztYcziU~pz)U@*j&SyQl{o>fp;JJGwl*+Ag<`=eZ6= zM~2h(zKDvOnsdFYc(!E1S-g#(Z@lz9%)ds=Cq3(d!Dg3T zuT%s@SXEqNmzo3?{keR!eD}i8eH+CSe|)L^crbDw(u^9Y^xM;PuauRUf#Crwfzl7U z{MAsepfWYY*Z;ABz~1mz^%6Ul#IE|Vak*=gXcKeHf=gjh3$JPwP4-Nlcw^$*El=*h zmsX!L?d`&~Z=aigzIWz^s;AN1IrD|jzI$GhfBW7`U(pwixuuTf*~_)AR_xlfV~0oP z$#oa+WoK(doMMa%cwXt)t6S39`h1sKYFFdN3w9QJ-!TQR*rJ|)dP8s@=YMm*nFm<6 zo>LO|=i;)jKR@S!<>ajBuyg!1w0|Zl8`Yco zN-kfUb)2Oz@RGx$6PAkvr+-ANef{d= z)5^;2Ra0i~bka#_SNZ&cPvCoc`XYJlov~$V{6TLo-E5m?du8Sf)`!K_)!KPov$#^X z&)+@u+ywniyCnTC?U+?N|3AN{xlG#Qx}cY=NAEsikl@TRn;mf0F0WU-&O>YeVu44x z(pgueyBH>4Z)V$3GvUD21NJl7Juauqf4Iq5R%gp_*<`A`)(#at&Js5W$6RY`kZ5imrFLe@RTIv<<>f_-zI$1bHSlSKeTx6ax1UV-ZJqM z|5K;;>}H2geAAsTV^#1Zw?5;Qcc;bN$rs-Vt_-yGTpW@m{daAu%f-8QwipSY*=nM7 zEI4Y<)s1_rGu6-dtf;igOxCkfm(N-JNy|=kYF6zM@g~Oo>thbiyF2YMPha41o97Di z{q)w?dHt`pcoHF+@gbwQ=1kINw_N$ZKYdL+Ib+k)PUYIH`jEq09}+ZOq}oZ~Au%R+RUQFe_dJ4_t|*qaO=VP?;Oxo!4T(b62^L{XLU%i`R7JgM!bPLPakgb5@?1@@ht1 zUVQt7MO`NkP5NtB$EUfpEs^1MUZaFs%C@>o6Wxt z=gd66F>SN<-$!v17PP-hn7)whil=GyW$)q$k^9ppZaB3hH~#uTP0@{YBKej}bxs|6 zAe!;S z^}b$KQU6K(%3LkI8L!qY@_VVe=vrOL3ezvP8f))n?7jBtPyYA#6Cwipb;4gh`StQ) zWK11e$y4`0(Z-jNfx(-Zv>-FmE2x|sbTErqQDCq5FaF7s^Q4!&F`N*?v~>BUYE7k^ zH}5irch6e#^Y^Q)$-W*@E7*_D{C@9@O=-`@t68jTH#3(=FwOM)wIJreGBzo@wcH;H z>e&lbWBfO?$Zg#=XYJHw*Q}hoLW5gg$Rs^bJr*ZqB|gKzkHyHE>qPahsRqsFy{D9O z-ZVT|Yie8;w&lbh=O-$gFP^Ht5q(|ehegWP6P}7LRtpY_eJYVFt)A(7I`M|pWL+U) z4I8G}hxfU+3skk(uBxz5;MbK*abNl}pwz^={P4W3rB`AsV()L;_29o=*Eb~e`^GyC3|38s#aY4=98dGMtsxeFN z=6rEj=8~SieNNjnb&Y_D+YXxj(OT?v_qfEGkmmFq^``_Rv+&hbbcj&x3Tr=&B@)1UhLw#vPa^zqxbWt6Ve6z zmdI{lSHH9T=c2!Ub+KwMC6YzgS2oMs=$!wvHD2(ep^X%`umoEuY0q39 zanid*tC4G=-vYM`z5v&onvDw9>H;a#S)^LB=e4f=q;sClvMJW|^;`ElPmX4Ewu_q{ zI;O>b>&M#Cl5Owg+J6`F>oEwry?eOOqS9tFH~Z&z&L%QROP`CZ{j&OMJ(J++9JX&u z4!lfC+lIYz(ws7{N^eEWhM8Lz-gKFi zv-SVJo9*xNTwlmBS>I3I=W|ThX_F3ftlXUbf(t*VA8dcga>;x}^&YLQSN7fU{CTl* z@eYBd!BZU-qu5?16h#Z9G%hNL3)$AVb_n^M{G+hg=X?U z&*+w7zRkL|hk{+Cw``s;`-sf#=AI3adU8(}RmAO?XIJ+9rp&e}dlnk@o!OpqI_>kl z^N$Z+o_KKPDK|&S-Ai64%ZaXe*#E;-YA##SR+SusMuESrr$a;Km~2-uKFp}PVX=~F zt*SHo`dlB`pZAoHeSR`)ML!Z%a{bB0TOYfb%zP{7h6uSBf zt4XNrfn7HoWG^jvJFRv8h3l92{U^Oo3DLHmJ#9sdoZ%76E6XL`Zaf}QS)KObm&a+( zc9*bp-^P{=n|%6NUYkzXayTej@kG{@mqIK1n$=}9YaO>mzLT1cv>y}{Vfm-T40V_o z7{XbJiZD>YvoyrF|1z}cGtF6MqTAh7;#yIhiUKj;4sd4f-sEGHxwiDpiL#8aj{oN@ z}?+Y=zCX-bESPZ#U{_C)zwkA73J>NIsHUVa3@!;jh=p`y|K1>ZmQvWW3I!G>;hiz;831(xQsnhv!*O% zuDWmVj+>j!Z&Y0Ilj5DJ^dv;CrTzEQM_VIA^2Oz6>GQ8I<9rkOMR2N7;HLh=_a{B8 zt(n}jOHBK;niI3?JQbPa&vlNMtYld5`jd9l1gRTYa}QLB=DU?P1oK7zaQ#0wVA6`H zE{%Cf!R_;`&*=EhHF&*@b6wHBd7+p0=xHDK`x)ZZ%aH2wE<(XKbj=mJBQ_B(=U3Pz z{?+;S-r`l$;&sKhteg^kIUi4pKalm;{@vGC{qLUEn9bkYVqMHszT}|%O8q~Ajh|!E z<`qxi+oCwT!X-;3QP5{%U;3|n_G^ll+cs<$J}t1!xUPRz2J?1%w~p=pv-is@m`R4o z*Jl*|R* zs~k%gEL(iz%Z`>?Pa_)EnhJk=pmE%Kap8-MNQdmV+7dB)mwzqu@2xIc+*=p4s786= zfj6mE33*2S=hOw<>?+T!n3}bk-9?J6YT*r41HPR>PIIyYFY&g%6;rA@(Q;*u`)to8 z#a@cCIZM(Ln+-!Zg#P3V@MdO#3^TM>{?}UnM?C!lsJbIAu^H6`qZVBQF*ZimO%`Zb+n|J1? zGb?Qi*!y2!t=^|)x6bap{JeWPN*;#4l%}i-m@?^`_TQ=h`V!_&niAu>c&FgjgTmV# z-PJ;ci*!oY+lJa@bLxaWww6AN&_6qS)3%D~{*zZvT%a{C`c9YH zlv^HeZ}~(kw;ZnfefxX&)Y6Z&Gx!th>JGZj-LXPaTr?)6Ah6ln!d1g3^w5rn>lOSI zcD5cq(@<_0`#-!^=y0yl>iseWvitvbKmB!Irq(-BZ(4VZNP<-F&YMy7TjI5K+q8AK zIRY~s!}T0&g)Xc+c%xZ1`CoI@N&oySTGg}rW`xfazUF%2T+XFKe=5z~_<3&m?bCl4 ztdyDkmDO-r<;!}{9p9(l*{-i=n*1Vf(#wdT=)N1??YCJc9sfGH{3kPNg7IG)$O5W_ z@3Ii+nZcLt6jb&Gd-u;a5ZI^uQGQu9qe=?n?@5c=qSuG=hw5KF!xZ~|^=C)uXpBctQ4-5J9_4aH^(VeiC zl`YS#cz#U9ypS*^#oVvPCtb`-+Wx9NuV~+WUupU6Cx2y&Hf`DK{%_06IcNTvpZq!P zV@`ehZ~4&w&f9)%X)ZiG+qr0-z%hvj?wxa6<&Q2rt{%lvMcQO{MyxDAiHF9+Xp z2$m7l3cSAJV&YMGlYQ>W@2mHPC-Ux^p1ANnZ||FMRl{4oHGzjWXz_TYwqKbdx#@AF zp?Y!TVt%(N%AA(ZRE(LlL!(U0*u;N+6}+5Lt$SYJnbYc3AGjoUX022?mwHj@`MPq( z=ede1&kw#km95wHVPUmdtESG^4k1Gp_bYB1CtKHq3dEk$Pcc0p+oS7fKiNEeI&Vj) zQEjpE1ih9v@0X@iN{UV_%6PZf`9b@Jg}>PapQ?-6%<$fPy#CLJw<*%9i9$<+=UVl< z?J-}mvUPv;!i`BE=I&y9HvNUwuc{Awk+#@@ijR^P^1DDMxKCy#E;WEFtBD8mnhki` z-h1q6zU|!+vQTZWuXew|+YPrvTsbZY<*Mj-uKxP=IZN1z7dv#?7yS7B_x6ox0zo3I zE4CS5YYq(!-YV-ad_dUYXhJ>r^QkLSkG){|Ecq;WPxO(wp|_3;RhPVae4D+(G|B9+ zP1^f^$5sp48`Z~saN8B~tG?G*Lu_)lb$(39tRmC8p} z6fNlO&rq27O}Z@H{Md(y$){L*ot`CJ=FSeTeEEm%kZzkSpMBy|`{=*gCl6npWwkr_ z(godZDlK}^nl2Kef{S#giZ$8Xy}HY^^_Nb~>`PPc-R3#ScEUAkd5@TvJnzEf-%Hmm zwmI=><%`;Cj;9qNXB4bkE^g`!v^jQe>5E{7FPL!uRC*%2$j=8#_IEAb)HT1p zzB<3B?Vv!#Ij3H?xl);hE%E88sdEoY`|;jse`Qs(_A>JEhM+k4Q~uM|oQZ*9G6!*S zVystC*&7Nu*mnJq`W>&mg|51&Xhw%l-SejQ*5P~0PIYx?Uh9~9Q!VQM-x^=HgpIz+ zDM{}vpV!IgtXA=SwTtcE*C5G&n%(!yYParS{(a-XPu3p{vx{w>GvA(NqU+(Q^~vK} zq?uy%(bkPW_FTLo^PAcG_<~kv&jm^!JQ8XTW~|?GdvclQG>v~Q)8xKhTO9XHo5_27 z*bbYWf34zE=au;xY0AspQk`x0Bk z|I6V5!Pu zXy01wm$~7<(sE7xjAZlW-5O3 z^Y%PV>qGb5*G0@e%x`UaVSmN_+jDK>(R&&bM5C1-F)%PJV8nfp3Am?GRGyv<9qQ8XGPFRkbTGy^qA9|nNyk79troVc3^c!x&k_-PXpIE_G8t`>q$)uF8A2#y% zSWV9LynRTK^97?gF;FrvKlVd674Jc z>bL#5;TiTKZIR#cP=EgOt51m|>P}G0{;;}cV>}}Rg9;1oqhY}TggW(GP}w{AZdbE` zK(#UA_qW-dFT*ardv#QN&df8GGX+L^KG3S(z;?t~xSHAgh|xT+Yxx~sbDn_;j~fO(=vqO_hE$8xUL zkOK=vF3kO)d$VIX9cb`YRou(<2dv8@_p3dU}1NYN&pWgeFP+7A3*U^)+uWyW78*ZuZu(c`W z)n>!+?~1J7@7_7hl(Qwr!6P?VFM0F3$XfIDGkz{i^G=s~=y!dY{+Xw-pWWCSQjFIJ z7T(qRxMp!j)U%YRcZ>6r`wS;uonz<`{6S*%<{*P-bKO?$|8_y@zn1C2!@s6~$lCn} zX#{AE_arTzRU8Vh85kI}nD8Xy;*xmqA-faiEuD_;ueQn}pr%lf~1LoN+*ME8bOZX&{HDVJ4 zTcy>!tn?n*?uiB0vdtsDN#JfLiPVnGDg+q&bM9_H+Cu91kCf1-oaCa8H%$5MmU<{n`NCy$uz zvA>h_qsoP4YNYA?X#Taoqj}=rx(CdRJ$+DJ@W99GB_d02Zk4T3W0a}ybq|~s`ucW| z#$N~BUzPiI^{=s5%^s88a&5)@=dal(il%>Wv-a1X@$$X!#nANcJ=W)SXS{qbKQVMV zcQy0ThzZPxCCsEN4*hW0ap1?xNA+%h!!mz0%#d$ljC>DOUD?#~l%_qRnJn8%qi zLvrG7t48|?^|8LbduK^9*VPsazl)tBZT~B1+nbvz(P5HZN_mi^e z>YhjX6d&gOIlTYW(?`OHWCY4^hdAc35|iP;2fslw9C)7F^*h`D!xN^m9C~19#`xXc zOOh@730KlhkFLyrc2y>s!na&^3!a%<{Jv*`iL`;!yW4CB&b@x5e53bx#4FymsM4n* zi^BO|1=_Am*EHTx_1fru;DL%5ex0s0tMym!`myieFS&gwPc$Dta#|zzCFjOwY033_ z?sYYPxgIywmqqq*Q}!3}7yKK)WOCX+Z7ct@=KoBYJe@D6?;f6e&+J-*Ly3v85)bnm zf%Hv$h2@_E9*T&x%y3$^X4jV5_**CI64ZnCE8FJ^#Vwfrn<-?^;vF}#|8K3=em&!8 zGwbUIhbPaD*kQ%{i9K_+F(RZAmp;}yv7SYXor!@Vhd_n{hZHo!OZ8HV+GB{O#iCh(bI^#`f zYqsj7?LT=M-oEnENZ^fKy}9t=G5fbE%&WyF-Bfp~{59vFU;L%(DuxYYu3B_S^j;rv00eRgQ|)n{_WXtmfS`@dXbo!%cMFsr+BivHRhhm)8z` zN@wX$(Qi)D-13hv_3+I7duv`q%Af2Iw3)OQl;KvIb3_F>{(^c0U*Q>UC31#SN6K*ONEz$=2CC}gllsjv*qo+ zVs+n5LwQw_`km^36H7Ecr|wBPcDh-i##ylZ``>@|Piwv*U3me@ZyqO1%MLLxFic=% zU{J#~TU}fdpNDklTtQ{+#DiST1_CbcoBnU8=n7!EI6I+!$rRPA8jN>6gu4FKPUdj+ zzWw^lo|~!L!0q7jZEfehqe)}7$c@J_Rg3Tc^SyIfuX*DFN8vSL zmsUu;y{xcL@q8R2FWpV*)nV03cS>YoU@+su-A#h5y^Aj|N-QWyEz-+a8y@X{+e4(z z{gJ&)pr)7DwR`E4l^CU0u8k6MbXmFT)T|qiE4H2MF*Ww{5d2?zK4y-ES{&=Pi3;E5 z+%8{NEYw!uD&p%{5aAhg@3ITG)ZM2?-; zQbpQM2C;gD7%iMRp;)S5)!~$L|K=FV=}E>)TJ39Jb!MfC>xz`5|LfG|?_cC88fR~_ zqy6#X$BWB#9&4U`kY%%P_OZ$Nm-!#huJ}^$GxbxY$o>9x%OBtV@%ru46r)|e_6pXY zjQsdh&3{z}g=n@u^x;@~xM*$h!NW@wypC?}64iA5fBMrQgW^pKR;h5Z{_+q@b$obI zhIzsF>1GM4QxAxQsI^5kxI15(lBs5)sUR4W898&qDu!j2M%9+<+4)Ue@4D(0Xq zhITXS#V$_~Yh|6(;d+wGWPbP5kNkThgH|>k;5p5fbH(AzKSxuKdnaDE&7LP?@kp=h zUyALvEB5DPD!(TuUuU{yti=|1cAxhfX(=1q-72Ng%&y&Qf=?cl`qor-OXRm}GVh+t z9RKHs<$QIUsC{4K($tlHzxQ8WvXqT2vfiM;#{YNZ;*P|#f;EO09@w6FG3VpI2Yb@Y zuinVFIyK?t`ruW_ixxgz5DX|>yKx3CDq>xYlK~Aige$oe9E9) zZ?Jrq{SEo{bN<#2H$=>KZWTWN?Dfw(OA|CBxF#96CeQEgw`i4f58}#vb+FUtT7|&< zz}n@iW%AE5zsxYPIRD^?C$n+7f)=lm^WGXi|E%4)F*`+8&ye~!LuAsV5?SrX>r%gq z7A53QR$1s}8WowjDDu&~2Hf`PC-L~nidl!(W z7cddD$0lJv;a2+k*Im zPY*4*81t)m+mbu0BRaMmVpu!l+;$TK;TQX-_f1=E{rYNw`R4Ssug^DZvO2SS{p~vM z`OTr)Zz^Z#=XJO#YFclq-m1&IwYm1z=G1L>+w=^rj(wk7WzK#sYs2<+_n#Ohh+dbg zo<6IgS;fsfrZext-?w4sp3TcF?#fQq3rbyG!Cre|lgNWhxBBv(Z*M3}m(#iYV%GMK z_t}^HZ1;Y9m-OaQsLXNJr-e0_6u0Kwn;CX4zBlZO{eHI?(<4`3AN^~ZaP;rz>?5xq zc7FQ$_~bUfKMQVTtennmeeHhWAH#_=qpUuJUqKpOtBCT_+tC7Y6mVyPqODRKGiNpJphN=I$$E?q*nWYeGZf zsg9ZnZhqS*#H>@h#ooMZ+AaI*y>ZInx2}qwz2TAjMeeAcfd2but7U>rU8U@j5@w{Ah z+VN#p>s1#1=TfMjs`fN5dGGHVpRN^Kt=#YWLD=d~?UQpqk$Rs!)*`y~fBIMUFfcHj zU|?VnL#v!K^HNeP^fF3vb7K29axobSxKtmkj|h5w^xo;ly;C2sA9*v6Q|0FFJM&)L zpWPr9#T$I4+ULFM(Zt;^Z6kALdgxS4%=G^(CFdq8#jP9H_*iGk(G`aU*G=E-SZ0;7 zB>lR?s@|{Di;`=u+N?cv(yJhV!&yqF!uUf0O_}|X`d#{(h znDuJ$igVu{AT=(M8mcwT)jfRob2Bi=$ucm=qPf2)H77N(I5j>mza+I-ucV@6ZRGoW zX>*~!ati;MXERG#ZWM|1yk&hg-K6wx%mpjMIa?gxpKiLfROQ<4)4C_OuKE4?{n-h3 zQgm_7IyLu$dpCT)cgtz5@$*9E%hi?OzQF7ldqrtxtiV3w6df5Ge_gC zH?5KK8`K}vtL8U3AFJA_b=FD0kgnjNw(b>)9ynfCq9 zcO3V6X1;u9qv6EEf78=TB9aq#d}B&Ku~lg8;n=j3_xO1(NSs;zPQY#A!_vH{2!_7P z`?5m|uduf#&dtx&%}c$>)SI2HRk(U>e(FudsSZ+$KJvC6W>0=I>4v9x?VCN`p68NR z>G@uqmbG(=D`SJjVKWU`hgmv-B2QK`DHW@#t+4Gnec|_FXO2lSmzc%l^@>+Fu*;-M ztzRwi#@TFAb8AsmuyG0FnV_$#Z2op{rN1VAoqg(WxyJdYLaod!2Y<0d2C4F`D3l8Q zFl9qPn{rX`iU6L27nyg+R2|)qwUvz z>O{_nd3(5Zp6uthe)e-^1)rqI@hQYv`71lZarod zxMkX@F9+Wqe&>Dc`@*UOrQq^;ofXr}eQ$gSyJuwD!or)^ef#HHp*H2G8JvM@yxI4z z-pjhK_|)28ds9D{xn0(sC_QzB(c{NTwnZsdW7kQY`Z=ZR*!$h9cJA7>y$}TpN2Y@ zEmMEIWUDEwMYY)i*~?Y8N)_gAZV*nA-(c_LE1j}aWcS*xt^fFz3tvBE@@@nB67F50 zYhOsatts$reG}0a+~1>X#y0K9x~>=tHW}sTSJT9AyjD20CpbgkR_`0e%!f4#cIX^o zQ(v60Vaee))hQQdT?;&*{nELq%Y1LDYqULTmss@Qu`H&(aRnFK_J#G$ z%tq>Y`rkzuv^MC!6FgtDFQ(>dYMa&1!*-8%>FqTB=Jv+q)z43l^`ATQS?Nz*qq)|1 zKkva(T@D442B{4fj_k{hU9F>QHFtg>N4Aiw=|>e+A5r$wz#TP)RtziO&gq`jG4s{W z&yBx@W1pu+7c3FHtR9&*KlP^Yxd!W5N0a|86{>E&p?k_>Tlualm) zzp(wv0F^5t9u-&i-H~^{e7260@##{%>8G6|l)SerEB=`=W!dzkjS+hPCSFQOjyKm% z_hQYH@ZKu#uzBN^&PKCiBAb6l-=1~T?8KEk>#gj!Ha8#Zek!#4Gwynj5& z{c7%1&*_a#2kJ~8v1=7IGA_NmLuu`cppu5L?5)Cy%U@q9Qaar$h!ug5N&w#{qC&`%Pgc7uD^ZY=U98fgl}Vqwb;Um zlR54OuDy2oMW#&gq-@*fqg{6&EnB!Oqh>?VaXHIru^GZ*e|1*0OK)Z0F0yjkd(ZoP zBDq_gA_9ySglw9UI(@$Wy81seQl0m4IC50Y6YQvcIK%#7RS3i8x7}YvwSGHZS{Y&g zYobZzH-EcDza^UQYpf6ERh3?t-Sxio-E{9>vG*D$IvD@^hc(&F-w@Cp8`?GBU=8ot zCDm@N0*jA$oz`@_+jKeA^R0fG zW!yed*c|eRkD7K_iQuoTARENeQ#I@sy-Eq>FnmQix#ry+P%m z`=J@Hej7QieRuVtt+?{H`NtU_^G~aM*T3#=PJm6J(y!IU1`!vuj&J8u^*k40>bg^V zbFcMb zuO0U{n(HVDx&F-vkmAZpPc7}t^A`@ZU!L-c&+@8_9@i(YN(D2CdlJs-Uf z{r~%F@sjh?^{oSE$2oG`wBZeqdwH1A#PE(x$uqx=Q?8oc+R!%b^kU^`56R5pKhOIz z?|HpaO<1^b*|7)C2bR59BJgC-tOWk!2erzp)`kl5OiNq*na`>tc-id@K?Dt$}&aqC*ZAVAX#{4~d#dpc=IiUIS%<{&`ODd}C&MEh8F)6)xxM0)c zTcPToCvQwS&MM2$cr=*#yHM4guglZ(&baBn%>7oXK36gCfN2zOe5dL1qpt;S{V>>c zv+B!PN0p;0dxF`l|9;?tG4nykS)8&>2@pLmpft6;!=HuDg3J6I$Smw-BXM^VJcI3aR1&4 z1)hk%YZs+YUOdnFuiiQROsBLJH>GN4%oEP?IpCA?ck{0u@7vBUH~;f6I=0t7ev818s$@TO+wYFm-N z3D1xJ;8ywIV!mk4jU)O_nrl`vU+U)lyK6zhzwOWXWWRLiUOIE6L7va~$pzCt%ft;X z-M>3~<-))j%V*pyJFzQq-`#~fwSUF3H_S;D{eMsC^sku$4vW>dh}wQX{-%WA@ve_b zu&M028`Vc|9W*WC+qG`$qnGCXkxU!dKXQIt|6gj={)|1!FEzPV?3(=K%E_G9t3Q2Q z{GSQ=Y#^U5SJ0L5pksc(m<>#V2myxwjvzWIKfky{A6bu0s27SJUXU^{2I&FqdV}bJ zUO|tnRbh=CidN8yHn2_xkXC;N1_l(ZDXArinK@9)L25Y|s@W%Ls~#=d$IijP;H1yM zpajv*z{sG;pwb9BjR~6x#hK}Oi6x~)sl|F31qBcnLChiEk7mJB(kC=l&cS_l@Ll%P~Ol0K7ZekLshn1fMJ}?i> zzyL*Uot@Q3*lL&=81gt77-T@EF)%>A+`)(4z~sc@5_HdIvi9kyzI&f@MUH{t$x;Re zbrh5Ags_{GT2Ydk2fFVxJ~=0`7$XEhF(R`pP0F8}fuTbaGNlMI7ZQTuhS&{FE6qzT z0pFpD=G(Igy*ipxmVFWDVqhqXf$XzJ828i$yK$L$nI-WsGts>ba^b#h$Bu9@Gcdg8 zMt7mTJ9Z>sW zsx%KYwjSTl$iTqIj2^c(0ocvT%g;+iH_1a^OLwMBSM6U`28K=n^kiomgxw_273#Rkg$e~Ga$n4bu@MZ zODYR6bFE*bm+rLw$2;>`85n$ck#jBRNVdLA>_$QSX=D_imRXUSqL+bO4zy1DsZ*f) z^<^Ow1A{jgdhprjV>c19e>5JH`p|>#w56kNlE~3VANd#x>x@=e7n!ez#u4&ZjMwVnmI+OX{kl2dC3^*qo#F-)_#XWh08b? z78g9OMm z@Nhn|5Sv+;2})s4ug=e##_Kw`85p`u(DUK>b?Bz#=as?kfJQ67jwkf$Ouq2gYcdxD zgPs+7DxbIu-K3&?#6Dy+qkd-a>h4jmivbl32iVZVI{qk{QK>~mSklj7OGjPt*h1qx zW(I~-4#+v;pdf-o*rF3?hCov^j=(-;>8N|pB)ub^i-AGM06nmM&!8CwDF={}G~__S zM6^Z+E66=y3~B{Dy2ii&-th*>o)9e=Xj*u{%0UE33+r{L7Dx_eQaQAJWIpz_3va zJqwhGGD6}P8d)H}!fI}eV7oLaS?kMpoq69G7#MCdp_hKPvY1Atr{={c=H%!VR3Znz zi;}(0QT^(d+H4FA)`IA*iX1r{<`kvJmy{Odq{bI#R)LNQKsNH@7B!t~_47W~Gczza zbD<}VTPoO%1eL33ZsXfmrRlV?E_V$p1A~hIdeWGrf!iQ(0gdWWkYSAb%DB(6FfhCl zKo9$BJ=}(+7NNQ8Wm2z>;nQ=Lo8%Z6_S{X$M!K8~ z3{uMIh7|>2Hw>08&)T@)za_CtxI|IW3G34qW)Csr~jomO%Esba+q6S+^*+-qJ zeGi{Ch%hj)m!b#T#ANIy7F5P37G$CswU9eTCoZDo*LgMuh6+ja%;{5s-Ke6}lG38Q z%)E3o)7+HobvUGSMgB80F#LfYxr)f@k@eV3gZFpPOarBk+KPuP;_M6zUc%@t;c3kT zOe;n+j%Qz$=KtFFcV00uFzjJP_v)K2T*ko~)~IpdsbsISym*E z*i9=-%qdNc&&UV24Nwh~=9r{?KTpB)I1>XyEGxQiyCz^7h?+#uiZxJO;L_7(6U@xO zu#z3U>p5XErg3PMDVljk`e$`){%yVJ%+0{?L=U|HQJ#)z9;`k^GYFJ;9X?)O$tu9W z;I_=OCgQA9=_G9`AkM&GIt9I<_-GTRX^NZ)Z(uVA_j73mUH#g%F?*s-0hAj+`1%jYV0%{TFHfFKoH!Z$6 zwWPE_FDbDEl2jo%uLdpWp|+guI8e<@$wzHD8#4sz)csgnAjrtT(9MLNJae$<1`pin zB^MV%906%Ji@0yl>6@>&;xG>b!y6U!WUz%3(-GjH0#&4-6&J`xl`p)cWh7Y{ZZ6Eg zu-Xtk#5ajy8kL-%TaZ|kS)89&tcPxzsoW&3hvIC}*@6rV6$a>)i@FvT(~#TX=*HP( z)o5C~Jm>ajXJFWGgx(0hXpL!HN@7W3d~r!pX)+#8;Zztl zGfPtQQm`cu(8VVIKCNTqKqlUge9+g< z%D`|?5IwCabP+ZYEvEK z4Eq((i))*i*i9?S#A?_xxk*~*I>JO5c^DXMRnQw*D$6hpgB+-Vk$9E)Uu$jN`z>l7 zCj&ztMyEDz6BdK=!EG$eECt%`S)M%kTsu1hL#ZHo8^C-Ircuyc*%*$xoYbpx?a`*# zKgtXYf_>;F{Wy$iQgK0Qa%N%`n=Cb#(D{MRt&;XQ|e{i>K~_woYGSLeJNlpRk*g zm{eR+l$Z>@4jtLFD@naNg&ksjE7=$r+yo#?ML_`ss;kfB*0p1okCtxE0<#03|3629U8& zoU7_)FfcHHt`o7F6+WwFeP+G{HCvb=he#rvS;2_i zJdBmRXs!fBNQT@I?HDEo22ECUQ0Wwd8x%EsVV4TcSUlN)(e9LFV-?J zFi1c*Q6rL!K0gk#khbZdgdoUiZ5h^fhZz|dvX~hdv_NLTCp4r52pSikS^;V`p*s^~ z?w^0lUp;1GV0g`nZmyaTVRJKcahZ#L)j7z?ka8?g6uY^QS{8gm5OSe-HK|ue8tnpT zgkc>L_zc6yAK0!?MHn_&7N23@n-L%`gVblBN(BAZJCI?ZmcL4)t_lvrkng}lTq%X^ zA|;SvkT6r%!fqI}6@U?FpqSl>cC`w^v}8TJreTB{wksqMrkymzYZ_9pLCR-r$EG7p zQ#QwL8tP7Zw89j$Cm;QsWrUHg*4T{%@3?^1#i#>?*iH^cn0V9%kBMmK2t!f~#Osf- z95IV9^^+YQQ?b|bsE!5&1Nwoh2;-d{@E8xR20@#0ksS;&5&i5*go$0wcud5o05RQ) zenca}i|l4>rwl?&1{LHXZg@DnKZ8s}KVt}C z;%k4xCSvn6`UyD*6YB#Bn~3gfP+~_v`UGL(k6?TzLJvYg4n&Y~=m&)$jFSw-V;pK> zhZ>Tgjlbw8TOf?xABMwN5euV>c08n_($*laY-PWv diff --git a/doc/PyConDC_2003/bpl.html b/doc/PyConDC_2003/bpl.html deleted file mode 100755 index a9ecebd5..00000000 --- a/doc/PyConDC_2003/bpl.html +++ /dev/null @@ -1,1127 +0,0 @@ - - - - - - -Building Hybrid Systems with Boost.Python - - - - - - - - -
-

Building Hybrid Systems with Boost.Python

- --- - - - - - - - - - - - - - -
Author:David Abrahams
Contact:dave@boost-consulting.com
Organization:Boost Consulting
Date:2003-03-19
Author:Ralf W. Grosse-Kunstleve
Copyright:Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved
- -
-

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.

-
-
-

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 <boost/python.hpp>
-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.hpp>
-BOOST_PYTHON_MODULE(hello)
-{
-    class_<World>("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>("World")
-
-

constructs an unnamed object of type class_<World> 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_<World> 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_<World> 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>("World", init<std::string>())
-    ...
-
-

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>("World", init<std::string>())
-    .def(init<double, double>())
-    ...
-
-

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>("World", init<std::string>())
-    .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>("World", init<std::string>())
-    .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> >("rational_int")
-  .def(init<int, int>()) // constructor, e.g. rational_int(3,4)
-  .def("numerator", &rational<int>::numerator)
-  .def("denominator", &rational<int>::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.

-
-
-

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, bases<Base1,Base2> >("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. -
  3. 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.
  4. -
-

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 "<stdin>", 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<int>(self, "f", x); }
-};
-
-...
-    def("calls_f", calls_f);
-    class_<Base, BaseWrap>("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 is being developed by Bruno da Silva de Oliveira. It 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. It will also allow us the choice to -shift some of the metaprogram code from C++ to Python. We expect that -soon, not only our users but the Boost.Python developers themselves -will be "thinking hybrid" about their own code.

-
-
-
-

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 <string>
-
-struct World
-{
-    World(std::string a_msg) : msg(a_msg) {}
-    std::string greet() const { return msg; }
-    std::string msg;
-};
-
-#include <boost/python.hpp>
-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>("World", init<std::string>())
-        .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<T> class template can be used to convert Python objects -to C++ types:

-
-double x = extract<double>(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.

-
-
-
-

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.

-

python_cpp_mix.jpg

-

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.

-
-
-

Development history

-

The first version of Boost.Python was developed in 2000 by Dave -Abrahams at Dragon Systems, where he was privileged to have Tim Peters -as a guide to "The Zen of Python". One of Dave's jobs was to develop -a Python-based natural language processing system. Since it was -eventually going to be targeting embedded hardware, it was always -assumed that the compute-intensive core would be rewritten in C++ to -optimize speed and memory footprint 1. The project also wanted to -test all of its C++ code using Python test scripts 2. The only -tool we knew of for binding C++ and Python was SWIG, and at the time -its handling of C++ was weak. It would be false to claim any deep -insight into the possible advantages of Boost.Python's approach at -this point. Dave's interest and expertise in fancy C++ template -tricks had just reached the point where he could do some real damage, -and Boost.Python emerged as it did because it filled a need and -because it seemed like a cool thing to try.

-

This early version was aimed at many of the same basic goals we've -described in this paper, differing most-noticeably by having a -slightly more cumbersome syntax and by lack of special support for -operator overloading, pickling, and component-based development. -These last three features were quickly added by Ullrich Koethe and -Ralf Grosse-Kunstleve 3, and other enthusiastic contributors arrived -on the scene to contribute enhancements like support for nested -modules and static member functions.

-

By early 2001 development had stabilized and few new features were -being added, however a disturbing new fact came to light: Ralf had -begun testing Boost.Python on pre-release versions of a compiler using -the EDG front-end, and the mechanism at the core of Boost.Python -responsible for handling conversions between Python and C++ types was -failing to compile. As it turned out, we had been exploiting a very -common bug in the implementation of all the C++ compilers we had -tested. We knew that as C++ compilers rapidly became more -standards-compliant, the library would begin failing on more -platforms. Unfortunately, because the mechanism was so central to the -functioning of the library, fixing the problem looked very difficult.

-

Fortunately, later that year Lawrence Berkeley and later Lawrence -Livermore National labs contracted with Boost Consulting for support -and development of Boost.Python, and there was a new opportunity to -address fundamental issues and ensure a future for the library. A -redesign effort began with the low level type conversion architecture, -building in standards-compliance and support for component-based -development (in contrast to version 1 where conversions had to be -explicitly imported and exported across module boundaries). A new -analysis of the relationship between the Python and C++ objects was -done, resulting in more intuitive handling for C++ lvalues and -rvalues.

-

The emergence of a powerful new type system in Python 2.2 made the -choice of whether to maintain compatibility with Python 1.5.2 easy: -the opportunity to throw away a great deal of elaborate code for -emulating classic Python classes alone was too good to pass up. In -addition, Python iterators and descriptors provided crucial and -elegant tools for representing similar C++ constructs. The -development of the generalized object interface allowed us to -further shield C++ programmers from the dangers and syntactic burdens -of the Python 'C' API. A great number of other features including C++ -exception translation, improved support for overloaded functions, and -most significantly, CallPolicies for handling pointers and -references, were added during this period.

-

In October 2002, version 2 of Boost.Python was released. Development -since then has concentrated on improved support for C++ runtime -polymorphism and smart pointers. Peter Dimov's ingenious -boost::shared_ptr design in particular has allowed us to give the -hybrid developer a consistent interface for moving objects back and -forth across the language barrier without loss of information. At -first, we were concerned that the sophistication and complexity of the -Boost.Python v2 implementation might discourage contributors, but the -emergence of Pyste and several other significant feature -contributions have laid those fears to rest. Daily questions on the -Python C++-sig and a backlog of desired improvements show that the -library is getting used. To us, the future looks bright.

-
-
-

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

Footnotes

- - - - - -
[1]In retrospect, it seems that "thinking hybrid" from the -ground up might have been better for the NLP system: the -natural component boundaries defined by the pure python -prototype turned out to be inappropriate for getting the -desired performance and memory footprint out of the C++ core, -which eventually caused some redesign overhead on the Python -side when the core was moved to C++.
- - - - - -
[2]We also have some reservations about driving all C++ -testing through a Python interface, unless that's the only way -it will be ultimately used. Any transition across language -boundaries with such different object models can inevitably -mask bugs.
- - - - - -
[3]These features were expressed very differently in v1 of -Boost.Python
-
-
- - - - diff --git a/doc/PyConDC_2003/bpl.pdf b/doc/PyConDC_2003/bpl.pdf deleted file mode 100755 index ffd8903e2debb90a96890b5fad941bc5e2c4457d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96642 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 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_ is being developed by Bruno da Silva de Oliveira. It 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. It will also allow us the choice to -shift some of the metaprogram code from C++ to Python. 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 -.. _`Pyste`: http://www.boost.org/libs/python/pyste - ---------------- - 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. - -================= - 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.jpg - -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. - -===================== - Development history -===================== - -The first version of Boost.Python was developed in 2000 by Dave -Abrahams at Dragon Systems, where he was privileged to have Tim Peters -as a guide to "The Zen of Python". One of Dave's jobs was to develop -a Python-based natural language processing system. Since it was -eventually going to be targeting embedded hardware, it was always -assumed that the compute-intensive core would be rewritten in C++ to -optimize speed and memory footprint [#proto]_. The project also wanted to -test all of its C++ code using Python test scripts [#test]_. The only -tool we knew of for binding C++ and Python was SWIG_, and at the time -its handling of C++ was weak. It would be false to claim any deep -insight into the possible advantages of Boost.Python's approach at -this point. Dave's interest and expertise in fancy C++ template -tricks had just reached the point where he could do some real damage, -and Boost.Python emerged as it did because it filled a need and -because it seemed like a cool thing to try. - -This early version was aimed at many of the same basic goals we've -described in this paper, differing most-noticeably by having a -slightly more cumbersome syntax and by lack of special support for -operator overloading, pickling, and component-based development. -These last three features were quickly added by Ullrich Koethe and -Ralf Grosse-Kunstleve [#feature]_, and other enthusiastic contributors arrived -on the scene to contribute enhancements like support for nested -modules and static member functions. - -By early 2001 development had stabilized and few new features were -being added, however a disturbing new fact came to light: Ralf had -begun testing Boost.Python on pre-release versions of a compiler using -the EDG_ front-end, and the mechanism at the core of Boost.Python -responsible for handling conversions between Python and C++ types was -failing to compile. As it turned out, we had been exploiting a very -common bug in the implementation of all the C++ compilers we had -tested. We knew that as C++ compilers rapidly became more -standards-compliant, the library would begin failing on more -platforms. Unfortunately, because the mechanism was so central to the -functioning of the library, fixing the problem looked very difficult. - -Fortunately, later that year Lawrence Berkeley and later Lawrence -Livermore National labs contracted with `Boost Consulting`_ for support -and development of Boost.Python, and there was a new opportunity to -address fundamental issues and ensure a future for the library. A -redesign effort began with the low level type conversion architecture, -building in standards-compliance and support for component-based -development (in contrast to version 1 where conversions had to be -explicitly imported and exported across module boundaries). A new -analysis of the relationship between the Python and C++ objects was -done, resulting in more intuitive handling for C++ lvalues and -rvalues. - -The emergence of a powerful new type system in Python 2.2 made the -choice of whether to maintain compatibility with Python 1.5.2 easy: -the opportunity to throw away a great deal of elaborate code for -emulating classic Python classes alone was too good to pass up. In -addition, Python iterators and descriptors provided crucial and -elegant tools for representing similar C++ constructs. The -development of the generalized ``object`` interface allowed us to -further shield C++ programmers from the dangers and syntactic burdens -of the Python 'C' API. A great number of other features including C++ -exception translation, improved support for overloaded functions, and -most significantly, CallPolicies for handling pointers and -references, were added during this period. - -In October 2002, version 2 of Boost.Python was released. Development -since then has concentrated on improved support for C++ runtime -polymorphism and smart pointers. Peter Dimov's ingenious -``boost::shared_ptr`` design in particular has allowed us to give the -hybrid developer a consistent interface for moving objects back and -forth across the language barrier without loss of information. At -first, we were concerned that the sophistication and complexity of the -Boost.Python v2 implementation might discourage contributors, but the -emergence of Pyste_ and several other significant feature -contributions have laid those fears to rest. Daily questions on the -Python C++-sig and a backlog of desired improvements show that the -library is getting used. To us, the future looks bright. - -.. _`EDG`: http://www.edg.com - -============= - 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 - -=========== - Footnotes -=========== - -.. [#proto] In retrospect, it seems that "thinking hybrid" from the - ground up might have been better for the NLP system: the - natural component boundaries defined by the pure python - prototype turned out to be inappropriate for getting the - desired performance and memory footprint out of the C++ core, - which eventually caused some redesign overhead on the Python - side when the core was moved to C++. - -.. [#test] We also have some reservations about driving all C++ - testing through a Python interface, unless that's the only way - it will be ultimately used. Any transition across language - boundaries with such different object models can inevitably - mask bugs. - -.. [#feature] These features were expressed very differently in v1 of - Boost.Python 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.jpg b/doc/PyConDC_2003/python_cpp_mix.jpg deleted file mode 100755 index 755a9605b8335a1a2ac33b9010e23a1e2c17679c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22831 zcmex=9G120;$SdZs*PMkNL&K}Kdl#{Wkc&0Dr^+rDGxu0w~996fgY#K}{a zE?>EN?fQ+Iw;n!v{N(Ag=PzEq`uOSdm#^Qx|M>X}Pb?HxGHT=yahkYr<3UbkKbJlOVGogFVCF;6+^;41*P~pZ}jBKfWtY{fF*v z^@``m;&`w8XV|#MbJ^eaH`Dj0ch&2k*}uK>pJ(WVrz(Y~=A|UvRT@eNB17`RS8>>m~>9c%)M|b>y@6x zb^U+h{%+mF{~`ME`=)(@*;U~kdV4${o!?m7_S%1Y72IJz${*Nw+!x*wFQVQfls&uqJ^Sky6C&RAJiJi!Y0L3PQLldIA)KK z#3Z-&qSIosli7=N?*uk5{Hk~P&(PHR$Lji@`j6R%#D3{_2?za1UzYW2-A0{l+YU)S zy1Z1-Z`+d?p)+TS8V@m9O??@&{?Pj$TJsO(_t+VISl;r-^x=J(xQg~8Rx>XrZIlYp zxz@#!{x(=-ZbO6iiK7#CE8RYIW);))pUe;DACm7jua~mVUN2bD|Iok7#<1|weCCS1 zxw)yApUsoh&&x}msH^)<%wW2Y--9-tpN-`j3fFhlA2hE|yIcHEV*jK649zv+5BEAh z{Lj#7lUTjtC2#eb7w7XUzeSq7NNRJM#BncTapgL$bq{v;GzfT0F?`|wQEh&R|0l

AHvA79IpJkBwck_?> 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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 e03c1ef7..00000000 --- a/doc/building.html +++ /dev/null @@ -1,429 +0,0 @@ - - - - - - - - - Boost.Python - Building and Testing - - - - - - - - - -
-

-

-
-

Boost.Python

- -

Building and Testing

-
-


- -

Contents

- -
-
Requirements
- -
Building Boost.Python
- -
-
-
Configuration
- -
Configuration for Cygwin GCC - from a Windows prompt
- -
Results
- -
Notes for Cygwin GCC Users
- -
Notes for MinGW (and Cygwin with -mno-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).

- -

Basic 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. Try the default - before attempting to set it yourself.
PYTHON_LIB_PATHpath to Python library object.Autoconfigured from PYTHON_ROOT. Try the default - before attempting to set it yourself.
- -

Configuration for Cygwin GCC from a - Windows prompt

- The following settings may be useful when building with Cygwin GCC (not MinGW) from a Windows command - shell using a Windows build of bjam. If - "bjam -v" does not report "OS=NT", these - settings do not apply to you; you should use the normal configuration variables instead. They are - only useful when building and testing with multiple toolsets on Windows - using a single build command, since Cygwin GCC requires a different build - of Python. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Variable NameSemanticsDefault
CYGWIN_PYTHON_[DEBUG_]VERSIONThe version of python being used under Cygwin.$(PYTHON_VERSION)
CYGWIN_PYTHON_[DEBUG_]ROOTunix-style path containing the include/ directory - containing - python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h.$(PYTHON_ROOT)
CYGWIN_PYTHON_[DEBUG_]LIB_PATHpath containing the user's Cygwin Python import lib - libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.aAutoconfigured from CYGWIN_PYTHON_ROOT
CYGWIN_PYTHON_[DEBUG_]DLL_PATHpath containing the user's Cygwin Python dll - (libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll)/bin
- -

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

- -

Notes for MinGW (and Cygwin with -mno-cygwin) GCC - Users

- -

You will need to create a MinGW-compatible version of the Python - library; the one shipped with Python will only work with a - Microsoft-compatible linker. Follow the instructions in the - "Non-Microsoft" section of the "Building Extensions: Tips And Tricks" - chapter in Installing Python - Modules to create libpythonXX.a, where XX - corresponds to the major and minor version numbers of your Python - installation.

- -

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 your 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 f10493f1..00000000 --- a/doc/index.html +++ /dev/null @@ -1,121 +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)
- -
Internals Documentation
- -
News/Change Log
- -
TODO list
- -
LLNL Progress Reports
- -
Acknowledgments
-
-
- -

Articles

- - "Building Hybrid - Systems With Boost Python", by Dave Abrahams and Ralf - W. Grosse-Kunstleve (PDF) - -
- -

Revised - - 26 August, 2003 - -

- -

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

- - - diff --git a/doc/internals.html b/doc/internals.html deleted file mode 100755 index d777bee9..00000000 --- a/doc/internals.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - -Boost Python Internals - - - - -
-

Boost Python Internals

-

A conversation between Brett Calcott and David Abrahams

- --- - - - -
Copyright:Copyright Brett Calcott and David Abrahams 2003. All -rights reserved.
-

In both of these cases, I'm quite capable of reading code - but the -thing I don't get from scanning the source is a sense of the -architecture, both structurally, and temporally (er, I mean in what -order things go on).

-
    -
  1. What happens when you do the following:

    -
    -struct boring {};
    -...etc...
    -class_<boring>("boring")
    -    ;
    -
    -
  2. -
-

There seems to be a fair bit going on.

-
-
    -
  • Python needs a new ClassType to be registered.
  • -
  • We need to construct a new type that can hold our boring struct.
  • -
  • Inward and outward converters need to be registered for the type.
  • -
-
-

Can you gesture in the general direction where these things are done?

-
-

I only have time for a "off-the-top-of-my-head" answer at the moment; -I suggest you step through the code with a debugger after reading this -to see how it works, fill in details, and make sure I didn't forget -anything.

-
-

A new (Python) subclass of Boost.Python.Instance (see -libs/python/src/object/class.cpp) is created by invoking -Boost.Python.class, the metatype:

-
->>> boring = Boost.Python.class(
-...     'boring'
-...   , bases_tuple       # in this case, just ()
-...   , { 
-...         '__module__' : module_name
-...       , '__doc__' : doc_string # optional
-...     }
-... )
-
-

A handle to this object is stuck in the m_class_object field -of the registration associated with typeid(boring). The -registry will keep that object alive forever, even if you -wipe out the 'boring' attribute of the extension module -(probably not a good thing).

-

Because you didn't specify class<boring, non_copyable, -...>, a to-python converter for boring is registered which -copies its argument into a value_holder held by the the -Python boring object.

-

Because you didn't specify class<boring ...>(no_init), -an __init__ function object is added to the class -dictionary which default-constructs a boring in a -value_holder (because you didn't specify some smart pointer -or derived wrapper class as a holder) held by the Python -boring object.

-

register_class_from_python is used to register a -from-python converter for shared_ptr<boring>. -boost::shared_ptrs are special among smart pointers -because their Deleter argument can be made to manage the -whole Python object, not just the C++ object it contains, no -matter how the C++ object is held.

-

If there were any bases<>, we'd also be registering the -relationship between these base classes and boring in the -up/down cast graph (inheritance.[hpp/cpp]).

-

In earlier versions of the code, we'd be registering lvalue -from-python converters for the class here, but now -from-python conversion for wrapped classes is handled as a -special case, before consulting the registry, if the source -Python object's metaclass is the Boost.Python metaclass.

-

Hmm, that from-python converter probably ought to be handled -the way class converters are, with no explicit conversions -registered.

-
-
-
    -
  1. Can you give a brief overview of the data structures that are -present in the registry

    -
    -

    The registry is simple: it's just a map from typeid -> -registration (see boost/python/converter/registrations.hpp). -lvalue_chain and rvalue_chain are simple endogenous -linked lists.

    -

    If you want to know more, just ask.

    -

    If you want to know about the cast graph, ask me something specific in -a separate message.

    -
    -

    and an overview of the process that happens as a type makes its -way from c++ to python and back again.

    -
  2. -
-
-

Big subject. I suggest some background reading: look for relevant -info in the LLNL progress reports and the messages they link to. -Also,

-
-http://mail.python.org/pipermail/c++-sig/2002-May/001023.html -http://mail.python.org/pipermail/c++-sig/2002-December/003115.html -http://aspn.activestate.com/ASPN/Mail/Message/1280898 -http://mail.python.org/pipermail/c++-sig/2002-July/001755.html
-

from c++ to python:

-
-

It depends on the type and the call policies in use or, for -call<>(...), call_method<>(...), or object(...), if -ref or ptr is used. There are also two basic -categories to to-python conversion, "return value" conversion -(for Python->C++ calls) and "argument" conversion (for -C++->Python calls and explicit object() conversions). The -behavior of these two categories differs subtly in various ways -whose details I forget at the moment. You can probably find -the answers in the above references, and certainly in the code.

-

The "default" case is by-value (copying) conversion, which uses -to_python_value as a to-python converter.

-
-

Since there can sensibly be only one way to convert any type -to python (disregarding the idea of scoped registries for the -moment), it makes sense that to-python conversions can be -handled by specializing a template. If the type is one of -the types handled by a built-in conversion -(builtin_converters.hpp), the corresponding template -specialization of to_python_value gets used.

-

Otherwise, to_python_value uses the m_to_python -function in the registration for the C++ type.

-
-

Other conversions, like by-reference conversions, are only -available for wrapped classes, and are requested explicitly by -using ref(...), ptr(...), or by specifying different -CallPolicies for a call, which can cause a different to-python -converter to be used. These conversions are never registered -anywhere, though they do need to use the registration to find -the Python class corresponding to the C++ type being referred -to. They just build a new Python instance and stick the -appropriate Holder instance in it.

-
-

from python to C++:

-
-

Once again I think there is a distinction between "return value" -and "argument" conversions, and I forget exactly what that is.

-

What happens depends on whether an lvalue conversion is needed -(see http://mail.python.org/pipermail/c++-sig/2002-May/001023.html) -All lvalue conversions are also registered in a type's rvalue -conversion chain, since when an rvalue will do, an lvalue is -certainly good enough.

-

An lvalue conversion can be done in one step (just get me the -pointer to the object - it can be NULL if no conversion is -possible) while an rvalue conversion requires two steps to -support wrapped function overloading and multiple converters for -a given C++ target type: first tell me if a conversion is -possible, then construct the converted object as a second step.

-
-
-
- - - - diff --git a/doc/internals.rst b/doc/internals.rst deleted file mode 100755 index a0b028b9..00000000 --- a/doc/internals.rst +++ /dev/null @@ -1,168 +0,0 @@ -======================== - Boost Python Internals -======================== - -------------------------------------------------------- -A conversation between Brett Calcott and David Abrahams -------------------------------------------------------- - -:copyright: Copyright Brett Calcott and David Abrahams 2003. All - rights reserved. - -In both of these cases, I'm quite capable of reading code - but the -thing I don't get from scanning the source is a sense of the -architecture, both structurally, and temporally (er, I mean in what -order things go on). - -1) What happens when you do the following:: - - struct boring {}; - ...etc... - class_("boring") - ; - -There seems to be a fair bit going on. - - - Python needs a new ClassType to be registered. - - We need to construct a new type that can hold our boring struct. - - Inward and outward converters need to be registered for the type. - -Can you gesture in the general direction where these things are done? - - I only have time for a "off-the-top-of-my-head" answer at the moment; - I suggest you step through the code with a debugger after reading this - to see how it works, fill in details, and make sure I didn't forget - anything. - - A new (Python) subclass of Boost.Python.Instance (see - libs/python/src/object/class.cpp) is created by invoking - Boost.Python.class, the metatype:: - - >>> boring = Boost.Python.class( - ... 'boring' - ... , bases_tuple # in this case, just () - ... , { - ... '__module__' : module_name - ... , '__doc__' : doc_string # optional - ... } - ... ) - - A handle to this object is stuck in the m_class_object field - of the registration associated with ``typeid(boring)``. The - registry will keep that object alive forever, even if you - wipe out the 'boring' attribute of the extension module - (probably not a good thing). - - Because you didn't specify ``class``, a to-python converter for boring is registered which - copies its argument into a value_holder held by the the - Python boring object. - - Because you didn't specify ``class(no_init)``, - an ``__init__`` function object is added to the class - dictionary which default-constructs a boring in a - value_holder (because you didn't specify some smart pointer - or derived wrapper class as a holder) held by the Python - boring object. - - ``register_class_from_python`` is used to register a - from-python converter for ``shared_ptr``. - ``boost::shared_ptr``\ s are special among smart pointers - because their Deleter argument can be made to manage the - whole Python object, not just the C++ object it contains, no - matter how the C++ object is held. - - If there were any ``bases<>``, we'd also be registering the - relationship between these base classes and boring in the - up/down cast graph (``inheritance.[hpp/cpp]``). - - In earlier versions of the code, we'd be registering lvalue - from-python converters for the class here, but now - from-python conversion for wrapped classes is handled as a - special case, before consulting the registry, if the source - Python object's metaclass is the Boost.Python metaclass. - - Hmm, that from-python converter probably ought to be handled - the way class converters are, with no explicit conversions - registered. - -2) Can you give a brief overview of the data structures that are - present in the registry - - The registry is simple: it's just a map from typeid -> - registration (see boost/python/converter/registrations.hpp). - ``lvalue_chain`` and ``rvalue_chain`` are simple endogenous - linked lists. - - If you want to know more, just ask. - - If you want to know about the cast graph, ask me something specific in - a separate message. - - and an overview of the process that happens as a type makes its - way from c++ to python and back again. - - Big subject. I suggest some background reading: look for relevant - info in the LLNL progress reports and the messages they link to. - Also, - - http://mail.python.org/pipermail/c++-sig/2002-May/001023.html - http://mail.python.org/pipermail/c++-sig/2002-December/003115.html - http://aspn.activestate.com/ASPN/Mail/Message/1280898 - http://mail.python.org/pipermail/c++-sig/2002-July/001755.html - - from c++ to python: - - It depends on the type and the call policies in use or, for - ``call<>(...)``, ``call_method<>(...)``, or ``object(...)``, if - ``ref`` or ``ptr`` is used. There are also two basic - categories to to-python conversion, "return value" conversion - (for Python->C++ calls) and "argument" conversion (for - C++->Python calls and explicit ``object()`` conversions). The - behavior of these two categories differs subtly in various ways - whose details I forget at the moment. You can probably find - the answers in the above references, and certainly in the code. - - The "default" case is by-value (copying) conversion, which uses - to_python_value as a to-python converter. - - Since there can sensibly be only one way to convert any type - to python (disregarding the idea of scoped registries for the - moment), it makes sense that to-python conversions can be - handled by specializing a template. If the type is one of - the types handled by a built-in conversion - (builtin_converters.hpp), the corresponding template - specialization of to_python_value gets used. - - Otherwise, to_python_value uses the ``m_to_python`` - function in the registration for the C++ type. - - Other conversions, like by-reference conversions, are only - available for wrapped classes, and are requested explicitly by - using ``ref(...)``, ``ptr(...)``, or by specifying different - CallPolicies for a call, which can cause a different to-python - converter to be used. These conversions are never registered - anywhere, though they do need to use the registration to find - the Python class corresponding to the C++ type being referred - to. They just build a new Python instance and stick the - appropriate Holder instance in it. - - - from python to C++: - - Once again I think there is a distinction between "return value" - and "argument" conversions, and I forget exactly what that is. - - What happens depends on whether an lvalue conversion is needed - (see http://mail.python.org/pipermail/c++-sig/2002-May/001023.html) - All lvalue conversions are also registered in a type's rvalue - conversion chain, since when an rvalue will do, an lvalue is - certainly good enough. - - An lvalue conversion can be done in one step (just get me the - pointer to the object - it can be ``NULL`` if no conversion is - possible) while an rvalue conversion requires two steps to - support wrapped function overloading and multiple converters for - a given C++ target type: first tell me if a conversion is - possible, then construct the converted object as a second step. - 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 a3344e34..00000000 --- a/doc/news.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - Boost.Python - News/Change Log - - - - - - - - - -
-

-

-
-

Boost.Python

- -

News/Change Log

-
-
- -
-
10 August 2003
- -
Added the new properties unit tests contributed by Roman Yakovenko and documented - add_static_property at his urging.
- -
1 August 2003
- -
- Added the new arg class contributed by Nikolay Mladenov which supplies the - ability to wrap functions that can be called with ommitted arguments - in the middle: -
-void f(int x = 0, double y = 3.14, std::string z = std::string("foo"));
-
-BOOST_PYTHON_MODULE(test)
-{
-   def("f", f
-       , (arg("x", 0), arg("y", 3.14), arg("z", "foo")));
-}
- 
-
- And in Python: -
->>> import test
->>> f(0, z = "bar")
->>> f(z = "bar", y = 0.0)
-
- Thanks, Nikolay! -
- -
22 July 2003
- -
Killed the dreaded "bad argument type for builtin operation" error. - Argument errors now show the actual and expected argument types!
- -
19 July 2003
- -
Added the new return_arg policy from Nikolay Mladenov. Thanks, - Nikolay!
- -
18 March, 2003
- -
Gottfried - Ganßauge has contributed opaque pointer support.
- Bruno da Silva de Oliveira - has contributed the exciting Pyste - ("Pie-steh") package.
- -
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 - - 1 August 2003 -

- -

© Copyright Dave - Abrahams 2002-2003. 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 a877cfe0..00000000 --- a/doc/projects.html +++ /dev/null @@ -1,344 +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 .

-
- -

Data Analysis

- -
-
NeuraLab
- -
Neuralab is a data analysis environment specifically tailored for - neural data from Neuralynx - acquisition systems. Neuralab combines presentation quality graphics, a - numerical analysis library, and the Python scripting engine in a single - application. With Neuralab, Neuralynx users can perform common analysis - tasks with just a few mouse clicks. More advanced users can create - custom Python scripts, which can optionally be assigned to menus and - mouse clicks.
-
- -
-
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. -
-
-
- -

Educational

- -
-
Kig
- -
-

KDE Interactive Geometry is a high-school level educational tool, - built for the KDE desktop. It is a nice tool to let students work - with geometrical constructions. It is meant to be the most intuitive, - yet featureful application of its kind.

- -

Versions after 0.6.x (will) support objects built by the user - himself in the Python language. The exporting of the relevant - internal API's were done using Boost.Python, which made the process - very easy.

-
-
- -

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. -
-
- -
Metafaq
- -
- Metafaq, from Transversal, - Inc., is an enterprise level online knowledge base management - system. - -

Ben Young - writes:

- -
- Boost.Python is used in an automated process to generate python - bindings to our api which is exposed though multiple backends and - frontends. This allows us to write quick tests and bespoke scripts - to perform one off tasks without having to go through the full - compilation cycle. -
-
-
- -

Graphics

- -
-
OpenSceneGraph - Bindings
- -
Gideon May has created a - set of bindings for OpenSceneGraph, a cross-platform - C++/OpenGL library for the real-time visualization.
-  
- -
PythonMagick
- -
PythonMagick binds the GraphicsMagick image manipulation - library to Python.
-  
- -
HippoDraw
- -
- 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. - -

Before the web page came online, Paul F. Kunz wrote:

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

-
-
- -
ESSS
- -
- ESSS (Engineering Simulation and Scientific Software) is a company - that provides engineering solutions and acts in the brazilian and - south-american market providing products and services related to - Computational Fluid Dynamics and Image Analysis. - -

Bruno da Silva de Oliveira - writes:

- -
- Recently we moved our work from working exclusively with C++ to an - hybrid-language approach, using Python and C++, with Boost.Python - providing the layer between the two. The results are great so far! -
- -

Two projects have been developed so far with this technology:

- -

Simba - provides 3D visualization of geological formations gattered from the - simulation of the evolution of oil systems, allowing the user to - analyse various aspects of the simulation, like deformation, pressure - and fluids, along the time of the simulation.

- -

Aero - aims to construct a CFD with brazilian technology, which involves - various companies and universities. ESSS is responsible for various - of the application modules, including GUI and post-processing of - results.

-
- -
Rational Discovery - LLC
- -
- Rational Discovery provides computational modeling, combinatorial - library design and custom software development services to the - pharmaceutical, biotech and chemical industries. We do a substantial - amount of internal research to develop new approaches for applying - machine-learning techniques to solve chemical problems. Because we're - a small organization and chemistry is a large and complex field, it - is essential that we be able to quickly and easily prototype and test - new algorithms. - -

For our internal software, we implement core data structures in C - and expose them to Python using Boost.Python. Algorithm development - is done in Python and then translated to C if required (often it's - not). This hybrid development approach not only greatly increases our - productivity, but it also allows "non-developers" (people without C - experience) to take part in method development. Learning C is a - daunting task, but "Python fits your brain." (Thanks to Bruce Eckel - for the quote.)

-
-
- -

Tools

- -
-
Jayacard
- -
- Jayacard aims at developing a secure portable open source operating - system for contactless smart cards and a complete suite of high - quality development tools to ease smart card OS and application - development. - -

The core of the smart card reader management is written in C++ but - all the development tools are written in the friendly Python - language. Boost plays the fundamental role of binding the tools to - our core smart card reader library.

-
-
-
- -

Revised - - 15 July, 2003

- -

© Copyright Dave - Abrahams 2002-2003. 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 2fbebd23..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 9e64ecac..00000000 --- a/doc/tutorial/doc/quickstart.txt +++ /dev/null @@ -1,1996 +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) - ; - -[def Py_Initialize [@http://www.python.org/doc/current/api/initialization.html#l2h-652 Py_Initialize]] -[def Py_Finalize [@http://www.python.org/doc/current/api/initialization.html#l2h-656 Py_Finalize]] -[def PyRun_String [@http://www.python.org/doc/current/api/veryhigh.html#l2h-55 PyRun_String]] -[def PyRun_File [@http://www.python.org/doc/current/api/veryhigh.html#l2h-56 PyRun_File]] -[def Py_eval_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-58 Py_eval_input]] -[def Py_file_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-59 Py_file_input]] -[def Py_single_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-60 Py_single_input]] -[def Py_XINCREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-65 Py_XINCREF]] -[def Py_XDECREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-67 Py_XDECREF]] -[def PyImport_AppendInittab [@http://www.python.org/doc/current/api/importing.html#l2h-137 PyImport_AppendInittab]] -[def PyImport_AddModule [@http://www.python.org/doc/current/api/importing.html#l2h-125 PyImport_AddModule]] -[def PyModule_New [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-591 PyModule_New]] -[def PyModule_GetDict [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-594 PyModule_GetDict]] - -[page:0 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 -[@http://www.python.org/doc/current/api/api.html 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... :-) - -[h2 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.html -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: - -[pre - 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 - boost_python c:\boost\libs\python - $(PYTHON_PROPERTIES) - $(PYTHON_LIB_PATH) - $(PYTHON_EMBEDDED_LIBRARY) ; -] - -[h2 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: - -# '''#include''' [^][br][br] - -# Call Py_Initialize() to start the interpreter and create the [^__main__] module.[br][br] - -# Call other Python C API routines to use the interpreter.[br][br] - -# 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...]]] - -[page:1 Using the interpreter] - -As you probably already know, objects in Python are reference-counted. -Naturally, the [^PyObject]s 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 -[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is -messy and especially hard to get right in the presence of C++ exceptions. -Fortunately Boost.Python provides the [@../../v2/handle.html handle] class -template to automate the process. - -[h2 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 -[@../../v2/handle.html#borrowed-spec 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 [^handle]s, we used -the [@../../v2/handle.html#handle-spec-observers 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. - -[blurb __detail__ [*Handle is a class ['template], so why haven't we been using any template parameters?][br] -[br] -[^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]. -] - -[h2 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 [@http://www.python.org/doc/current/api/veryhigh.html 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: - -[table Start symbols - - [Py_eval_input] [for interpreting isolated expressions] - [Py_file_input] [for interpreting sequences of statements] - [Py_single_input] [for 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__ [*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 [^handle]s. - -[h2 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 [@object_interface.html 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__") )); - dict main_namespace(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( 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(result); - -__note__ [*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. - -[h2 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 [@../../v2/errors.html#error_already_set-spec 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(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 [@http://www.python.org/doc/api/exceptionHandling.html exception handling functions] of the Python/C API in your catch-statement. This can be as simple as calling [@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to print the exception's traceback to the console, or comparing the type of the exception with those of the [@http://www.python.org/doc/api/standardExceptions.html 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 [@http://www.python.org/doc/api/exceptionHandling.html here].) - -If you'd rather not have [^handle] throw a C++ exception when it is constructed, you can use the [@../../v2/handle.html#allow_null-spec 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 - -[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); - ... - -[page General Techniques] - -Here are presented some useful techniques that you can use while wrapping code with Boost.Python. - -[page:1 Creating Packages] - -A Python package is a collection of modules that provide to the user a certain -functionality. If you're not familiar on how to create packages, a good -introduction to them is provided in the -[@http://www.python.org/doc/current/tut/node8.html Python Tutorial]. - -But we are wrapping C++ code, using Boost.Python. How can we provide a nice -package interface to our users? To better explain some concepts, let's work -with an example. - -We have a C++ library that works with sounds: reading and writing various -formats, applying filters to the sound data, etc. It is named (conveniently) -[^sounds]. Our library already has a neat C++ namespace hierarchy, like so: - - sounds::core - sounds::io - sounds::filters - -We would like to present this same hierarchy to the Python user, allowing him -to write code like this: - - import sounds.filters - sounds.filters.echo(...) # echo is a C++ function - -The first step is to write the wrapping code. We have to export each module -separately with Boost.Python, like this: - - /* file core.cpp */ - BOOST_PYTHON_MODULE(core) - { - /* export everything in the sounds::core namespace */ - ... - } - - /* file io.cpp */ - BOOST_PYTHON_MODULE(io) - { - /* export everything in the sounds::io namespace */ - ... - } - - /* file filters.cpp */ - BOOST_PYTHON_MODULE(filters) - { - /* export everything in the sounds::filters namespace */ - ... - } - -Compiling these files will generate the following Python extensions: -[^core.pyd], [^io.pyd] and [^filters.pyd]. - -[blurb __note__ The extension [^.pyd] is used for python extension modules, which -are just shared libraries. Using the default for your system, like [^.so] for -Unix and [^.dll] for Windows, works just as well.] - -Now, we create this directory structure for our Python package: - -[pre - sounds/ - __init__.py - core.pyd - filters.pyd - io.pyd -] - -The file [^__init__.py] is what tells Python that the directory [^sounds/] is -actually a Python package. It can be a empty file, but can also perform some -magic, that will be shown later. - -Now our package is ready. All the user has to do is put [^sounds] into his -[@http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000 PYTHONPATH] and fire up the interpreter: - - >>> import sounds.io - >>> import sounds.filters - >>> sound = sounds.io.open('file.mp3') - >>> new_sound = sounds.filters.echo(sound, 1.0) - -Nice heh? - -This is the simplest way to create hierarchies of packages, but it is not very -flexible. What if we want to add a ['pure] Python function to the filters -package, for instance, one that applies 3 filters in a sound object at once? -Sure, you can do this in C++ and export it, but why not do so in Python? You -don't have to recompile the extension modules, plus it will be easier to write -it. - -If we want this flexibility, we will have to complicate our package hierarchy a -little. First, we will have to change the name of the extension modules: - - /* file core.cpp */ - BOOST_PYTHON_MODULE(_core) - { - ... - /* export everything in the sounds::core namespace */ - } - -Note that we added an underscore to the module name. The filename will have to -be changed to [^_core.pyd] as well, and we do the same to the other extension modules. -Now, we change our package hierarchy like so: - -[pre - sounds/ - __init__.py - core/ - __init__.py - _core.pyd - filters/ - __init__.py - _filters.pyd - io/ - __init__.py - _io.pyd -] - -Note that we created a directory for each extension module, and added a -__init__.py to each one. But if we leave it that way, the user will have to -access the functions in the core module with this syntax: - - >>> import sounds.core._core - >>> sounds.core._core.foo(...) - -which is not what we want. But here enters the [^__init__.py] magic: everything -that is brought to the [^__init__.py] namespace can be accessed directly by the -user. So, all we have to do is bring the entire namespace from [^_core.pyd] -to [^core/__init__.py]. So add this line of code to [^sounds/core/__init__.py]: - - from _core import * - -We do the same for the other packages. Now the user accesses the functions and -classes in the extension modules like before: - - >>> import sounds.filters - >>> sounds.filters.echo(...) - -with the additional benefit that we can easily add pure Python functions to -any module, in a way that the user can't tell the difference between a C++ -function and a Python function. Let's add a ['pure] Python function, -[^echo_noise], to the [^filters] package. This function applies both the -[^echo] and [^noise] filters in sequence in the given [^sound] object. We -create a file named [^sounds/filters/echo_noise.py] and code our function: - - import _filters - def echo_noise(sound): - s = _filters.echo(sound) - s = _filters.noise(sound) - return s - -Next, we add this line to [^sounds/filters/__init__.py]: - - from echo_noise import echo_noise - -And that's it. The user now accesses this function like any other function -from the [^filters] package: - - >>> import sounds.filters - >>> sounds.filters.echo_noise(...) - -[page:1 Extending Wrapped Objects in Python] - -Thanks to Python's flexibility, you can easily add new methods to a class, -even after it was already created: - - >>> class C(object): pass - >>> - >>> # a regular function - >>> def C_str(self): return 'A C instance!' - >>> - >>> # now we turn it in a member function - >>> C.__str__ = C_str - >>> - >>> c = C() - >>> print c - A C instance! - >>> C_str(c) - A C instance! - -Yes, Python rox. :-) - -We can do the same with classes that were wrapped with Boost.Python. Suppose -we have a class [^point] in C++: - - class point {...}; - - BOOST_PYTHON_MODULE(_geom) - { - class_("point")...; - } - -If we are using the technique from the previous session, [@creating_packages.html -Creating Packages], we can code directly into [^geom/__init__.py]: - - from _geom import * - - # a regular function - def point_str(self): - return str((self.x, self.y)) - - # now we turn it into a member function - point.__str__ = point_str - -[*All] point instances created from C++ will also have this member function! -This technique has several advantages: - -* Cut down compile times to zero for these additional functions -* Reduce the memory footprint to virtually zero -* Minimize the need to recompile -* Rapid prototyping (you can move the code to C++ if required without changing the interface) - -You can even add a little syntactic sugar with the use of metaclasses. Let's -create a special metaclass that "injects" methods in other classes. - - # The one Boost.Python uses for all wrapped classes. - # You can use here any class exported by Boost instead of "point" - BoostPythonMetaclass = point.__class__ - - class injector(object): - class __metaclass__(BoostPythonMetaclass): - def __init__(self, name, bases, dict): - for b in bases: - if type(b) not in (self, type): - for k,v in dict.items(): - setattr(b,k,v) - return type.__init__(self, name, bases, dict) - - # inject some methods in the point foo - class more_point(injector, point): - def __repr__(self): - return 'Point(x=%s, y=%s)' % (self.x, self.y) - def foo(self): - print 'foo!' - -Now let's see how it got: - - >>> print point() - Point(x=10, y=10) - >>> point().foo() - foo! - -Another useful idea is to replace constructors with factory functions: - - _point = point - - def point(x=0, y=0): - return _point(x, y) - -In this simple case there is not much gained, but for constructurs with -many overloads and/or arguments this is often a great simplification, again -with virtually zero memory footprint and zero compile-time overhead for -the keyword support. - -[page:1 Reducing Compiling Time] - -If you have ever exported a lot of classes, you know that it takes quite a good -time to compile the Boost.Python wrappers. Plus the memory consumption can -easily become too high. If this is causing you problems, you can split the -class_ definitions in multiple files: - - /* file point.cpp */ - #include - #include - - void export_point() - { - class_("point")...; - } - - /* file triangle.cpp */ - #include - #include - - void export_triangle() - { - class_("triangle")...; - } - -Now you create a file [^main.cpp], which contains the [^BOOST_PYTHON_MODULE] -macro, and call the various export functions inside it. - - void export_point(); - void export_triangle(); - - BOOST_PYTHON_MODULE(_geom) - { - export_point(); - export_triangle(); - } - -Compiling and linking together all this files produces the same result as the -usual approach: - - #include - #include - #include - - BOOST_PYTHON_MODULE(_geom) - { - class_("point")...; - class_("triangle")...; - } - -but the memory is kept under control. - -This method is recommended too if you are developing the C++ library and -exporting it to Python at the same time: changes in a class will only demand -the compilation of a single cpp, instead of the entire wrapper code. - -[blurb __note__ If you're exporting your classes with [@../../../pyste/index.html Pyste], -take a look at the [^--multiple] option, that generates the wrappers in -various files as demonstrated here.] - -[blurb __note__ This method is useful too if you are getting the error message -['"fatal error C1204:Compiler limit:internal structure overflow"] when compiling -a large source file, as explained in the [@../../v2/faq.html#c1204 FAQ].] 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__") ));
-    dict main_namespace(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/acknowledgments.html b/doc/v2/acknowledgments.html deleted file mode 100644 index 3cc24edb..00000000 --- a/doc/v2/acknowledgments.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - Boost.Python - Acknowledgments - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Acknowledgments

-
-


- -

Dave Abrahams is - the architect, designer, and implementor of Boost.Python.

- -

Brett Calcott - contributed and maintains the Visual Studio project files and - documentation.

- -

Gottfried - Ganßauge supplied support for opaque pointer conversions, - complete with documentation and a regression test (and I didn't - even have to ask him for those)! - -

Joel de Guzman implemented the default - argument support and wrote the excellent tutorial documentation.

- -

Ralf W. - Grosse-Kunstleve implemented the pickle - support, and has enthusiastically supported the library since its - birth, contributing to design decisions and providing invaluable - real-world insight into user requirements. Ralf has written some extensions for converting C++ containers that I - hope will be incorporated into the library soon. He also implemented the - cross-module support in the first version of Boost.Python. More - importantly, Ralf makes sure nobody forgets the near-perfect synergy of - C++ and Python for solving the problems of large-scale software - construction.

- -

Aleksey Gurtovoy - wrote an incredible C++ Template - Metaprogramming Library which allows Boost.Python to perform much of - its compile-time magic. In addition, Aleksey very generously contributed - his time and deep knowledge of the quirks of various buggy compilers to - help us get around problems at crucial moments.

- -

Paul Mensonides, - building on the work Vesa - Karvonen, wrote a similarly amazing Preprocessor Metaprogramming - Library, and generously contributed the time and expertise to get it - working in the Boost.Python library, rewriting much of Boost.Python to - use the new preproccessor metaprogramming constructs and helping us to - work around buggy and slow C++ preprocessors.

- -

Bruno da Silva de - Oliveira contributed the ingenious Pyste ("Pie-Steh") - code generator. - -

Nikolay Mladenov contributed - staticmethod support.

- -

Martin Casado solved some sticky problems which allow us to build the - Boost.Python shared library for AIX's crazy dynamic linking model.

- -

Achim Domma contributed some - of the Object Wrappers and - HTML templates for this documentation. Dave Hawkes contributed - inspiration for the use of the scope class to simplify module - definition syntax. Pearu Pearson wrote some of the test cases that are in - the current test suite.

- -

The development of this version of Boost.Python was funded in part by - the Lawrence Livermore National - Laboratories and by the Computational - Crystallography Initiative at Lawrence Berkeley National - Laboratories.

- -

Ullrich - Koethe had independently developed a similar system. When he - discovered Boost.Python v1, he generously contributed countless hours of - coding and much insight into improving it. He is responsible for an early - version of the support for function overloading and wrote the support for - reflecting C++ inheritance relationships. He has helped to improve - error-reporting from both Python and C++ (we hope to do as well in v2 - again soon), and has designed the original support for exposing numeric - operators, including a way to avoid explicit coercion by means of - overloading.

- -

The members of the boost mailing list and the Python community - supplied invaluable early feedback. In particular, Ron Clarke, Mark - Evans, Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott - took the brave step of trying to use Boost.Python while it was still in - early stages of development.

- -

The first version of Boost.Python would not have been possible without - the support of Dragon Systems, which supported its development and - release as a Boost library.

-
- -

Revised - - 26 November, 2002 - -

- -

© Copyright Dave Abrahams 2002. All Rights - Reserved.

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

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/args.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
keyword-expressions
- -
Classes
- -
-
-
class arg
- -
-
-
class arg - synopsis
- -
class arg - constructor
- -
class arg template - operator =
-
-
-
-
- -
Keyword-expression - operator ,
- -
Functions (deprecated)
- -
-
-
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. The keyword-expression - may contain default values for some or all of the keywords it holds

- -

Classes

- -

class arg;

- -

The objects of class arg are keyword-expressions holding one keyword ( - size one )

- -

Class arg synopsis

-
-namespace boost { namespace python
-{
-        struct arg 
-        {
-          template <class T>
-                  arg &perator = (T const &value);
-          explicit arg (char const *name){elements[0].name = name;}
-        };
-
-}}
-
- -

Class arg constructor

-
-arg(char const* name);
-
- -
-
Requires: The argument must be a ntbs.
- -
Effects: Constructs an arg object holding a - keyword with name name.
-
- -

Class arg operator =

-
-template <class T> arg &operator = (T const &value);
-
- -
-
Requires: The argument must convertible to python.
- -
Effects: Assigns default value for the keyword.
- -
Returns: Reference to this.
-
- -

Keyword-expression - operator ,

-
-      keyword-expression operator , (keyword-expression, const arg &kw) const
-      keyword-expression operator , (keyword-expression, const char *name) const;
-
- -
-
Requires: The argument name must be a ntbs.
- -
Effects: Extends the keyword-expression argument with - one more keyword.
- -
Returns: The extended keyword-expression.
-
- -

Functions - (deprecated)

- -

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(double x, double y, double z=0.0, double w=1.0);
-
-BOOST_PYTHON_MODULE(xxx)
-{
-   def("f", f
-            , ( arg("x"), "y", arg("z")=0.0, arg("w")=1.0 ) 
-            );
-}
-
- -

Revised 01 August, 2003

- -

© Copyright Dave Abrahams 2002-2003. 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 d9105e0b..00000000 --- a/doc/v2/class.html +++ /dev/null @@ -1,785 +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);
-
-    // exposing static data members
-    template <class D>
-    class_& def_readonly(char const* name, D const& d);
-    template <class D>
-    class_& def_readwrite(char const* name, D& d);
-
-    // 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);
-
-    template <class Get>
-    void add_static_property(char const* name, Get const& fget);
-    template <class Get, class Set>
-    void add_static_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 Get>
-void add_static_property(char const* name, Get const& fget);
-template <class Get, class Set>
-void add_static_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 Boost.Python.StaticProperty object, - passing object(fget) (and object(fset) in the - second form) to its constructor, then adds that property to the Python - class under construction with the given attribute name. - StaticProperty is a special subclass of Python's property - class which can be called without an initial self - argument.
- -
Returns: *this
- -
Rationale: Allows users to easily expose functions that can - be invoked from Python with static attribute access syntax.
-
-
-
-template <class D>
-class_& def_readonly(char const* name, D T::*pm);
-template <class D>
-class_& def_readonly(char const* name, D const& d);
-
- -
-
Requires: name is an ntbs which conforms to Python's identifier - naming rules.
- -
Effects:
- -
-
-this->add_property(name, make_getter(pm));
-
- and -
-this->add_static_property(name, make_getter(pm));
-
- respectively.
-
-
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' data - member or free variable such that it can be inspected from Python with - a natural syntax.
-
-
-template <class D>
-class_& def_readwrite(char const* name, D T::*pm);
-template <class D>
-class_& def_readwrite(char const* name, D& d);
-
- -
-
Effects:
- -
-
-this->add_property(name, make_getter(pm), make_setter(pm));
-
- and -
-this->add_static_property(name, make_getter(pm), make_setter(pm));
-
- respectively.
-
-
- -
Returns: *this
- -
Rationale: Allows users to easily expose a class' data or - free variable 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 - - 5 August, 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 e6fa8a91..00000000 --- a/doc/v2/data_members.html +++ /dev/null @@ -1,227 +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 D>
-object make_getter(D const& d);
-template <class D, class Policies>
-object make_getter(D const& d, Policies const& policies);
-
-template <class D>
-object make_getter(D const* p);
-template <class D, class Policies>
-object make_getter(D const* p, Policies const& policies);
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Creates a Python callable object which accepts no - arguments and returns d or *p, converted - to_python on demand. 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 reference_existing_object
- -
for Policies.
- -
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.
-
-
-template <class D>
-object make_setter(D& d);
-template <class D, class Policies>
-object make_setter(D& d, Policies const& policies);
-
-template <class D>
-object make_setter(D* p);
-template <class D, class Policies>
-object make_setter(D* p, Policies const& policies);
-
- -
-
Requires: Policies is a model of CallPolicies.
- -
Effects: Creates a Python callable object which accepts one - argument, which is converted from Python to D const& - and written into d or *p, respectively. 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
-
- -

- - 5 August, 2003 -

- -

© 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 e5c24a8b..00000000 --- a/doc/v2/faq.html +++ /dev/null @@ -1,578 +0,0 @@ - - - - - - - - - Boost.Python - FAQ - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Frequently Asked Questions (FAQs)

-
-
- -
- -
How can I wrap a function which takes a - function pointer as an argument?
- -
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?
- -
Compilation takes too much time and eats too much memory! - What can I do to make it faster?
- -
How do I create sub-packages using Boost.Python?
-
-
- -

How can I wrap a function which takes a - function pointer as an argument?

- - If what you're trying to do is something like this: -
-typedef boost::function<void (string s) > funcptr;
-
-void foo(funcptr fp)
-{
-    fp("hello,world!");
-}
-
-BOOST_PYTHON_MODULE(test)
-{
-    def("foo",foo) ;
-}
-
- -And then: - -
->>> def hello(s):
-...    print s 
-...
->>> foo(hello)
-hello, world!
-
- - The short answer is: "you can't". This is not a - Boost.Python limitation so much as a limitation of C++. The - problem is that a Python function is actually data, and the only - way of associating data with a C++ function pointer is to store it - in a static variable of the function. The problem with that is - that you can only associate one piece of data with every C++ - function, and we have no way of compiling a new C++ function - on-the-fly for every Python function you decide to pass - to foo. In other words, this could work if the C++ - function is always going to invoke the same Python - function, but you probably don't want that. - -

If you have the luxury of changing the C++ code you're - wrapping, pass it an object instead and call that; - the overloaded function call operator will invoke the Python - function you pass it behind the object. - -

For more perspective on the issue, see this - posting. - -


- -

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

Compilation takes too much time and eats too - much memory! What can I do to make it faster?

-

- Please refer to the Techniques - section in the tutorial. -

- -

How do I create sub-packages using Boost.Python?

-

- In the Techniques - section of the tutorial this topic is explored. -

- -
- -

Revised - - 18 March, 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 0d5ace16..00000000 --- a/doc/v2/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - Loading index page; if nothing happens, please go to ../index.html. - - - diff --git a/doc/v2/indexing.html b/doc/v2/indexing.html deleted file mode 100644 index b139843b..00000000 --- a/doc/v2/indexing.html +++ /dev/null @@ -1,636 +0,0 @@ - - - - - - - - Indexing Support - - - - - - - - -
-

- C++ Boost -

-
-

- Boost.Python -

- -

Headers <boost/python/indexing/indexing_suite.hpp>
- <boost/python/indexing/vector_indexing_suite.hpp>

-
-
-

- Contents -

-
-
- Introduction -
-
- Interface -
-
-
-
- indexing_suite -
-
- indexing_suite - sub-classes -
-
-
-
- vector_indexing_suite -
-
-
-
-
-
-
-
- indexing_suite class -
-
- vector_indexing_suite - class -
-
-
-

- Introduction -

-

- Indexing is a Boost Python facility for easy exportation of indexable - C++ containers to Python. Indexable containers are containers that - allow random access through the operator[] (e.g. std::vector). -

-

- While Boost Python has all the facilities needed to expose indexable - C++ containers such as the ubiquitous std::vector to Python, the - procedure is not as straightforward as we'd like it to be. Python - containers do not map easily to C++ containers. Emulating Python - containers in C++ (see Python Reference Manual, Emulating - container types) using Boost Python is non trivial. There are a lot - of issues to consider before we can map a C++ container to Python. - These involve implementing wrapper functions for the methods - __len__, __getitem__, - __setitem__, __delitem__, - __iter__ and __contains. -

-

- The goals: -

-
    -
  • -
    - Make indexable C++ containers behave exactly as one would expect a - Python container to behave. -
    -
  • -
  • - Provide default reference semantics for container element indexing - (__getitem__) such that c[i] can be mutable. - Require: -
    -
    -    val = c[i]
    -    c[i].m()
    -    val == c[i]
    -          
    -
    where m is a non-const (mutating) member function - (method). -
  • -
  • - Return safe references from __getitem__ such that subsequent - adds and deletes to and from the container will not result in - dangling references (will not crash Python). -
  • -
  • - Support slice indexes. -
  • -
  • - Accept Python container arguments (e.g. lists, tuples) wherever - appropriate. -
  • -
  • - Allow for extensibility through re-definable policy classes. -
  • -
  • - Provide predefined support for the most common STL and STL like - indexable containers. -
  • -
-
- -

The Boost.Python Indexing Interface

-

indexing_suite [ Header <boost/python/indexing/indexing_suite.hpp> - ]

-

- The indexing_suite class is the base protocol class for the - management of C++ containers intended to be integrated to Python. The - objective is make a C++ container look and feel and behave exactly as - we'd expect a Python container. The class automatically wraps these - special Python methods (taken from the Python reference: Emulating - container types): -

-
-
-
-
- __len__(self) -
-
- Called to implement the built-in function len()  Should return - the length of the object, an integer >= 0. Also, - an object that doesn't define a __nonzero__() method and whose __len__() method returns zero is considered to be - false in a Boolean context.   -
-
-
-
- __getitem__(self, key) -
-
- Called to implement evaluation of - self[key]. For sequence types, - the accepted keys should be integers and slice - objects.  Note that the special - interpretation of negative indexes (if the class wishes to - emulate a sequence type) is up to the __getitem__() method. If key is of - an inappropriate type, TypeError - may be raised; if of a value outside the set of indexes for - the sequence (after any special interpretation of negative - values), IndexError should be - raised. Note: - for loops expect that an IndexError will be raised for illegal - indexes to allow proper detection of the end of the - sequence. -
-
-
-
- __setitem__(self, key, value) -
-
- Called to implement assignment to - self[key]. Same note as for - __getitem__(). This should only be - implemented for mappings if the objects support changes to the - values for keys, or if new keys can be added, or for sequences if - elements can be replaced. The same exceptions should be raised - for improper key values as for the __getitem__() method. -
-
-
-
- __delitem__(self, key) -
-
- Called to implement deletion of - self[key]. Same note as for - __getitem__(). This should only be - implemented for mappings if the objects support removal of keys, - or for sequences if elements can be removed from the sequence. - The same exceptions should be raised for improper key - values as for the __getitem__() method. -
-
-
-
- __iter__(self) -
-
- This method is called when an iterator is required for a - container. This method should return a new iterator object that - can iterate over all the objects in the container. For mappings, - it should iterate over the keys of the container, and should also - be made available as the method iterkeys(). -

- Iterator objects also need to implement this method; they are - required to return themselves. For more information on iterator - objects, see ``Iterator - Types'' in the Python Library Reference. -

-
-
-
-
- __contains__(self, item) -
-
- Called to implement membership test operators. Should return true - if item is in self, false otherwise. For - mapping objects, this should consider the keys of the mapping - rather than the values or the key-item pairs. -
-
-
-
- -

indexing_suite sub-classes

-

- The indexing_suite is not meant to be used as is. A couple of - policy functions must be supplied by subclasses of - indexing_suite. However, a set of indexing_suite - subclasses for the standard indexable STL containers will be provided, - In most cases, we can simply use the available predefined suites. In - some cases, we can refine the predefined suites to suit our needs. -

- -

vector_indexing_suite [ Header <boost/python/indexing/vector_indexing_suite.hpp> - ]

-

- The vector_indexing_suite class is a predefined - indexing_suite derived class designed to wrap - std::vector (and std::vector like [i.e. a class with - std::vector interface]) classes (currently, this is the only predefined - suite available). It provides all the policies required by the - indexing_suite. -

-

- Example usage: -

-
-    class X {...};
-    ...
-
-    class_<std::vector<X> >("XVec")
-        .def(vector_indexing_suite<std::vector<X> >())
-    ;
-
-

- XVec is now a full-fledged Python container (see the - example in full, - along with its python - test). -

-
-

- indexing_suite class -

-

- Class template
- indexing_suite<
- class Container
- , class DerivedPolicies
, - bool NoProxy
- , bool NoProxy,
- , class Element
- , class Key
- , class Index
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Template Parameter
-
- Requirements - - Semantics - - Default -
- Container - - A class type - - The container type to be wrapped to Python. -   - -
- DerivedPolicies - - A subclass of indexing_suite - - Derived classes provide the policy hooks. See DerivedPolicies below. -   - -
- NoProxy - - A boolean - - By default indexed elements have Python reference semantics and are - returned by proxy. This can be disabled by supplying - true in the NoProxy template parameter. - - false -
- Element -   - - - The container's element type. - - Container::value_type -
- Key -   - - - The container's key type. - - Container::value_type -
- Index -   - - - The container's index type. - - Container::size_type -
-
-    template <
class Container - , class DerivedPolicies - , bool NoProxy = false - , class Element = typename Container::value_type - , class Key = typename Container::value_type - , class Index = typename Container::size_type - >
class indexing_suite - : unspecified - { - public: - - indexing_suite(); // default constructor - } -
-

- DerivedPolicies -

-
-
- Derived classes provide the hooks needed by - theindexing_suite: -
-
-
-        static element_type&
-        get_item(Container& container, index_type i);
-
-        static object
-        get_slice(Container& container, index_type from, index_type to);
-
-        static void
-        set_item(Container& container, index_type i, element_type const& v);
-
-        static void
-        set_slice(
-            Container& container, index_type from,
-            index_type to, element_type const& v
-        );
-
-        template <class Iter>
-        static void
set_slice(Container& container, index_type from, - index_type to, Iter first, Iter last - ); - - static void - delete_item(Container& container, index_type i); - - static void - delete_slice(Container& container, index_type from, index_type to); - - static size_t - size(Container& container); - - template <class T> - static bool - contains(Container& container, T const& val); - - static index_type - convert_index(Container& container, PyObject* i); - - static index_type - adjust_index(index_type current, index_type from, - index_type to, size_type len - ); -
-
-

- Most of these policies are self explanatory. However, - convert_index and - adjust_index deserve some explanation. -

-

- convert_index converts a Python index into - a C++ index that the container can handle. For instance, negative - indexes in Python, by convention, start counting from the right(e.g. - C[-1] indexes the rightmost element in C). - convert_index should handle the necessary - conversion for the C++ container (e.g. convert -1 to - C.size()-1). convert_index should - also be able to convert the type of the index (A dynamic Python type) - to the actual type that the C++ container expects. -

-

- When a container expands or contracts, held indexes to its elements - must be adjusted to follow the movement of data. For instance, if we - erase 3 elements, starting from index 0 from a 5 element vector, what - used to be at index 4 will now be at index 1: -

-
-    [a][b][c][d][e] ---> [d][e]
-                 ^           ^
-                 4           1
-
-

- adjust_index takes care of the adjustment. - Given a current index, the function should return the adjusted index - when data in the container at index from..to is - replaced by len elements. -

-
-
-
-

- vector_indexing_suite class -

-

- Class template
- vector_indexing_suite<
- class Container
- , bool NoProxy
- , class DerivedPolicies>
-

- - - - - - - - - - - - - - - - - - - - - - - - - -
- Template Parameter
-
- Requirements - - Semantics - - Default -
- Container - - A class type - - The container type to be wrapped to Python. -   - -
- NoProxy - - A boolean - - By default indexed elements have Python reference semantics and - are returned by proxy. This can be disabled by supplying - true in the NoProxy template parameter. - - false -
- DerivedPolicies - - A subclass of indexing_suite - - The vector_indexing_suite may still be derived to - further tweak any of the predefined policies. Static polymorphism - through CRTP (James Coplien. "Curiously Recurring Template - Pattern". C++ Report, Feb. 1995) enables the base - indexing_suite class to call policy function of the most - derived class -   - -
-
-    template <
class Container,
bool NoProxy = false,
class DerivedPolicies = unspecified_default
class vector_indexing_suite
: public indexing_suite<Container, DerivedPolicies, NoProxy>
{
public:

typedef typename Container::value_type element_type;
typedef typename Container::value_type key_type;
typedef typename Container::size_type index_type;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;

static element_type&
get_item(Container& container, index_type i); - - static object - get_slice(Container& container, index_type from, index_type to); - - static void
set_item(Container& container, index_type i, element_type const& v); - - static void - set_slice(Container& container, index_type from, - index_type to, element_type const& v); - - template <class Iter>
static void
set_slice(Container& container, index_type from,
index_type to, Iter first, Iter last); - - static void - delete_item(Container& container, index_type i); - - static void - delete_slice(Container& container, index_type from, index_type to);
- static size_t - size(Container& container); - - static bool - contains(Container& container, key_type const& key); - - static index_type - convert_index(Container& container, PyObject* i); - - static index_type - adjust_index(index_type current, index_type from, - index_type to, size_type len); - }; -
-
- © Copyright Joel de Guzman 2003. 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. -
- - 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/opaque_pointer_converter.html b/doc/v2/opaque_pointer_converter.html deleted file mode 100644 index 61dbb531..00000000 --- a/doc/v2/opaque_pointer_converter.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - Boost.Python - <boost/python/opaque_pointer_converter.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/opaque_pointer_converter.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class template - opaque_pointer_converter<P>
- -
-
-
Class template - opaque_pointer_converter synopsis
-
-
-
-
- -
Macros
-
-
-
Macro - BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
-
-
- -
Example
- -
See Also
-
-
- -

Classes

- -

Class template - opaque_pointer_converter<P>

- -

opaque_pointer_converter<> is derived from - - to_python_converter - and registers itself as an - - lvalue_from_pytype converter from Python objects - into pointers to undefined types. - Thus it may be used as a converter from opaque pointers into - Python objects and vice versa.

- -

Class template - opaque_pointer_converter synopsis

-
-namespace boost { namespace python
-{
-    template<class Pointer>
-    struct opaque_pointer_converter
-        : to_python_converter<
-          Pointer, opaque_pointer_converter<Pointer> >
-    {
-        explicit opaque_pointer_converter(char const* name);
-    };
-}}
-
- -

Class template - opaque_pointer_converter constructor

-
-explicit opaque_pointer_converter(char const* name);
-
- -
-
Effects: -

Registers the instance as a - - lvalue_from_pytype converter from Python objects - into opaque pointers.

-

The name is used for the type of the Python Objects created; - it should be printable but needn't be an - ntbs because the object type is - not supposed to be user constructible within python scripts.

-
-
- -

Macros

- -

- Macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)

-

This macro must be used to define specializations of the - type_id function - which can't be instantiated for incomplete types.

-

Note

-

In order for this to work in a cross-module environment the macro must - be invoked in every translation unit which uses the - opaque_pointer_converter.

- -

Example

- - please see example for - return_opaque_pointer. - -

See Also

-

- return_opaque_pointer -

- -

Revised - 10 March, 2003 -

- -

© Copyright 2003 Haufe Mediengruppe. 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 edce8596..00000000 --- a/doc/v2/overloads.html +++ /dev/null @@ -1,227 +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, 
-        f_overloads(
-            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 April, 2003 - -

- -

© 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.html b/doc/v2/reference.html deleted file mode 100644 index 9d5e3a63..00000000 --- a/doc/v2/reference.html +++ /dev/null @@ -1,1021 +0,0 @@ - - - - - - - - - Boost.Python - Reference - - - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Reference

-
-
- -

Contents

- -
-
Concepts
- -
High Level Components
- -
Object Wrappers
- -
Function Invocation and Creation
- -
-
-
Models of - CallPolicies
- -
Models of - ResultConverter
- -
Models of - ResultConverterGenerator
-
-
- -
To/From Python Type Conversion
- -
Utility and Infrastructure
- -
Topics
-
-
- - -

Concepts

- -
-
CallPolicies
- -
Dereferenceable
- -
Extractor
- -
HolderGenerator
- -
ResultConverter
- -
ResultConverterGenerator
- -
ObjectWrapper
- -
TypeWrapper
-
- -

High Level Components

- -
-
class.hpp/class_fwd.hpp
- -
-
-
Classes
- -
-
-
class_
- -
bases
-
-
-
-
- -
def.hpp
- -
-
-
Functions
- -
-
-
def
-
-
-
-
- -
enum.hpp
- -
-
-
Classes
- -
-
-
enum_
-
-
-
-
- -
errors.hpp
- -
-
-
Classes
- -
-
-
error_already_set
-
-
- -
Functions
- -
-
-
handle_exception
- -
expect_non_null
- -
throw_error_already_set
-
-
-
-
- -
exception_translator.hpp
- -
-
-
Functions
- -
-
-
register_exception_translator
-
-
-
-
- -
init.hpp
- -
-
-
Classes
- -
-
-
init
- -
optional
-
-
-
-
- -
iterator.hpp
- -
-
-
Classes
- -
-
-
iterator
- -
iterators
-
-
- -
Functions
- -
-
-
range
-
-
-
-
- -
module.hpp
- -
-
-
Macros
- -
-
-
BOOST_PYTHON_MODULE
-
-
-
-
- -
operators.hpp
- -
-
-
Classes
- -
-
-
self_t
- -
other
- -
operator_
-
-
- -
Objects
- -
-
-
self
-
-
-
-
- -
scope.hpp
- -
-
-
Classes
- -
-
-
scope
-
-
-
-
-
- -

Object Wrappers

- -
-
dict.hpp
- -
-
-
Classes
- -
-
-
dict
-
-
-
-
- -
list.hpp
- -
-
-
Classes
- -
-
-
list
-
-
-
-
- -
long.hpp
- -
-
-
Classes
- -
-
-
long_
-
-
-
-
- -
numeric.hpp
- -
-
-
Classes
- -
-
-
numeric::array
-
-
-
-
- -
object.hpp
- -
-
-
Classes
- -
-
-
object
-
-
-
-
- -
str.hpp
- -
-
-
Classes
- -
-
-
str
-
-
-
-
- -
tuple.hpp
- -
-
-
Classes
- -
-
-
tuple
-
-
- -
Functions
- -
-
-
make_tuple
-
-
-
-
-
- -

Function Invocation and Creation

- -
-
args.hpp
- -
-
-
Functions
- -
-
-
args
-
-
-
-
- -
call.hpp
- -
-
-
Functions
- -
-
-
call
-
-
-
-
- -
call_method.hpp
- -
-
-
Functions
- -
-
-
call_method
-
-
-
-
- -
data_members.hpp
- -
-
-
Functions
- -
-
-
make_getter
- -
make_setter
-
-
-
-
- -
make_function.hpp
- -
-
-
Functions
- -
-
-
make_function
- -
make_constructor
-
-
-
-
- -
overloads.hpp
- -
-
-
macros
- -
-
-
BOOST_PYTHON_FUNCTION_OVERLOADS
- -
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
-
-
-
-
- -
ptr.hpp
- -
-
-
Functions
- -
-
-
ptr
-
-
- -
Classes
- -
-
-
pointer_wrapper
-
-
- -
MetaFunctions
- -
-
-
is_pointer_wrapper
- -
unwrap_pointer
-
-
-
-
- -
raw_function.hpp
- -
-
-
Functions
- -
-
-
raw_function
-
-
-
-
- -
- - -

Models of CallPolicies

- -
-
default_call_policies.hpp
- -
-
-
Classes
- -
-
-
default_call_policies
- -
default_result_converter
-
-
-
-
- -
return_arg.hpp
- -
-
-
Classes
- -
-
-
return_arg
- -
return_self
-
-
-
-
- -
return_internal_reference.hpp
- -
-
-
Classes
- -
-
-
- return_internal_reference
-
-
-
-
- -
return_value_policy.hpp
- -
-
-
Classes
- -
-
-
return_value_policy
-
-
-
-
- -
with_custodian_and_ward.hpp
- -
-
-
Classes
- -
-
-
- with_custodian_and_ward
- -
- with_custodian_and_ward_postcall
-
-
-
-
-
- - -

Models of ResultConverter

- -
-
to_python_indirect.hpp
- -
-
-
Classes
- -
-
-
to_python_indirect
-
-
-
-
- -
to_python_value.hpp
- -
-
-
Classes
- -
-
-
to_python_value
-
-
-
-
-
- - -

Models of ResultConverterGenerator

- -
-
copy_const_reference.hpp
- -
-
-
Classes
- -
-
-
copy_const_reference
-
-
-
-
- -
copy_non_const_reference.hpp
- -
-
-
Classes
- -
-
-
- copy_non_const_reference
-
-
-
-
- -
manage_new_object.hpp
- -
-
-
Classes
- -
-
-
manage_new_object
-
-
-
-
- -
reference_existing_object.hpp
- -
-
-
Classes
- -
-
-
- reference_existing_object
-
-
-
-
- -
return_by_value.hpp
- -
-
-
Classes
- -
-
-
return_by_value
-
-
-
-
- -
return_opaque_pointer.hpp
- -
-
-
Classes
- -
-
-
return_opaque_pointer
-
-
-
-
-
-
-
- -

To/From Python Type Conversion

- -
-
extract.hpp
- -
-
-
Classes
- -
-
-
extract
-
-
-
-
- -
implicit.hpp
- -
-
-
Functions
- -
-
-
implicitly_convertible
-
-
-
-
- -
lvalue_from_pytype.hpp
- -
-
-
Classes
- -
-
-
lvalue_from_pytype
- -
extract_identity
- -
extract_member
-
-
-
-
- -
opaque_pointer_converter.hpp
- -
-
-
Classes
- -
-
-
opaque_pointer_converter
-
-
- -
Macros
- -
-
-
- BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
-
-
-
-
- -
to_python_converter.hpp
- -
-
-
Classes
- -
-
-
to_python_converter
-
-
-
-
- -
register_ptr_to_python.hpp
- -
-
-
Functions
- -
-
-
register_ptr_to_python
-
-
-
-
-
- -

Utility and Infrastructure

- -
-
has_back_reference.hpp
- -
-
-
Classes
- -
-
-
has_back_reference
-
-
-
-
- -
instance_holder.hpp
- -
-
-
Classes
- -
-
-
instance_holder
-
-
-
-
- -
pointee.hpp
- -
-
-
Classes
- -
-
-
class template pointee
-
-
-
-
- -
<boost/python.hpp>
- -
handle.hpp
- -
-
-
Classes
- -
-
-
handle
-
-
- -
Functions
- -
-
-
borrowed
- -
allow_null
-
-
-
-
- -
type_id.hpp
- -
-
-
Functions
- -
-
-
type_id
-
-
- -
Classes
- -
-
-
type_info
-
-
-
-
-
- -

Topics

- - -
-
Calling Python Functions and Methods
-
Pickle Support
- Indexing Support
-
-
- -

Revised - - 19 July, 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/register_ptr_to_python.html b/doc/v2/register_ptr_to_python.html deleted file mode 100644 index 68a0737e..00000000 --- a/doc/v2/register_ptr_to_python.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - -Boost.Python - <register_ptr_to_python.hpp> - - - - - - - -
-

-

-
-

Boost.Python

-

Header <register_ptr_to_python.hpp>

-
-
-

Contents

-
-
Introduction
-
Functions
-
-
register_ptr_to_python
-
- -
Example(s)
- -
-
-

Introduction

-

- <boost/python/register_ptr_to_python.hpp> - supplies register_ptr_to_python, a function template - which registers a conversion for smart pointers to Python. The - resulting Python object holds a copy of the converted smart pointer, - but behaves as though it were a wrapped copy of the pointee. If - the pointee type has virtual functions and the class representing - its dynamic (most-derived) type has been wrapped, the Python object - will be an instance of the wrapper for the most-derived type. More than - one smart pointer type for a pointee's class can be registered. -

-

- Note that in order to convert a Python X object to a - smart_ptr<X>& (non-const reference), the embedded C++ - object must be held by smart_ptr<X>, and that when wrapped - objects are created by calling the constructor from Python, how they are held - is determined by the HeldType parameter to - class_<...> instances. -

- -

Functions

-
-template <class P>
-void register_ptr_to_python() 
-
-
-
Requires: P is the type of the smart pointer, - for example smart_ptr<X>. -
-
Effects: Allows conversions to-python of smart_ptr<X> - instances. -
-
- -

Example(s)

- -

C++ Wrapper Code

- -Here is an example of a module that contains a class A with -virtual functions and some functions that work with -boost::shared_ptr<A>. - -
-struct A
-{
-    virtual int f() { return 0; }
-};
-
-shared_ptr<A> New() { return shared_ptr<A>( new A() ); }
-
-int Ok( const shared_ptr<A>& a ) { return a->f(); }
-
-int Fail( shared_ptr<A>& a ) { return a->f(); }
-
-struct A_Wrapper: A
-{
-    A_Wrapper(PyObject* self_): self(self_) {}
-    int f() { return call_method<int>(self, "f"); }    
-    int default_f() { return A::f(); }    
-    PyObject* self;
-};
-
-BOOST_PYTHON_MODULE(register_ptr)
-{
-    class_<A, A_Wrapper>("A")
-        .def("f", &A::f, &A_Wrapper::default_f)
-    ;
-    
-    def("New", &New);
-    def("Ok", &Call);
-    def("Fail", &Fail);
-    
-    register_ptr_to_python< shared_ptr<A> >();
-} 
-
- -

Python Code

- -
->>> from register_ptr import *
->>> a = A()
->>> Ok(a)     # ok, passed as shared_ptr<A>
-0
->>> Fail(a)   # passed as shared_ptr<A>&, and was created in Python!
-Traceback (most recent call last):
-  File "<stdin>", line 1, in ?
-TypeError: bad argument type for built-in operation
->>>
->>> na = New()   # now "na" is actually a shared_ptr<A> 
->>> Ok(a)
-0
->>> Fail(a)
-0
->>>
-
- -If shared_ptr<A> is registered as follows: - -
-    class_<A, A_Wrapper, shared_ptr<A> >("A")
-        .def("f", &A::f, &A_Wrapper::default_f)
-    ;            
-
- -There will be an error when trying to convert shared_ptr<A> to -shared_ptr<A_Wrapper>: - -
->>> a = New()
-Traceback (most recent call last):
-File "<stdin>", line 1, in ?
-TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr<struct A>
->>>    
-
- -

Revised - - 24 Jun, 2003 - -

-

© Copyright Dave Abrahams - 2002. All Rights Reserved.

- - - - diff --git a/doc/v2/return_arg.html b/doc/v2/return_arg.html deleted file mode 100755 index 06c383bc..00000000 --- a/doc/v2/return_arg.html +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - - Boost.Python - <boost/python/return_arg.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header <boost/python/return_arg.hpp>

-
-
- -

Contents

- -
-
Introduction
- -
Classes
- -
-
-
Class Template - return_arg
- -
-
-
Class Template - return_arg synopsis
- -
Class - return_arg static functions
-
-
- -
Class Template - return_self
-
-
- -
Example
-
-
- -

Introduction

- return_arg and return_self instantiations are - models of CallPolicies which return the - specified argument parameter (usually *this) of a wrapped - (member) function. - -

Classes

- -

Class template - return_arg

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- return_arg template parameters -
ParameterRequirementsDescriptionDefault
arg_posA positive compile-time constant of type - std::size_t.the position of the argument to be returned.1
BaseA model of CallPoliciesUsed for policy composition. Any result_converter it - supplies will be overridden by return_arg, but its - precall and postcall policies are composed - as described here CallPolicies.default_call_policies
- -

Class template - return_arg synopsis

-
-namespace boost { namespace python
-{
-   template <size_t arg_pos=1, class Base = default_call_policies>
-   struct return_arg : Base
-   {
-      static PyObject* postcall(PyObject*, PyObject* result);
-      struct result_converter{ template <class T> struct apply; };
-   };
-}}
-
- -

Class return_arg - static functions

-
-PyObject* postcall(PyObject* args, PyObject* result);
-
- -
-
Requires: PyTuple_Check(args) - != 0 and PyTuple_Size(args) != 0
- -
Returns: PyTuple_GetItem(args,arg_pos-1)
-
- -

Class template - return_self

- -

Class template return_self synopsis:

-
-namespace boost { namespace python
-{
-   template <class Base = default_call_policies>
-   struct return_self 
-     : return_arg<1,Base>
-   {};
-}}
-
- -

Example

- -

C++ module definition

-
-#include <boost/python/module.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/return_arg.hpp>
-
-struct Widget
-{
-   Widget() :sensitive_(true){}
-   bool get_sensitive() const { return sensitive_; }
-   void set_sensitive(bool s) { this->sensitive_ = s; }
- private:
-   bool sensitive_;
-};
-
-struct Label : Widget
-{
-   Label() {}
-
-   std::string  get_label() const { return label_; }
-   void set_label(const std::string &l){ label_ = l; }
-
- private:
-   std::string label_;
-};
-
-using namespace boost::python;
-BOOST_PYTHON_MODULE(return_self_ext)
-{
-   class_<widget>("Widget")
-      .def("sensitive", &Widget::get_sensitive)
-      .def("sensitive", &Widget::set_sensitive, return_self<>())
-      ;
-
-   class_<Label, bases<Widget> >("Label")
-      .def("label", &Label::get_label)
-      .def("label", &Label::set_label, return_self<>())
-      ;
-}
-
-
-
- -

Python code

-
->>> from return_self_ext import *
->>> l1 = Label().label("foo").sensitive(false)
->>> l2 = Label().sensitive(false).label("foo") 
-
- -

Revised - - 19 July, 2003 -

- -

© Copyright Dave Abrahams and Nikolay - Mladenov 2003. 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_opaque_pointer.html b/doc/v2/return_opaque_pointer.html deleted file mode 100644 index f50b864f..00000000 --- a/doc/v2/return_opaque_pointer.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - Boost.Python - <boost/python/return_opaque_pointer.hpp> - - - - - - - - - -
-

C++ Boost

-
-

Boost.Python

- -

Header - <boost/python/return_opaque_pointer.hpp>

-
-
- -

Contents

- -
-
Classes
- -
-
-
Class - return_opaque_pointer
- -
-
-
Class - return_opaque_pointer synopsis
- -
Class - return_opaque_pointer metafunctions
-
-
-
-
- -
Example
- -
See Also
-
-
- -

Classes

- -

Class - return_opaque_pointer

- -

return_opaque_pointer is a model of - - ResultConverterGenerator - which can be used to wrap C++ functions returning pointers to - undefined types such that the return value is copied into a - new Python object.

-

In addition to specifying the return_opaque_pointer - policy the - BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID macro must be - used to define specializations for the - type_id function - on the type pointed to by returned pointer.

- -

Class - return_opaque_pointer synopsis

-
-namespace boost { namespace python
-{
-    struct return_opaque_pointer
-    {
-        template <class R> struct apply;
-    };
-}}
-
- -

Class - return_opaque_pointer metafunctions

-
-template <class R> struct apply
-
- -
-
Returns: typedef - detail::opaque_conversion_holder<R> - type;
-
- -

Example

- -

C++ Module Definition

-
-# include <boost/python/return_opaque_pointer.hpp>
-# include <boost/python/def.hpp>
-# include <boost/python/module.hpp>
-# include <boost/python/return_value_policy.hpp>
-
-typedef struct opaque_ *opaque;
-
-opaque the_op   = ((opaque) 0x47110815);
-
-opaque get () { return the_op; }
-void use (opaque op) {
-    if (op != the_op)
-	throw std::runtime_error (std::string ("failed"));
-}
-
-void failuse (opaque op) {
-    if (op == the_op)
-	throw std::runtime_error (std::string ("success"));
-}
-
-BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
-
-namespace bpl = boost::python;
-
-BOOST_PYTHON_MODULE(opaque_ext)
-{
-    bpl::def (
-        "get", &::get, bpl::return_value_policy<bpl::return_opaque_pointer>());
-    bpl::def ("use", &::use);
-    bpl::def ("failuse", &::failuse);
-}
-
- -

Python Code

-
-"""
->>> from opaque_ext import *
->>> #
->>> # Check for correct conversion
->>> use(get())
->>> failuse(get())
-Traceback (most recent call last):
-        ...
-RuntimeError: success
->>> #
->>> # Check that there is no conversion from integers ...
->>> use(0)
-Traceback (most recent call last):
-        ...
-TypeError: bad argument type for built-in operation
->>> #
->>> # ... and from strings to opaque objects
->>> use("")
-Traceback (most recent call last):
-        ...
-TypeError: bad argument type for built-in operation
-"""
-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])
-
- -

See Also

-

- - opaque_pointer_converter -

- -

Revised - 28 January, 2003 -

- -

© Copyright 2003 Haufe Mediengruppe. 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 fcd6618b..00000000 --- a/example/Jamfile.v2 +++ /dev/null @@ -1,10 +0,0 @@ - -use-project /boost/python : ../build ; - -project - : requirements /boost/python//boost_python - ; - -python-extension getting_started1 : getting_started1.cpp : shared ; -python-extension getting_started2 : getting_started2.cpp : shared ; - 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.hpp b/include/boost/python.hpp deleted file mode 100644 index aa552bfe..00000000 --- a/include/boost/python.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. - -// See http://www.boost.org/libs/python for documentation. - -#ifndef PYTHON_DWA2002810_HPP -# define PYTHON_DWA2002810_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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -#endif // PYTHON_DWA2002810_HPP diff --git a/include/boost/python/arg_from_python.hpp b/include/boost/python/arg_from_python.hpp deleted file mode 100755 index 23de5903..00000000 --- a/include/boost/python/arg_from_python.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 ARG_FROM_PYTHON_DWA2002128_HPP -# define ARG_FROM_PYTHON_DWA2002128_HPP - -# include -# 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 aed14276..00000000 --- a/include/boost/python/args.hpp +++ /dev/null @@ -1,160 +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 - -# 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); - } - - keywords operator,(const keywords<1> &k) const - { - python::detail::keywords res; - std::copy(elements, elements+size, res.elements); - res.elements[size] = k.elements[0]; - return res; - } - - keywords operator,(const char *name) const; - - 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 -} - -#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 -class old_edg_workaround_for_arg { friend class arg; }; -#endif - -struct arg : detail::keywords<1> -{ - explicit arg(char const *name) - { - elements[0].name = name; - } - - template - arg& operator=(T const& value) - { - object z(value); - elements[0].default_value = handle<>(python::borrowed(object(value).ptr())); - return *this; - } - - operator detail::keyword const&() const - { - return elements[0]; - } -}; - -namespace detail -{ - template - inline keywords - keywords::operator,(const char *name) const - { - return this->operator,(arg(name)); - } -} - -# 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 f45592ad..00000000 --- a/include/boost/python/args_fwd.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 ARGS_FWD_DWA2002927_HPP -# define ARGS_FWD_DWA2002927_HPP - -# include - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - struct keyword - { - keyword(char const* name_=0) - : name(name_) - {} - - 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 65ea67d5..00000000 --- a/include/boost/python/back_reference.hpp +++ /dev/null @@ -1,103 +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 -# 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 d66f413d..00000000 --- a/include/boost/python/base_type_traits.hpp +++ /dev/null @@ -1,38 +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 - -# include - -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 76fa9cea..00000000 --- a/include/boost/python/bases.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 BASES_DWA2002321_HPP -# define BASES_DWA2002321_HPP - -# include -# 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 8b15a3f7..00000000 --- a/include/boost/python/borrowed.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 BORROWED_DWA2002614_HPP -# define BORROWED_DWA2002614_HPP - -# include -# 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 234a25d0..00000000 --- a/include/boost/python/call.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 CALL_DWA2002411_HPP -# define CALL_DWA2002411_HPP - -# include - -# 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 - ) -{ - PyObject* const result = - 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) - ); - - // This conversion *must not* be done in the same expression as - // the call, because, in the special case where the result is a - // reference a Python object which was created by converting a C++ - // argument for passing to PyEval_CallFunction, its reference - // count will be 2 until the end of the full expression containing - // the conversion, and that interferes with dangling - // pointer/reference detection. - converter::return_from_python converter; - return converter(result); -} - -# undef N - -#endif diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp deleted file mode 100644 index 474552e3..00000000 --- a/include/boost/python/call_method.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 CALL_METHOD_DWA2002411_HPP -# define CALL_METHOD_DWA2002411_HPP - -# include - -# 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 - ) -{ - PyObject* const result = - 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) - ); - - // This conversion *must not* be done in the same expression as - // the call, because, in the special case where the result is a - // reference a Python object which was created by converting a C++ - // argument for passing to PyEval_CallFunction, its reference - // count will be 2 until the end of the full expression containing - // the conversion, and that interferes with dangling - // pointer/reference detection. - converter::return_from_python converter; - return converter(result); -} - -# 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 c54141f0..00000000 --- a/include/boost/python/cast.hpp +++ /dev/null @@ -1,107 +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; - 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 84ac59db..00000000 --- a/include/boost/python/class.hpp +++ /dev/null @@ -1,665 +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 -# include - -# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) || BOOST_WORKAROUND(__GNUC__, < 3) -# define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1 -# endif - -# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING -# include -# include -# endif - -namespace boost { namespace python { - -template class def_visitor; - -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; - - // 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_, SelectHolder, T* = 0) - { - typedef typename SelectHolder::type holder; - force_instantiate(objects::class_cref_wrapper >()); - SelectHolder::register_(); - } - - template - inline void register_class_to_python(mpl::false_, SelectHolder, T* = 0) - { - SelectHolder::register_(); - } - - // - // register_wrapper_class -- register the relationship between a - // virtual function callback wrapper class and the class being - // wrapped. - // - template - inline void register_wrapper_class_impl(T*, T*, int) {} - - template - inline void register_wrapper_class_impl(Wrapper*, T*, ...) - { - objects::register_class_from_python >(); - objects::copy_class_object(type_id(), type_id()); - } - - template - inline void register_wrapper_class(Held* = 0, T* = 0) - { - register_wrapper_class_impl((Held*)0, (T*)0, 0); - } - -# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING - template - struct is_data_member_pointer - : mpl::and_< - is_member_pointer - , mpl::not_ > - > - {}; -# define BOOST_PYTHON_DATA_MEMBER_HELPER , detail::is_data_member_pointer() -# define BOOST_PYTHON_YES_DATA_MEMBER , mpl::true_ -# define BOOST_PYTHON_NO_DATA_MEMBER , mpl::false_ -# elif defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) -# define BOOST_PYTHON_DATA_MEMBER_HELPER , 0 -# define BOOST_PYTHON_YES_DATA_MEMBER , int -# define BOOST_PYTHON_NO_DATA_MEMBER , ... -# else -# define BOOST_PYTHON_DATA_MEMBER_HELPER -# define BOOST_PYTHON_YES_DATA_MEMBER -# define BOOST_PYTHON_NO_DATA_MEMBER -# endif - - 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)); - - // held_type - either T, a class derived from T or a smart pointer - // to a (class derived from) T. - 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 select_holder; - - 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_holder(); - this->def(i); - } - - // 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_holder(); - this->def(i); - } - - public: // member functions - - // Generic visitation - template - self& def(def_visitor const& visitor) - { - visitor.visit(*this); - 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, a callable - // python object, or a generic visitor. - 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; - } - - // - // Data member access - // - template - self& def_readonly(char const* name, D const& d) - { - return this->def_readonly_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER); - } - - template - self& def_readwrite(char const* name, D const& d) - { - return this->def_readwrite_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER); - } - - template - self& def_readonly(char const* name, D& d) - { - return this->def_readonly_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER); - } - - template - self& def_readwrite(char const* name, D& d) - { - return this->def_readwrite_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER); - } - - // 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& add_static_property(char const* name, Get fget) - { - base::add_static_property( - name - , object( - detail::member_function_cast::stage1(fget).stage2((T*)0).stage3(fget) - ) - ); - - return *this; - } - - template - self& add_static_property(char const* name, Get fget, Set fset) - { - base::add_static_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 - - template - self& def_readonly_impl( - char const* name, D B::*pm_ BOOST_PYTHON_YES_DATA_MEMBER) - { - D T::*pm = pm_; - return this->add_property(name, make_getter(pm)); - } - - template - self& def_readwrite_impl( - char const* name, D B::*pm_ BOOST_PYTHON_YES_DATA_MEMBER) - { - D T::*pm = pm_; - return this->add_property(name, make_getter(pm), make_setter(pm)); - } - - template - self& def_readonly_impl( - char const* name, D& d BOOST_PYTHON_NO_DATA_MEMBER) - { - return this->add_static_property(name, make_getter(d)); - } - - template - self& def_readwrite_impl( - char const* name, D& d BOOST_PYTHON_NO_DATA_MEMBER) - { - return this->add_static_property(name, make_getter(d), make_setter(d)); - } - - inline void register_() const; - inline void register_holder(); - - // - // These two overloads discriminate between def() as applied to a - // generic visitor and everything else. - // - template - inline void def_impl( - char const* name - , LeafVisitor - , Helper const& helper - , def_visitor const* v - ) - { - v->visit(*this, name, helper); - } - - 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(); - - typedef BOOST_DEDUCED_TYPENAME select_holder::held_type held_t; - detail::register_wrapper_class(); - - detail::register_class_to_python( - mpl::bool_() - , select_holder() - ); -} - -template -inline void class_::register_holder() -{ - this->register_(); - typedef typename select_holder::type holder; - this->set_instance_size( - objects::additional_instance_size::value - ); -} - -template -inline class_::class_(char const* name, char const* doc) - : base(name, id_vector::size, id_vector().ids, doc) -{ - this->register_holder(); - select_holder::assert_default_constructible(); - 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 - -# undef BOOST_PYTHON_DATA_MEMBER_HELPER -# undef BOOST_PYTHON_YES_DATA_MEMBER -# undef BOOST_PYTHON_NO_DATA_MEMBER -# undef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING - -#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 352e1cd9..00000000 --- a/include/boost/python/class_fwd.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 CLASS_FWD_DWA200222_HPP -# define CLASS_FWD_DWA200222_HPP - -# include -# 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 b17261d0..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 5bd192d5..00000000 --- a/include/boost/python/converter/arg_to_python_base.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 ARG_TO_PYTHON_BASE_DWA200237_HPP -# define ARG_TO_PYTHON_BASE_DWA200237_HPP -# 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 fc4446a0..00000000 --- a/include/boost/python/converter/as_to_python_function.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 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 void convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0) {} - template - static void convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...) {} - - static PyObject* convert(void const* x) - { - convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L); - - // 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 e78eee9a..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 BOOST_PYTHON_LONG_LONG, PyLong_FromLongLong(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_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 c0e27050..00000000 --- a/include/boost/python/converter/from_python.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 FIND_FROM_PYTHON_DWA2002223_HPP -# define FIND_FROM_PYTHON_DWA2002223_HPP - -# 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 1266767d..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 f67ff58d..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 014c9c96..00000000 --- a/include/boost/python/converter/pyobject_type.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 PYOBJECT_TYPE_DWA2002720_HPP -# define PYOBJECT_TYPE_DWA2002720_HPP - -# 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 7b50b919..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 1f2f31e1..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 27988d52..00000000 --- a/include/boost/python/converter/registered.hpp +++ /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. -#ifndef REGISTERED_DWA2002710_HPP -# define REGISTERED_DWA2002710_HPP -# include -# 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 - > -{ -}; - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ - && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) -// collapses a few more types to the same static instance. MSVC7.1 -// fails to strip cv-qualification from array types in typeid. For -// some reason we can't use this collapse there or array converters -// will not be found. -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 8c76a504..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 ae09f53d..00000000 --- a/include/boost/python/converter/registry.hpp +++ /dev/null @@ -1,50 +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 - -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 ac89aad0..00000000 --- a/include/boost/python/converter/shared_ptr_to_python.hpp +++ /dev/null @@ -1,28 +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 (!x) - return python::detail::none(); - else 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 336b1a27..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 b0b96dc6..00000000 --- a/include/boost/python/copy_const_reference.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 COPY_CONST_REFERENCE_DWA2002131_HPP -# define COPY_CONST_REFERENCE_DWA2002131_HPP - -# include -# 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 35beec34..00000000 --- a/include/boost/python/copy_non_const_reference.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 COPY_NON_CONST_REFERENCE_DWA2002131_HPP -# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP - -# include -# 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 e9e84a8b..00000000 --- a/include/boost/python/data_members.hpp +++ /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. -#ifndef DATA_MEMBERS_DWA2002328_HPP -# define DATA_MEMBERS_DWA2002328_HPP - -# include - -# include -# include -# include -# include - -# include - -# include - -# include -# include - -# include -# include -# include - -# include -# include -# include - -# include - -# include - -namespace boost { namespace python { - -// -// This file defines the make_getter and make_setter function -// families, which are responsible for turning pointers, references, -// and pointers-to-data-members into callable Python objects which -// can be used for attribute access on wrapped classes. -// - -namespace detail -{ - // - // Raw Getter and Setter function generators. These class templates - // generate static functions which can be bound together with - // policies and wrapped to generate the python callable objects - // mentioned above. - // - - // - // Generates get and set functions for access through - // pointers-to-data-members - // - 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()); - } - }; - - // - // Generates get and set functions for access through ordinary - // pointers. These are generally used to wrap static data members, - // but can also be used to expose namespace-scope data as class - // attributes. - // - template - struct datum - { - static PyObject* get(Data *p, PyObject* args_, PyObject*, Policies const& policies) - { - // 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( *p ); - - return policies.postcall(args_, result); - } - - static PyObject* set(Data* p, PyObject* args_, PyObject*, Policies const& policies) - { - // check that each of the arguments is convertible - typedef typename add_const::type target1; - typedef typename add_reference::type target; - arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); - - if (!c0.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - *p = c0(PyTuple_GET_ITEM(args_, 0)); - - return policies.postcall(args_, detail::none()); - } - }; - - // - // Helper metafunction for determining the default CallPolicy to use - // for attribute access. If T is a [reference to a] class type X - // whose conversion to python would normally produce a new copy of X - // in a wrapped X class instance (as opposed to types such as - // std::string, which are converted to native Python types, and - // smart pointer types which produce a wrapped class instance of the - // pointee type), to-python conversions will attempt to produce an - // object which refers to the original C++ object, rather than a - // copy. See default_member_getter_policy for rationale. - // - template - struct default_getter_by_ref - : mpl::and_< - mpl::bool_< - to_python_value< - typename add_reference::type>::type - >::uses_registry - > - , is_reference_to_class< - typename add_reference::type>::type - > - > - { - }; - - // Metafunction computing the default CallPolicy to use for reading - // data members - // - // 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_member_getter_policy - : mpl::if_< - default_getter_by_ref - , return_internal_reference<> - , return_value_policy - > - {}; - - // Metafunction computing the default CallPolicy to use for reading - // non-member data. - template - struct default_datum_getter_policy - : mpl::if_< - default_getter_by_ref - , return_value_policy - , return_value_policy - > - {}; - - // - // make_getter helper function family -- These helpers to - // boost::python::make_getter are used to dispatch behavior. The - // third argument is a workaround for a CWPro8 partial ordering bug - // with pointers to data members. It should be convertible to - // mpl::true_ iff the first argument is a pointer-to-member, and - // mpl::false_ otherwise. The fourth argument is for compilers - // which don't support partial ordering at all and should always be - // passed 0L. - // - -#if BOOST_WORKAROUND(__EDG_VERSION__, <= 238) - template - inline object make_getter(D& d, P& p, mpl::false_, ...); -#endif - - // Handle non-member pointers with policies - template - inline object make_getter(D* d, Policies const& policies, mpl::false_, int) - { - return objects::function_object( - objects::py_function( - ::boost::bind( - &detail::datum::get, d, _1, _2 - , policies) - , mpl::vector1() - ) - ); - } - - // Handle non-member pointers without policies - template - inline object make_getter(D* d, not_specified, mpl::false_, long) - { - typedef typename default_datum_getter_policy::type policies; - return detail::make_getter(d, policies(), mpl::false_(), 0); - } - - // Handle pointers-to-members with policies - template - inline object make_getter(D C::*pm, Policies const& policies, mpl::true_, int) - { - return objects::function_object( - objects::py_function( - ::boost::bind( - &detail::member::get, pm, _1, _2 - , policies) - , mpl::vector2() - ) - ); - } - - // Handle pointers-to-members without policies - template - inline object make_getter(D C::*pm, not_specified, mpl::true_, long) - { - typedef typename default_member_getter_policy::type policies; - return detail::make_getter(pm, policies(), mpl::true_(), 0); - } - - // Handle references - template - inline object make_getter(D& d, P& p, mpl::false_, ...) - { - // Just dispatch to the handler for pointer types. - return detail::make_getter(&d, p, mpl::false_(), 0L); - } - - // - // make_setter helper function family -- These helpers to - // boost::python::make_setter are used to dispatch behavior. The - // third argument is for compilers which don't support partial - // ordering at all and should always be passed 0. - // - - - // Handle non-member pointers - template - inline object make_setter(D* p, Policies const& policies, mpl::false_, int) - { - return objects::function_object( - objects::py_function( - ::boost::bind( - &detail::datum::set, p, _1, _2 - , policies) - , mpl::vector2() - ) - ); - } - - // Handle pointers-to-members - template - inline object make_setter(D C::*pm, Policies const& policies, mpl::true_, int) - { - return objects::function_object( - objects::py_function( - ::boost::bind( - &detail::member::set, pm, _1, _2 - , policies) - , mpl::vector3() - ) - ); - } - - // Handle references - template - inline object make_setter(D& x, Policies const& policies, mpl::false_, ...) - { - return detail::make_setter(&x, policies, mpl::false_(), 0L); - } -} - -// -// make_getter function family -- build a callable object which -// retrieves data through the first argument and is appropriate for -// use as the `get' function in Python properties . The second, -// policies argument, is optional. We need both D& and D const& -// overloads in order be able to handle rvalues. -// -template -inline object make_getter(D& d, Policies const& policies) -{ - return detail::make_getter(d, policies, is_member_pointer(), 0L); -} - -template -inline object make_getter(D const& d, Policies const& policies) -{ - return detail::make_getter(d, policies, is_member_pointer(), 0L); -} - -template -inline object make_getter(D& x) -{ - detail::not_specified policy; - return detail::make_getter(x, policy, is_member_pointer(), 0L); -} - -# if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) -template -inline object make_getter(D const& d) -{ - detail::not_specified policy; - return detail::make_getter(d, policy, is_member_pointer(), 0L); -} -# endif - -// -// make_setter function family -- build a callable object which -// writes data through the first argument and is appropriate for -// use as the `set' function in Python properties . The second, -// policies argument, is optional. We need both D& and D const& -// overloads in order be able to handle rvalues. -// -template -inline object make_setter(D& x, Policies const& policies) -{ - return detail::make_setter(x, policies, is_member_pointer(), 0); -} - -template -inline object make_setter(D const& x, Policies const& policies) -{ - return detail::make_setter(x, policies, is_member_pointer(), 0); -} - -template -inline object make_setter(D& x) -{ - return detail::make_setter(x, default_call_policies(), is_member_pointer(), 0); -} - -# if !(BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__EDG_VERSION__, <= 238)) -template -inline object make_setter(D const& x) -{ - return detail::make_setter(x, default_call_policies(), is_member_pointer(), 0); -} -# endif - -}} // 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 894b6e08..00000000 --- a/include/boost/python/def.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 DEF_DWA200292_HPP -# define DEF_DWA200292_HPP - -# include - -# 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/def_visitor.hpp b/include/boost/python/def_visitor.hpp deleted file mode 100755 index 50c510f4..00000000 --- a/include/boost/python/def_visitor.hpp +++ /dev/null @@ -1,87 +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 DEF_VISITOR_DWA2003810_HPP -# define DEF_VISITOR_DWA2003810_HPP - -# include -# include - -namespace boost { namespace python { - -template class def_visitor; -template class class_; - -class def_visitor_access -{ -# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ - || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) - // Tasteless as this may seem, making all members public allows member templates - // to work in the absence of member template friends. - public: -# else - template friend class def_visitor; -# endif - - // unnamed visit, c.f. init<...>, container suites - template - static void visit(V const& v, classT& c) - { - v.derived_visitor().visit(c); - } - - // named visit, c.f. object, pure_virtual - template - static void visit( - V const& v - , classT& c - , char const* name - , OptionalArgs const& options - ) - { - v.derived_visitor().visit(c, name, options); - } - -}; - - -template -class def_visitor -{ - friend class def_visitor_access; - -# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ - || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) - // Tasteless as this may seem, making all members public allows member templates - // to work in the absence of member template friends. - public: -# else - template friend class class_; -# endif - - // unnamed visit, c.f. init<...>, container suites - template - void visit(classT& c) const - { - def_visitor_access::visit(*this, c); - } - - // named visit, c.f. object, pure_virtual - template - void visit(classT& c, char const* name, OptionalArgs const& options) const - { - def_visitor_access::visit(*this, c, name, options); - } - - protected: - DerivedVisitor const& derived_visitor() const - { - return static_cast(*this); - } -}; - -}} // namespace boost::python - -#endif // DEF_VISITOR_DWA2003810_HPP diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp deleted file mode 100644 index 797a00f6..00000000 --- a/include/boost/python/default_call_policies.hpp +++ /dev/null @@ -1,79 +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 8a83bf63..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 14fe9c57..00000000 --- a/include/boost/python/detail/caller.hpp +++ /dev/null @@ -1,189 +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 - -# 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; - -template -struct caller; - -# 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); - } - - static unsigned min_arity() { return N; } - - static signature_element const* signature() - { - return detail::signature::elements(); - } - - 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 142f56c1..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) || defined(__CYGWIN__)) -# 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 e8c91d07..00000000 --- a/include/boost/python/detail/cv_category.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 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< - ::boost::is_const::value - , ::boost::is_volatile::value - > type; -}; - -}}} // namespace boost::python::detail - -#endif // CV_CATEGORY_DWA200222_HPP diff --git a/include/boost/python/detail/dealloc.hpp b/include/boost/python/detail/dealloc.hpp deleted file mode 100644 index dd708bc4..00000000 --- a/include/boost/python/detail/dealloc.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright Gottfried Ganßauge 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 BOOST_PYTHON_DETAIL_DEALLOC_HPP_ -# define BOOST_PYTHON_DETAIL_DEALLOC_HPP_ -namespace boost { namespace python { namespace detail { - extern "C" - { - inline void dealloc(PyObject* self) - { - PyObject_Del(self); - } - } -}}} // namespace boost::python::detail -# endif // BOOST_PYTHON_DETAIL_DEALLOC_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 12ed5099..00000000 --- a/include/boost/python/detail/def_helper.hpp +++ /dev/null @@ -1,213 +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 -# 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/def_helper_fwd.hpp b/include/boost/python/detail/def_helper_fwd.hpp deleted file mode 100755 index 38af07f3..00000000 --- a/include/boost/python/detail/def_helper_fwd.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 DEF_HELPER_FWD_DWA2003810_HPP -# define DEF_HELPER_FWD_DWA2003810_HPP - -# include - -namespace boost { namespace python { namespace detail { - -template -struct def_helper; - -}}} // namespace boost::python::detail - -#endif // DEF_HELPER_FWD_DWA2003810_HPP diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp deleted file mode 100644 index 64ef70cc..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&) - { - 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 4416bdda..00000000 --- a/include/boost/python/detail/defaults_gen.hpp +++ /dev/null @@ -1,389 +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 -#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, ::boost::python::detail::keywords const& keywords) \ - : ::boost::python::detail::overloads_common( \ - doc, keywords.range()) \ - { \ - typedef typename ::boost::python::detail:: \ - error::more_keywords_than_function_arguments< \ - N,n_args>::too_many_keywords assertion; \ - } \ - template \ - fstubs_name(::boost::python::detail::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< \ - N,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 475548b6..00000000 --- a/include/boost/python/detail/destroy.hpp +++ /dev/null @@ -1,107 +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 -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) -# include -# endif -namespace boost { namespace python { namespace detail { - -template < - bool array -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - , bool enum_ // vc7 has a problem destroying enums -# endif - > struct value_destroyer; - -template <> -struct value_destroyer< - false -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - , false -# endif - > -{ - template - static void execute(T const volatile* p) - { - p->T::~T(); - } -}; - -template <> -struct value_destroyer< - true -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - , false -# endif - > -{ - 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 -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - , boost::is_enum::value -# endif - >::execute(p); - } - } - - template - static void execute(T const volatile* p) - { - execute(p, *p); - } -}; - -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) -template <> -struct value_destroyer -{ - template - static void execute(T const volatile*) - { - } -}; - -template <> -struct value_destroyer -{ - template - static void execute(T const volatile*) - { - } -}; -# endif -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) -# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - , (boost::is_enum::value) -# endif - >::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 752cd7d2..00000000 --- a/include/boost/python/detail/indirect_traits.hpp +++ /dev/null @@ -1,472 +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 : mpl::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)); - typedef mpl::bool_ type; - }; -}; - -template -struct is_reference_to_const_helper1 : true_helper1 -{ -}; - -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 ad75b16a..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 27de203a..00000000 --- a/include/boost/python/detail/make_keyword_range_fn.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 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, Arity* = 0) -{ - 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 2c9990fb..00000000 --- a/include/boost/python/detail/msvc_typeinfo.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 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*) -{ - return detail::typeid_ref( - (boost::type*)0, detail::is_ref_tester1(type()) - ); -} - -template <> -inline typeinfo msvc_typeid(boost::type*) -{ - return typeid(void); -} - -# ifndef NDEBUG -inline typeinfo assert_array_typeid_compiles() -{ - return msvc_typeid((boost::type*)0) - , msvc_typeid((boost::type*)0); -} -# 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 49039696..00000000 --- a/include/boost/python/detail/none.hpp +++ /dev/null @@ -1,20 +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 - -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/nullary_function_adaptor.hpp b/include/boost/python/detail/nullary_function_adaptor.hpp deleted file mode 100755 index a63fd82e..00000000 --- a/include/boost/python/detail/nullary_function_adaptor.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 NULLARY_FUNCTION_ADAPTOR_DWA2003824_HPP -# define NULLARY_FUNCTION_ADAPTOR_DWA2003824_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// nullary_function_adaptor -- a class template which ignores its -// arguments and calls a nullary function instead. Used for building -// error-reporting functions, c.f. pure_virtual -template -struct nullary_function_adaptor -{ - nullary_function_adaptor(NullaryFunction fn) - : m_fn(fn) - {} - - void operator()() const { m_fn(); } - -# define BOOST_PP_LOCAL_MACRO(i) \ - template \ - void operator()( \ - BOOST_PP_ENUM_BINARY_PARAMS_Z(1, i, A, const& BOOST_PP_INTERCEPT) \ - ) const \ - { \ - m_fn(); \ - } - -# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) -# include BOOST_PP_LOCAL_ITERATE() - - private: - NullaryFunction m_fn; -}; - -}}} // namespace boost::python::detail - -#endif // NULLARY_FUNCTION_ADAPTOR_DWA2003824_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/prefix.hpp b/include/boost/python/detail/prefix.hpp deleted file mode 100755 index 1e55f428..00000000 --- a/include/boost/python/detail/prefix.hpp +++ /dev/null @@ -1,16 +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 PREFIX_DWA2003531_HPP -# define PREFIX_DWA2003531_HPP - -// The rule is that must be included before any system -// headers (so it can get control over some awful macros). -// Unfortunately, Boost.Python needs to #include first, at -// least... but this gets us as close as possible. -# include -# include - -#endif // PREFIX_DWA2003531_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 3d9540ee..00000000 --- a/include/boost/python/detail/referent_storage.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 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< - ::boost::python::detail::referent_size::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/signature.hpp b/include/boost/python/detail/signature.hpp deleted file mode 100644 index de1bd4a2..00000000 --- a/include/boost/python/detail/signature.hpp +++ /dev/null @@ -1,86 +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 SIGNATURE_DWA20021121_HPP -# define SIGNATURE_DWA20021121_HPP - -# include - -# include -# include -# include - -# include - -# include - -namespace boost { namespace python { namespace detail { - -struct signature_element -{ - char const* basename; - bool lvalue; -}; - -template struct signature_arity; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY + 1, )) -# include BOOST_PP_ITERATE() - -// A metafunction returning the base class used for signature. -template -struct signature_base_select -{ - enum { arity = mpl::size::value - 1 }; - typedef typename signature_arity::template impl type; -}; - -template -struct signature - : signature_base_select::type -{ -}; - -}}} // namespace boost::python::detail - -# endif // SIGNATURE_DWA20021121_HPP - -#else - -# define N BOOST_PP_ITERATION() - -template <> -struct signature_arity -{ - template - struct impl - { - static signature_element const* elements() - { - static signature_element const result[N+2] = { - -# define BOOST_PP_LOCAL_MACRO(i) \ - { \ - type_id::type>().name() \ - , is_reference_to_non_const::type>::value \ - }, - -# define BOOST_PP_LOCAL_LIMITS (0, N) -# include BOOST_PP_LOCAL_ITERATE() - {0,0} - }; - return result; - } - }; -}; - -#endif // BOOST_PP_IS_ITERATING - - 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 0791fb28..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 vector 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 545664f9..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::vector,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::vector,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 280db11e..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::vector,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 07c5d3a5..00000000 --- a/include/boost/python/detail/void_ptr.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 VOID_PTR_DWA200239_HPP -# define VOID_PTR_DWA200239_HPP - -# include - -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 ecd77810..00000000 --- a/include/boost/python/detail/wrap_python.hpp +++ /dev/null @@ -1,167 +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 - -#if defined(HAVE_LONG_LONG) -# if defined(PY_LONG_LONG) -# define BOOST_PYTHON_LONG_LONG PY_LONG_LONG -# elif defined(LONG_LONG) -# define BOOST_PYTHON_LONG_LONG LONG_LONG -# else -# error "HAVE_LONG_LONG defined but not PY_LONG_LONG or LONG_LONG" -# endif -#endif diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp deleted file mode 100644 index 63a672af..00000000 --- a/include/boost/python/dict.hpp +++ /dev/null @@ -1,153 +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 -#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 10ea1711..00000000 --- a/include/boost/python/enum.hpp +++ /dev/null @@ -1,103 +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 -# 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 424baf71..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 - -namespace boost { namespace python { - -struct BOOST_PYTHON_DECL error_already_set -{ - virtual ~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_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 d6eff8a6..00000000 --- a/include/boost/python/exception_translator.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 EXCEPTION_TRANSLATOR_DWA2002810_HPP -# define EXCEPTION_TRANSLATOR_DWA2002810_HPP - -# include - -# 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 bcc83aa9..00000000 --- a/include/boost/python/extract.hpp +++ /dev/null @@ -1,248 +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 -# 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 fee589bf..00000000 --- a/include/boost/python/handle.hpp +++ /dev/null @@ -1,247 +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) - { - python::xdecref(m_p); - m_p = python::xincref(r.m_p); - return *this; - } - -#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 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 621c91e6..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 7d8a6500..00000000 --- a/include/boost/python/has_back_reference.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 HAS_BACK_REFERENCE_DWA2002323_HPP -# define HAS_BACK_REFERENCE_DWA2002323_HPP - -# include -# include - -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 - : mpl::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 668f6aba..00000000 --- a/include/boost/python/implicit.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 IMPLICIT_DWA2002325_HPP -# define IMPLICIT_DWA2002325_HPP - -# include -# 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 97da2f3b..00000000 --- a/include/boost/python/init.hpp +++ /dev/null @@ -1,424 +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 - -/////////////////////////////////////////////////////////////////////////////// -#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; - }; - -#else - - template - struct is_optional - : mpl::false_ - {}; - - template - struct is_optional > - : mpl::true_ - {}; - -#endif - - template - struct define_class_init_helper; - -} // namespace detail - -template -struct init_base : def_visitor -{ - 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: - // visit - // - // Defines a set of n_defaults + 1 constructors for its - // class_<...> argument. 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 visit(classT& cl) const - { - typedef typename DerivedT::signature signature; - typedef typename DerivedT::n_arguments n_arguments; - typedef typename DerivedT::n_defaults n_defaults; - - detail::define_class_init_helper::apply( - cl - , derived().call_policies() - , signature() - , n_arguments() - , derived().doc_string() - , derived().keywords()); - } - - friend class python::def_visitor_access; - - 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: - typedef typename InitT::n_arguments n_arguments; - typedef typename InitT::n_defaults n_defaults; - typedef typename InitT::signature signature; - - 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; -}; - -// -// drop1 is the initial length(S) elements of S -// -namespace detail -{ - template - struct drop1 - : mpl::iterator_range< - typename mpl::begin::type - , typename mpl::prior< - typename mpl::end::type - >::type - > - {}; -} - -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_, detail::keywords const& kw) - : base(doc_, kw.range()) - { - typedef typename detail::error::more_keywords_than_init_arguments< - N, n_arguments::value - >::too_many_keywords assertion; - } - - template - init(detail::keywords const& kw, char const* doc_ = 0) - : base(doc_, kw.range()) - { - typedef typename detail::error::more_keywords_than_init_arguments< - N, n_arguments::value - >::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 detail::is_optional< - typename mpl::apply_if< - mpl::empty - , mpl::false_ - , mpl::back - >::type - > back_is_optional; - - typedef typename mpl::apply_if< - back_is_optional - , mpl::back - , mpl::vector0<> - >::type optional_args; - - typedef typename mpl::apply_if< - back_is_optional - , mpl::if_< - mpl::empty - , detail::drop1 - , mpl::joint_view< - detail::drop1 - , optional_args - > - > - , signature_ - >::type signature; - - // TODO: static assert to make sure there are no other optional elements - - // Count the number of default args - typedef mpl::size n_defaults; - typedef mpl::size n_arguments; -}; - -/////////////////////////////////////////////////////////////////////////////// -// -// optional -// -// optional::type returns a typelist. -// -/////////////////////////////////////////////////////////////////////////////// -template -struct optional - : detail::type_list -{ -}; - -namespace detail -{ - template - inline void def_init_aux( - ClassT& cl - , Signature const& - , NArgs - , CallPoliciesT const& policies - , char const* doc - , detail::keyword_range const& keywords_ - ) - { - typedef typename ClassT::select_holder selector_t; - - cl.def( - "__init__", - detail::make_keyword_range_constructor( - policies - , keywords_ - , selector_t::get() - ) - , 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 fewer argument (the - // rightmost argument is shaved off) - // - /////////////////////////////////////////////////////////////////////////////// - template - struct define_class_init_helper - { - - template - static void apply( - ClassT& cl - , CallPoliciesT const& policies - , Signature const& args - , NArgs - , char const* doc - , detail::keyword_range keywords) - { - detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords); - - if (keywords.second > keywords.first) - --keywords.second; - - typedef typename mpl::prior::type next_nargs; - define_class_init_helper::apply( - cl, policies, Signature(), next_nargs(), 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 - , Signature const& args - , NArgs - , char const* doc - , detail::keyword_range const& keywords) - { - def_init_aux(cl, args, NArgs(), policies, doc, 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 0c5a60c2..00000000 --- a/include/boost/python/instance_holder.hpp +++ /dev/null @@ -1,58 +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 7fa000f8..00000000 --- a/include/boost/python/iterator.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 ITERATOR_DWA2002512_HPP -# define ITERATOR_DWA2002512_HPP - -# include - -# 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 eaeaa51e..00000000 --- a/include/boost/python/list.hpp +++ /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. -#ifndef LIST_DWA2002627_HPP -# define LIST_DWA2002627_HPP - -# include - -# 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 fbf1dd85..00000000 --- a/include/boost/python/long.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 LONG_DWA2002627_HPP -# define LONG_DWA2002627_HPP - -# include - -# 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 443f94c3..00000000 --- a/include/boost/python/lvalue_from_pytype.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 LVALUE_FROM_PYTYPE_DWA2002130_HPP -# define LVALUE_FROM_PYTYPE_DWA2002130_HPP - -# include - -# 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 91db7c88..00000000 --- a/include/boost/python/make_function.hpp +++ /dev/null @@ -1,104 +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 -# 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) - ); - } - - // 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) - , 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 97cd911a..00000000 --- a/include/boost/python/manage_new_object.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 MANAGE_NEW_OBJECT_DWA200222_HPP -# define MANAGE_NEW_OBJECT_DWA200222_HPP - -# include -# 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 f97d9470..00000000 --- a/include/boost/python/module.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 MODULE_DWA2001128_HPP -# define MODULE_DWA2001128_HPP - -# include - -# 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 39162e25..00000000 --- a/include/boost/python/module_init.hpp +++ /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. -#ifndef MODULE_INIT_DWA20020722_HPP -# define MODULE_INIT_DWA20020722_HPP - -# 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 b7fc1c64..00000000 --- a/include/boost/python/numeric.hpp +++ /dev/null @@ -1,233 +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 -# 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 a367ed1c..00000000 --- a/include/boost/python/object.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_DWA2002612_HPP -# define OBJECT_DWA2002612_HPP - -# include -# include -# include -# include -# include -# include -# include - -#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 6a862b3d..00000000 --- a/include/boost/python/object/add_to_namespace.hpp +++ /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. -#ifndef ADD_TO_NAMESPACE_DWA200286_HPP -# define ADD_TO_NAMESPACE_DWA200286_HPP - -# 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 45bffbf7..00000000 --- a/include/boost/python/object/class.hpp +++ /dev/null @@ -1,65 +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 - -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: - void add_property(char const* name, object const& fget); - void add_property(char const* name, object const& fget, object const& fset); - - void add_static_property(char const* name, object const& fget); - void add_static_property(char const* name, object const& fget, object const& fset); - - // Retrieve the underlying object - 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); -}; - -BOOST_PYTHON_DECL void copy_class_object(type_info const& src, type_info const& dst); - -}}} // 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 b9cf4a43..00000000 --- a/include/boost/python/object/class_converters.hpp +++ /dev/null @@ -1,90 +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 - -# 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_< -# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - mpl::true_ -# else - is_polymorphic -# endif - , 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 bf21aa2a..00000000 --- a/include/boost/python/object/forward.hpp +++ /dev/null @@ -1,197 +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 -# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) -# include -# include -# include -# endif - -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) {} - reference get() 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_< -# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) - // vc6 chokes on unforwarding enums nested in classes - mpl::and_< - is_scalar - , mpl::not_< - is_enum - > - > -# else - is_scalar -# endif - , T - , reference_to_value - > -{ -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct unforward -{ - typedef typename unwrap_reference::type& type; -}; - -template -struct unforward > -{ - typedef T type; -}; - -template -struct unforward_cref - : add_reference< - typename add_const< - typename unwrap_reference::type - >::type - > -{ -}; - -template -struct unforward_cref > - : add_reference::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 - struct cref_unforwarder - { - template - struct apply - : add_reference< - typename add_const< - typename unwrap_reference::type - >::type - > - { - }; - }; - - template<> - struct cref_unforwarder - { - template - struct apply - : add_reference< - typename add_const< - typename T::reference - >::type - > - { - }; - }; - - template - struct is_reference_to_value - { - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(is_reference_to_value_test(boost::type())) - == sizeof(yes_reference_to_value_t))); - typedef mpl::bool_ type; - }; -} - -template -struct unforward - : public detail::unforwarder< - detail::is_reference_to_value::value - >::template apply -{}; - -template -struct unforward_cref - : public detail::cref_unforwarder< - detail::is_reference_to_value::value - >::template apply -{}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -template -typename reference_to_value::reference -do_unforward(reference_to_value const& x, int) -{ - return x.get(); -} - -template -typename reference_wrapper::type& -do_unforward(reference_wrapper const& x, int) -{ - return x.get(); -} - -template -T const& do_unforward(T const& x, ...) -{ - return x; -} - -}}} // 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 9a3e0818..00000000 --- a/include/boost/python/object/function.hpp +++ /dev/null @@ -1,77 +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 - -namespace boost { namespace python { namespace objects { - -struct BOOST_PYTHON_DECL function : PyObject -{ - function( - py_function const& - , 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; - handle m_overloads; - object m_name; - object m_namespace; - object m_doc; - object m_arg_names; - unsigned m_nkeyword_values; -}; - -// -// 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 67896336..00000000 --- a/include/boost/python/object/function_handle.hpp +++ /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. -#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); - -// 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() - ) - ); -} - -// 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 0bf91669..00000000 --- a/include/boost/python/object/function_object.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 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 - , python::detail::keyword_range const&); - - BOOST_PYTHON_DECL api::object function_object( - py_function const& f - , python::detail::keyword_range const&); - - BOOST_PYTHON_DECL api::object function_object(py_function const& f); - - // 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 68295f62..00000000 --- a/include/boost/python/object/inheritance.hpp +++ /dev/null @@ -1,133 +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 is_downcast); - -// -// 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 - : mpl::if_< - boost::is_polymorphic - , boost::python::objects::polymorphic_id_generator - , boost::python::objects::non_polymorphic_id_generator - > -{}; - -// 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 - : mpl::if_< - is_base_and_derived - , implicit_cast_generator - , dynamic_cast_generator - > -{ -}; - -template -inline void register_conversion( - bool is_downcast = ::boost::is_base_and_derived::value - // 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/inheritance_query.hpp b/include/boost/python/object/inheritance_query.hpp deleted file mode 100755 index de476f2d..00000000 --- a/include/boost/python/object/inheritance_query.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 INHERITANCE_QUERY_DWA2003520_HPP -# define INHERITANCE_QUERY_DWA2003520_HPP - -# include - -namespace boost { namespace python { namespace objects { - -BOOST_PYTHON_DECL void* find_static_type(void* p, type_info src, type_info dst); -BOOST_PYTHON_DECL void* find_dynamic_type(void* p, type_info src, type_info dst); - -}}} // namespace boost::python::object - -#endif // INHERITANCE_QUERY_DWA2003520_HPP diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp deleted file mode 100644 index 8b4e45f0..00000000 --- a/include/boost/python/object/instance.hpp +++ /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. -#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; - - typedef typename type_with_alignment< - ::boost::alignment_of::value - >::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 af7f68aa..00000000 --- a/include/boost/python/object/iterator.hpp +++ /dev/null @@ -1,248 +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 -# 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( - py_function( - bind(&detail::iterator_next::execute, _1, _2, policies) - , mpl::vector2< -# if defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - object -# else - typename boost::detail::iterator_traits::value_type -# endif - , Iterator - >() - ) - ); - - 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( - py_function( - boost::bind( - &make_iterator_help< - Target,Iterator,Accessor1,Accessor2,NextPolicies - >::create - , get_start, get_finish, _1, _2) - , mpl::vector2() - ) - ); - } - - 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 67442166..00000000 --- a/include/boost/python/object/iterator_core.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 ITERATOR_CORE_DWA2002512_HPP -# define ITERATOR_CORE_DWA2002512_HPP - -# 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 af520006..00000000 --- a/include/boost/python/object/life_support.hpp +++ /dev/null @@ -1,16 +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 - -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 91a0d455..00000000 --- a/include/boost/python/object/make_holder.hpp +++ /dev/null @@ -1,95 +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 68e7b379..00000000 --- a/include/boost/python/object/make_instance.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 MAKE_INSTANCE_DWA200296_HPP -# define MAKE_INSTANCE_DWA200296_HPP - -# include -# include -# 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); - - if (type == 0) - return python::detail::none(); - - 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 169106f4..00000000 --- a/include/boost/python/object/make_ptr_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_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) - { - if (p == 0) - return 0; // means "return None". - - PyTypeObject* derived = get_derived_class_object( - BOOST_DEDUCED_TYPENAME 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 cf1c5e99..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 cc114925..00000000 --- a/include/boost/python/object/pointer_holder.hpp +++ /dev/null @@ -1,180 +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; -} - -# if BOOST_WORKAROUND(__GNUC__, == 2) -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)objects::do_unforward(a##n,0) -# else -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0) -# endif - -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 fe3bde37..00000000 --- a/include/boost/python/object/py_function.hpp +++ /dev/null @@ -1,164 +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 -# include -# include -# 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) - -struct BOOST_PYTHON_DECL py_function_impl_base -{ - virtual ~py_function_impl_base(); - virtual PyObject* operator()(PyObject*, PyObject*) = 0; - virtual unsigned min_arity() const = 0; - virtual unsigned max_arity() const; - virtual python::detail::signature_element const* signature() const = 0; -}; - -template -struct caller_py_function_impl : py_function_impl_base -{ - caller_py_function_impl(Caller const& caller) - : m_caller(caller) - {} - - PyObject* operator()(PyObject* args, PyObject* kw) - { - return m_caller(args, kw); - } - - virtual unsigned min_arity() const - { - return m_caller.min_arity(); - } - - virtual python::detail::signature_element const* signature() const - { - return m_caller.signature(); - } - - private: - Caller m_caller; -}; - -template -struct signature_py_function_impl : py_function_impl_base -{ - signature_py_function_impl(Caller const& caller) - : m_caller(caller) - {} - - PyObject* operator()(PyObject* args, PyObject* kw) - { - return m_caller(args, kw); - } - - virtual unsigned min_arity() const - { - return mpl::size::value - 1; - } - - virtual python::detail::signature_element const* signature() const - { - return python::detail::signature::elements(); - } - - private: - Caller m_caller; -}; - -template -struct full_py_function_impl : py_function_impl_base -{ - full_py_function_impl(Caller const& caller, unsigned min_arity, unsigned max_arity) - : m_caller(caller) - , m_min_arity(min_arity) - , m_max_arity(max_arity > min_arity ? max_arity : min_arity) - {} - - PyObject* operator()(PyObject* args, PyObject* kw) - { - return m_caller(args, kw); - } - - virtual unsigned min_arity() const - { - return m_min_arity; - } - - virtual unsigned max_arity() const - { - return m_max_arity; - } - - virtual python::detail::signature_element const* signature() const - { - return python::detail::signature::elements(); - } - - private: - Caller m_caller; - unsigned m_min_arity; - unsigned m_max_arity; -}; - -struct py_function -{ - template - py_function(Caller const& caller) - : m_impl(new caller_py_function_impl(caller)) - {} - - template - py_function(Caller const& caller, Sig) - : m_impl(new signature_py_function_impl(caller)) - {} - - template - py_function(Caller const& caller, Sig, int min_arity, int max_arity = 0) - : m_impl(new full_py_function_impl(caller, min_arity, max_arity)) - {} - - py_function(py_function const& rhs) - : m_impl(rhs.m_impl) - {} - - PyObject* operator()(PyObject* args, PyObject* kw) const - { - return (*m_impl)(args, kw); - } - - unsigned min_arity() const - { - return m_impl->min_arity(); - } - - unsigned max_arity() const - { - return m_impl->max_arity(); - } - - python::detail::signature_element const* signature() const - { - return m_impl->signature(); - } - - private: - mutable std::auto_ptr m_impl; -}; - -}}} // 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 11a8c09a..00000000 --- a/include/boost/python/object/select_holder.hpp +++ /dev/null @@ -1,195 +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 - -# 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::true_) - { - 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::false_) - { - 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 - { - private: - typedef mpl::or_< - mpl::not_ > - , has_back_reference - > use_back_ref; - - public: - static void assert_default_constructible() - { - detail::check_default_constructible((T*)0,(Held*)0, use_back_ref()); - } - - typedef typename mpl::if_< - use_back_ref - , value_holder_back_reference - , value_holder - >::type type; - - typedef Held held_type; - - static inline void register_() {} - - static type* get() { return 0; } - }; - - template - struct select_pointer_holder - { - private: - typedef typename python::pointee::type wrapper; - typedef mpl::or_< - mpl::not_ > - , has_back_reference - > use_back_ref; - - public: - static void assert_default_constructible() - { - detail::check_default_constructible((T*)0,(wrapper*)0, use_back_ref()); - } - - typedef typename mpl::if_< - use_back_ref - , pointer_holder_back_reference - , pointer_holder - >::type type; - - typedef typename pointee::type held_type; - - static inline void register_() - { - select_pointer_holder::register_(use_back_ref()); - } - - 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) -// -// Returns an instantiation of -// detail::select_value_holder or detail::select_pointer_holder, as -// appropriate for class_ -template -struct select_holder - : 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 -{ -}; - -}}} // 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 89e52352..00000000 --- a/include/boost/python/object/value_holder.hpp +++ /dev/null @@ -1,143 +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 { - -# if BOOST_WORKAROUND(__GNUC__, == 2) -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)objects::do_unforward(a##n,0) -# else -# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) objects::do_unforward(a##n,0) -# endif - -template -struct value_holder : instance_holder -{ - typedef Value held_type; - typedef Value 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 - Value m_held; -}; - -template -struct value_holder_back_reference : instance_holder -{ - typedef Held held_type; - typedef Value 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 - Held 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(); - Value* 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 56609037..00000000 --- a/include/boost/python/object_attributes.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 OBJECT_ATTRIBUTES_DWA2002615_HPP -# define OBJECT_ATTRIBUTES_DWA2002615_HPP - -# include - -# 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 a9b51ac6..00000000 --- a/include/boost/python/object_core.hpp +++ /dev/null @@ -1,471 +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 - -# include -# include - -# include -# include - -# include -# include -# include - -# include -# include -# include - -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) -# include -# endif - -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 - // - BOOST_PYTHON_IS_XXX_DEF(proxy, boost::python::api::proxy, 1) - - template struct object_initializer; - - class object; - typedef PyObject* (object::*bool_type)() const; - - template - class object_operators : public def_visitor - { - 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: // def visitation for adding callable objects as class methods - template - void visit(ClassT& cl, char const* name, python::detail::def_helper const& helper) 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(cl, name, this->derived_visitor(), helper.doc()); - } - - friend class python::def_visitor_access; - - 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; - }; - -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct is_derived_impl - { - static T x; - template - static X* to_pointer(X const&); - - static char test(U const*); - typedef char (&no)[2]; - static no test(...); - - BOOST_STATIC_CONSTANT(bool, value = sizeof(test(to_pointer(x))) == 1); - }; - - template - struct is_derived - : mpl::bool_::value> - {}; -# else - template - struct is_derived - : is_convertible< - typename remove_reference::type* - , U const* - > - {}; -# endif - - template - typename objects::unforward_cref::type do_unforward_cref(T const& x) - { -# if BOOST_WORKAROUND(__GNUC__, == 2) - typedef typename objects::unforward_cref::type ret; - return ret(x); -# else - return x; -# endif - } - -# if BOOST_WORKAROUND(__GNUC__, == 2) - // GCC 2.x has non-const string literals; this hacks around that problem. - template - char const (& do_unforward_cref(char const(&x)[N]) )[N] - { - return x; - } -# endif - - class object; - - template - PyObject* object_base_initializer(T const& x) - { - typedef typename is_derived< - BOOST_DEDUCED_TYPENAME objects::unforward_cref::type - , object - >::type is_obj; - - return object_initializer< - BOOST_DEDUCED_TYPENAME unwrap_reference::type - >::get( - api::do_unforward_cref(x) - , is_obj() - ); - } - - 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_base_initializer(x)) - { - } - - // Throw error_already_set() if the handle is null. - BOOST_PYTHON_DECL explicit object(handle<> const&); - private: - - 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_impl - { - static PyObject* - get(object const& x, mpl::true_) - { - return python::incref(x.ptr()); - } - - template - static PyObject* - get(T const& x, mpl::false_) - { - return python::incref(converter::arg_to_python(x).get()); - } - }; - - template <> - struct object_initializer_impl - { - template - static PyObject* - get(proxy const& x, mpl::false_) - { - return python::incref(x.operator object().ptr()); - } - }; - - template <> - struct object_initializer_impl - { - template - static PyObject* - get(T const& x, ...) - { - return python::incref(get_managed_object(x, tag)); - } - }; - - template <> - struct object_initializer_impl - {}; // empty implementation should cause an error - - template - struct object_initializer : object_initializer_impl< - is_proxy::value - , converter::is_object_manager::value - > - {}; - -} -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 5ac0c4d0..00000000 --- a/include/boost/python/object_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 OBJECT_FWD_DWA2002724_HPP -# define OBJECT_FWD_DWA2002724_HPP - -# include - -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 c3ea1735..00000000 --- a/include/boost/python/object_items.hpp +++ /dev/null @@ -1,90 +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 -# 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 a17fb614..00000000 --- a/include/boost/python/object_operators.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 OBJECT_OPERATORS_DWA2002617_HPP -# define OBJECT_OPERATORS_DWA2002617_HPP - -# include - -# include -# include -# include -# include - -# include - -namespace boost { namespace python { namespace api { - -# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE) - -template char -is_object_operators_helper(object_operators const&); - -typedef char (&no_type)[2]; -no_type is_object_operators_helper(...); - -template X& make(); - -template -struct is_object_operators -{ - enum { - value - = (sizeof(api::is_object_operators_helper(api::make())) - + sizeof(api::is_object_operators_helper(api::make())) - < 4 - ) - }; - typedef mpl::bool_ type; -}; - -template -struct enable_binary - : boost::iterators::enable_if, T> -{}; -# define BOOST_PYTHON_BINARY_RETURN(T) typename enable_binary::type -# else -# define BOOST_PYTHON_BINARY_RETURN(T) T -# endif - -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 \ -BOOST_PYTHON_BINARY_RETURN(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 \ -BOOST_PYTHON_BINARY_RETURN(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 - -#include - -#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 9e31c1b5..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 - -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 021eff46..00000000 --- a/include/boost/python/object_protocol_core.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 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 9a3c747b..00000000 --- a/include/boost/python/object_slices.hpp +++ /dev/null @@ -1,127 +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 -# 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/opaque_pointer_converter.hpp b/include/boost/python/opaque_pointer_converter.hpp deleted file mode 100644 index 8f9a1dd9..00000000 --- a/include/boost/python/opaque_pointer_converter.hpp +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright Gottfried Ganßauge 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. -/* - * Generic Conversion of opaque C++-pointers to a Python-Wrapper. - */ -# ifndef OPAQUE_POINTER_CONVERTER_HPP_ -# define OPAQUE_POINTER_CONVERTER_HPP_ - -# include -# include -# include -# include -# include -# include -# include - -// opaque_pointer_converter -- -// -// usage: opaque_pointer_converter("name") -// -// registers to- and from- python conversions for a type Pointer, -// and a corresponding Python type called "name". -// -// Note: -// In addition you need to define specializations for type_id -// on the type pointed to by Pointer using -// BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) -// -// For an example see libs/python/test/opaque.cpp -// -namespace boost { namespace python { - namespace detail { - template - struct opaque_pointer_converter_requires_a_pointer_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; - } - -template -struct opaque_pointer_converter - : to_python_converter< - Pointer, opaque_pointer_converter > -{ - BOOST_STATIC_CONSTANT( - bool, ok = is_pointer::value); - - typedef typename mpl::if_c< - ok - , Pointer - , detail::opaque_pointer_converter_requires_a_pointer_type - >::type ptr_type; - -private: - struct instance; - -public: - explicit opaque_pointer_converter(char const* name) - { - type_object.tp_name = const_cast (name); - - lvalue_from_pytype< - opaque_pointer_converter, - &opaque_pointer_converter::type_object - >(); - } - - static PyObject* convert(ptr_type x) - { - PyObject *result = 0; - - if (x != 0) { - instance *o = PyObject_New (instance, &type_object); - - o->x = x; - result = &o->base_; - } else { - result = detail::none(); - } - - return (result); - } - - static typename ::boost::remove_pointer::type& - execute(instance &p_) - { - return *p_.x; - } - -private: - static PyTypeObject type_object; - - // This is a POD so we can use PyObject_Del on it, for example. - struct instance - { - PyObject base_; - ptr_type x; - }; -}; - -template -PyTypeObject opaque_pointer_converter::type_object = -{ - PyObject_HEAD_INIT(NULL) - 0, - 0, - sizeof(typename opaque_pointer_converter::instance), - 0, - ::boost::python::detail::dealloc -}; -}} // namespace boost::python -# ifdef BOOST_MSVC -// MSC works without this workaround, but needs another one ... -# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \ - BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(Pointee) -# else -# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \ - namespace boost { namespace python { \ - template<> \ - inline type_info type_id(BOOST_PYTHON_EXPLICIT_TT_DEF(Pointee)) \ - { \ - return type_info (typeid (Pointee *)); \ - } \ - template<> \ - inline type_info type_id( \ - BOOST_PYTHON_EXPLICIT_TT_DEF(const volatile Pointee&)) \ - { \ - return type_info (typeid (Pointee *)); \ - } \ -}} -# endif -# endif // OPAQUE_POINTER_CONVERTER_HPP_ diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp deleted file mode 100644 index f64ec22a..00000000 --- a/include/boost/python/operators.hpp +++ /dev/null @@ -1,356 +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 -# 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_ - : def_visitor > - { - private: - template - void visit(ClassT& cl) const - { - typedef typename mpl::apply_if< - is_same - , mpl::if_< - is_same - , binary_op - , binary_op_l< - id - , BOOST_DEDUCED_TYPENAME unwrap_other::type - > - > - , mpl::if_< - is_same - , unary_op - , binary_op_r< - id - , BOOST_DEDUCED_TYPENAME unwrap_other::type - > - > - >::type generator; - - cl.def( - generator::name() - , &generator::template apply< - BOOST_DEDUCED_TYPENAME ClassT::wrapped_type - >::execute - ); - } - - friend class python::def_visitor_access; - }; -} - -# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \ -namespace detail \ -{ \ - template <> \ - struct operator_l \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* execute(L& 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& 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& 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 86cd94b0..00000000 --- a/include/boost/python/other.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef OTHER_DWA20020601_HPP -# define OTHER_DWA20020601_HPP - -# include -// 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 34909033..00000000 --- a/include/boost/python/overloads.hpp +++ /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. -#ifndef OVERLOADS_DWA2002101_HPP -# define OVERLOADS_DWA2002101_HPP - -# include - -# 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 72cd8664..00000000 --- a/include/boost/python/pointee.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 POINTEE_DWA2002323_HPP -# define POINTEE_DWA2002323_HPP - -# include - -# 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< - ::boost::is_pointer::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 4585201b..00000000 --- a/include/boost/python/proxy.hpp +++ /dev/null @@ -1,102 +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 -# 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 1bbe8c5e..00000000 --- a/include/boost/python/ptr.hpp +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef PTR_DWA20020601_HPP -# define PTR_DWA20020601_HPP - -# include -// 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/pure_virtual.hpp b/include/boost/python/pure_virtual.hpp deleted file mode 100755 index eb7e8a45..00000000 --- a/include/boost/python/pure_virtual.hpp +++ /dev/null @@ -1,129 +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 PURE_VIRTUAL_DWA2003810_HPP -# define PURE_VIRTUAL_DWA2003810_HPP - -# include -# include -# include -# include -# include - -# include - -namespace boost { namespace python { - -namespace detail -{ - // - // { Helpers for pure_virtual_visitor, below. - // - - // Raises a Python RuntimeError reporting that a pure virtual - // function was called. - void BOOST_PYTHON_DECL pure_virtual_called(); - - // Replace the two front elements of S with T1 and T2 - template - struct replace_front2 - { - // Metafunction forwarding seemed to confound vc6 - typedef typename mpl::push_front< - typename mpl::push_front< - typename mpl::pop_front< - typename mpl::pop_front< - S - >::type - >::type - , T2 - >::type - , T1 - >::type type; - }; - - // Given an MPL sequence representing a signature, returns a new MPL - // sequence whose return type is replaced by void, and whose first - // argument is replaced by C&. - template - typename replace_front2::type - error_signature(S BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(C)) - { - typedef typename replace_front2::type r; - return r(); - } - - // - // } Helpers for pure_virtual_visitor - // - - // - // A def_visitor which defines a method as usual, then adds a - // corresponding function which raises a "pure virtual called" - // exception unless it's been overridden. - // - template - struct pure_virtual_visitor - : def_visitor > - { - pure_virtual_visitor(PointerToMemberFunction pmf) - : m_pmf(pmf) - {} - -#if !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) - private: -#endif - friend class def_visitor_access; - - template - void visit(C_& c, char const* name, Options& options) const - { - // This should probably be a nicer error message - BOOST_STATIC_ASSERT(!Options::has_default_implementation); - - // Add the virtual function dispatcher - c.def( - name - , m_pmf - , options.doc() - , options.keywords() - , options.policies() - ); - - typedef BOOST_DEDUCED_TYPENAME C_::select_holder::held_type held_t; - - // Add the default implementation which raises the exception - c.def( - name - , detail::make_function_aux( - detail::nullary_function_adaptor(pure_virtual_called) - , default_call_policies() - , args_from_python() - , detail::error_signature(detail::get_signature(m_pmf)) - ) - ); - } - - private: // data members - PointerToMemberFunction m_pmf; - }; -} - -// -// Passed a pointer to member function, generates a def_visitor which -// creates a method that only dispatches to Python if the function has -// been overridden, either in C++ or in Python, raising a "pure -// virtual called" exception otherwise. -// -template -detail::pure_virtual_visitor -pure_virtual(PointerToMemberFunction pmf) -{ - return detail::pure_virtual_visitor(pmf); -} - -}} // namespace boost::python - -#endif // PURE_VIRTUAL_DWA2003810_HPP diff --git a/include/boost/python/raw_function.hpp b/include/boost/python/raw_function.hpp deleted file mode 100755 index 1ed3c3c1..00000000 --- a/include/boost/python/raw_function.hpp +++ /dev/null @@ -1,62 +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 -# 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)) - , keywords ? dict(borrowed_reference(keywords)) : dict() - ) - ).ptr() - ); - } - - private: - F f; - }; - - object BOOST_PYTHON_DECL make_raw_function(objects::py_function); -} - -template -object raw_function(F f, std::size_t min_args = 0) -{ - return detail::make_raw_function( - objects::py_function( - detail::raw_dispatcher(f) - , mpl::vector1() - , min_args - , std::numeric_limits::max() - ) - ); -} - -}} // 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 45b1e9ab..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 5aeeab6c..00000000 --- a/include/boost/python/reference_existing_object.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 REFERENCE_EXISTING_OBJECT_DWA200222_HPP -# define REFERENCE_EXISTING_OBJECT_DWA200222_HPP - -# include -# 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/register_ptr_to_python.hpp b/include/boost/python/register_ptr_to_python.hpp deleted file mode 100644 index cbd42cc1..00000000 --- a/include/boost/python/register_ptr_to_python.hpp +++ /dev/null @@ -1,32 +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 REGISTER_PTR_TO_PYTHON_HPP -#define REGISTER_PTR_TO_PYTHON_HPP - -#include -#include -#include - -namespace boost { namespace python { - -template -void register_ptr_to_python(BOOST_EXPLICIT_TEMPLATE_TYPE(P)) -{ - typedef typename boost::python::pointee

::type X; - objects::class_value_wrapper< - P - , objects::make_ptr_instance< - X - , objects::pointer_holder - > - >(); -} - -}} // namespace boost::python - -#endif // REGISTER_PTR_TO_PYTHON_HPP - - diff --git a/include/boost/python/return_arg.hpp b/include/boost/python/return_arg.hpp deleted file mode 100755 index 8c4dc189..00000000 --- a/include/boost/python/return_arg.hpp +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright David Abrahams and Nikolay Mladenov 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 RETURN_ARG_DWA2003719_HPP -# define RETURN_ARG_DWA2003719_HPP -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct return_arg_pos_argument_must_be_positive -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; - - struct return_none - { - template struct apply - { - struct type - { - static bool convertible() - { - return true; - } - - PyObject *operator()( - typename add_reference< - typename add_const::type - >::type - ) const - { - return none(); - } - }; - }; - }; -} - -template < - std::size_t arg_pos=1 - , class Base = default_call_policies -> -struct return_arg : Base -{ - private: - BOOST_STATIC_CONSTANT(bool, legal = arg_pos > 0); - - public: - typedef typename mpl::if_c< - legal - , detail::return_none - , detail::return_arg_pos_argument_must_be_positive - // we could default to the base result_converter in case or - // arg_pos==0 since return arg 0 means return result, but I - // think it is better to issue an error instead, cause it can - // lead to confusions - >::type result_converter; - - static PyObject* postcall(PyObject *args, PyObject* result); -}; - -template < - class Base = default_call_policies - > -struct return_self - : return_arg<1,Base> -{}; - - -template -inline PyObject* -return_arg::postcall(PyObject *args, PyObject* result) -{ - // In case of arg_pos == 0 we could simply return Base::postcall, - // but this is redundant - BOOST_STATIC_ASSERT(arg_pos > 0); - - handle<> base_result(Base::postcall(args,result)); - - if(!base_result) - return 0; - - return incref(PyTuple_GetItem(args,arg_pos-1)); -} - -}} // namespace boost::python - -#endif // RETURN_ARG_DWA2003719_HPP diff --git a/include/boost/python/return_by_value.hpp b/include/boost/python/return_by_value.hpp deleted file mode 100644 index dba6736f..00000000 --- a/include/boost/python/return_by_value.hpp +++ /dev/null @@ -1,32 +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 -# 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 70e5d749..00000000 --- a/include/boost/python/return_internal_reference.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 RETURN_INTERNAL_REFERENCE_DWA2002131_HPP -# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP - -# include - -# 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_opaque_pointer.hpp b/include/boost/python/return_opaque_pointer.hpp deleted file mode 100644 index 2109d4ec..00000000 --- a/include/boost/python/return_opaque_pointer.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright Gottfried Ganßauge 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. -/* - * Generic Return value converter generator for opaque C++-pointers - */ -# ifndef RETURN_OPAQUE_POINTER_HPP_ -# define RETURN_OPAQUE_POINTER_HPP_ - -# include -# include -# include -# include - -namespace boost { namespace python { - namespace detail { - template - struct opaque_conversion_holder { - inline PyObject *operator () (Pointer p) { - static opaque_pointer_converter converter ( - typeid (Pointer).name()); - - return converter.convert(p); - } - }; - - template - struct return_opaque_pointer_requires_a_pointer_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; - } - - struct return_opaque_pointer - { - template - struct apply - { - BOOST_STATIC_CONSTANT( - bool, ok = is_pointer::value); - - typedef typename mpl::if_c< - ok - , detail::opaque_conversion_holder - , detail::return_opaque_pointer_requires_a_pointer_type - >::type type; - }; - }; -}} // namespace boost::python -# endif // RETURN_OPAQUE_POINTER_HPP_ diff --git a/include/boost/python/return_value_policy.hpp b/include/boost/python/return_value_policy.hpp deleted file mode 100644 index 7f23ea91..00000000 --- a/include/boost/python/return_value_policy.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 RETURN_VALUE_POLICY_DWA2002131_HPP -# define RETURN_VALUE_POLICY_DWA2002131_HPP - -# include -# 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 caaf3b1c..00000000 --- a/include/boost/python/scope.hpp +++ /dev/null @@ -1,79 +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 -# include - -namespace boost { namespace python { - -namespace detail -{ - // Making this a namespace-scope variable to avoid Cygwin issues. - // Use a PyObject* to avoid problems with static destruction after Py_Finalize - extern BOOST_PYTHON_DECL PyObject* current_scope; -} - -class 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&); -}; - -inline scope::scope(object const& new_scope) - : object(new_scope) - , m_previous_scope(detail::current_scope) -{ - detail::current_scope = python::incref(new_scope.ptr()); -} - -inline scope::scope() - : object(detail::borrowed_reference( - detail::current_scope ? detail::current_scope : Py_None - )) - , m_previous_scope(python::xincref(detail::current_scope)) -{ -} - -inline scope::~scope() -{ - python::xdecref(detail::current_scope); - detail::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(detail::current_scope) -{ - detail::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 665546d2..00000000 --- a/include/boost/python/self.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 SELF_DWA2002531_HPP -# define SELF_DWA2002531_HPP - -# include - -namespace boost { namespace python { - -#define BOOST_PYTHON_SELF_IS_CLASS - -// 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 0d20f8ff..00000000 --- a/include/boost/python/signature.hpp +++ /dev/null @@ -1,121 +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 -# include - -# define BOOST_PYTHON_LIST_INC(n) \ - BOOST_PP_CAT(mpl::vector, 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 b77d06cb..00000000 --- a/include/boost/python/slice_nil.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 SLICE_NIL_DWA2002620_HPP -# define SLICE_NIL_DWA2002620_HPP - -# include - -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 6fc20f9d..00000000 --- a/include/boost/python/str.hpp +++ /dev/null @@ -1,402 +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 -#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/suite/indexing/container_utils.hpp b/include/boost/python/suite/indexing/container_utils.hpp deleted file mode 100644 index 2370fa8d..00000000 --- a/include/boost/python/suite/indexing/container_utils.hpp +++ /dev/null @@ -1,53 +0,0 @@ - -// (C) Copyright Joel de Guzman 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 PY_CONTAINER_UTILS_JDG20038_HPP -# define PY_CONTAINER_UTILS_JDG20038_HPP - -# include -# include -# include - -namespace boost { namespace python { namespace container_utils { - - template - void - extend_container(Container& container, object l) - { - typedef typename Container::value_type data_type; - - // l must be a list or some container - - for (int i = 0; i < l.attr("__len__")(); i++) - { - object elem(l[i]); - extract x(elem); - // try if elem is an exact data_type type - if (x.check()) - { - container.push_back(x()); - } - else - { - // try to convert elem to data_type type - extract x(elem); - if (x.check()) - { - container.push_back(x()); - } - else - { - PyErr_SetString(PyExc_TypeError, "Incompatible Data Type"); - throw_error_already_set(); - } - } - } - } - -}}} // namespace boost::python::container_utils - -#endif diff --git a/include/boost/python/suite/indexing/detail/indexing_suite_detail.hpp b/include/boost/python/suite/indexing/detail/indexing_suite_detail.hpp deleted file mode 100644 index 10aa0954..00000000 --- a/include/boost/python/suite/indexing/detail/indexing_suite_detail.hpp +++ /dev/null @@ -1,706 +0,0 @@ -// (C) Copyright Joel de Guzman 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 INDEXING_SUITE_DETAIL_JDG20036_HPP -# define INDEXING_SUITE_DETAIL_JDG20036_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -#if defined(NDEBUG) -#define BOOST_PYTHON_INDEXING_CHECK_INVARIANT -#else -#define BOOST_PYTHON_INDEXING_CHECK_INVARIANT check_invariant() -#endif - - template - struct compare_proxy_index - { - // This functor compares a proxy and an index. - // This is used by proxy_group::first_proxy to - // get first proxy with index i. - - template - bool operator()(PyObject* prox, Index i) const - { - typedef typename Proxy::policies_type policies_type; - Proxy& proxy = extract(prox)(); - return policies_type:: - compare_index(proxy.get_container(), proxy.get_index(), i); - } - }; - - // The proxy_group class holds a vector of container element - // proxies. First, what is a container element proxy? A container - // element proxy acts like a smart pointer holding a reference to - // a container and an index (see container_element, for details). - // - // The proxies are held in a vector always sorted by its index. - // Various functions manage the addition, removal and searching - // of proxies from the vector. - // - template - class proxy_group - { - public: - - typedef typename std::vector::const_iterator const_iterator; - typedef typename std::vector::iterator iterator; - typedef typename Proxy::index_type index_type; - typedef typename Proxy::policies_type policies_type; - - iterator - first_proxy(index_type i) - { - // Return the first proxy with index <= i - return boost::detail::lower_bound( - proxies.begin(), proxies.end(), - i, compare_proxy_index()); - } - - void - remove(Proxy& proxy) - { - // Remove a proxy - for (iterator iter = first_proxy(proxy.get_index()); - iter != proxies.end(); ++iter) - { - if (&extract(*iter)() == &proxy) - { - proxies.erase(iter); - break; - } - } - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - } - - void - add(PyObject* prox) - { - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - // Add a proxy - proxies.insert( - first_proxy(extract(prox)().get_index()), prox); - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - } - - void - erase(index_type i, mpl::false_) - { - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - // Erase the proxy with index i - replace(i, i+1, 0); - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - } - - void - erase(index_type i, mpl::true_) - { - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - // Erase the proxy with index i - - iterator iter = first_proxy(i); - extract p(*iter); - - if (iter != proxies.end() && p().get_index() == i) - { - extract p(*iter); - p().detach(); - proxies.erase(iter); - } - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - } - - void - erase(index_type from, index_type to) - { - // note: this cannot be called when container is not sliceable - - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - // Erase all proxies with indexes from..to - replace(from, to, 0); - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - } - - void - replace( - index_type from, - index_type to, - typename std::vector::size_type len) - { - // note: this cannot be called when container is not sliceable - - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - // Erase all proxies with indexes from..to. - // Adjust the displaced indexes such that the - // final effect is that we have inserted *len* - // number of proxies in the vacated region. This - // procedure involves adjusting the indexes of - // the proxies. - - iterator left = first_proxy(from); - iterator right = proxies.end(); // we'll adjust this later - - for (iterator iter = left; iter != right; ++iter) - { - if (extract(*iter)().get_index() > to) - { - right = iter; // adjust right - break; - } - extract p(*iter); - p().detach(); - } - - typename std::vector::size_type - offset = left-proxies.begin(); - proxies.erase(left, right); - right = proxies.begin()+offset; - - while (right != proxies.end()) - { - typedef typename Proxy::container_type::difference_type difference_type; - extract p(*right); - p().set_index( - extract(*right)().get_index() - - (difference_type(to) - from - len) - ); - - ++right; - } - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - } - - PyObject* - find(index_type i) - { - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - // Find the proxy with *exact* index i. - // Return 0 (null) if no proxy with the - // given index is found. - iterator iter = first_proxy(i); - if (iter != proxies.end() - && extract(*iter)().get_index() == i) - { - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - return *iter; - } - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - return 0; - } - - typename std::vector::size_type - size() const - { - BOOST_PYTHON_INDEXING_CHECK_INVARIANT; - // How many proxies are there so far? - return proxies.size(); - } - - private: - -#if !defined(NDEBUG) - void - check_invariant() const - { - for (const_iterator i = proxies.begin(); i != proxies.end(); ++i) - { - if ((*i)->ob_refcnt <= 0) - { - PyErr_SetString(PyExc_RuntimeError, - "Invariant: Proxy vector in an inconsistent state"); - throw_error_already_set(); - } - - if (i+1 != proxies.end()) - { - if (extract(*(i+1))().get_index() == - extract(*(i))().get_index()) - { - PyErr_SetString(PyExc_RuntimeError, - "Invariant: Proxy vector in an inconsistent state (duplicate proxy)"); - throw_error_already_set(); - } - } - } - } -#endif - - std::vector proxies; - }; - - // proxy_links holds a map of Container pointers (keys) - // with proxy_group(s) (data). Various functions manage - // the addition, removal and searching of proxies from - // the map. - // - template - class proxy_links - { - public: - - typedef std::map > links_t; - typedef typename Proxy::index_type index_type; - - void - remove(Proxy& proxy) - { - // Remove a proxy. - typename links_t::iterator r = links.find(&proxy.get_container()); - if (r != links.end()) - { - r->second.remove(proxy); - if (r->second.size() == 0) - links.erase(r); - } - } - - void - add(PyObject* prox, Container& container) - { - // Add a proxy - links[&container].add(prox); - } - - template - void erase(Container& container, index_type i, NoSlice no_slice) - { - // Erase the proxy with index i - typename links_t::iterator r = links.find(&container); - if (r != links.end()) - { - r->second.erase(i, no_slice); - if (r->second.size() == 0) - links.erase(r); - } - } - - void - erase(Container& container, index_type from, index_type to) - { - // Erase all proxies with indexes from..to - typename links_t::iterator r = links.find(&container); - if (r != links.end()) - { - r->second.erase(from, to); - if (r->second.size() == 0) - links.erase(r); - } - } - - void - replace( - Container& container, - index_type from, index_type to, index_type len) - { - // Erase all proxies with indexes from..to. - // Adjust the displaced indexes such that the - // final effect is that we have inserted *len* - // number of proxies in the vacated region. This - // procedure involves adjusting the indexes of - // the proxies. - - typename links_t::iterator r = links.find(&container); - if (r != links.end()) - { - r->second.replace(from, to, len); - if (r->second.size() == 0) - links.erase(r); - } - } - - PyObject* - find(Container& container, index_type i) - { - // Find the proxy with *exact* index i. - // Return 0 (null) if no proxy with the given - // index is found. - typename links_t::iterator r = links.find(&container); - if (r != links.end()) - return r->second.find(i); - return 0; - } - - private: - - links_t links; - }; - - // container_element is our container proxy class. - // This class acts like a smart pointer to a container - // element. The class holds an index and a reference to - // a container. Dereferencing the smart pointer will - // retrieve the nth (index) element from the container. - // - // A container_element can also be detached from the - // container. In such a detached state, the container_element - // holds a copy of the nth (index) element, which it - // returns when dereferenced. - // - template - class container_element - { - public: - - typedef Index index_type; - typedef Container container_type; - typedef typename Policies::data_type element_type; - typedef Policies policies_type; - typedef container_element self_t; - typedef proxy_group links_type; - - container_element(object container, Index index) - : ptr() - , container(container) - , index(index) - { - } - - container_element(container_element const& ce) - : ptr(ce.ptr.get() == 0 ? 0 : new element_type(*ce.ptr.get())) - , container(ce.container) - , index(ce.index) - { - } - - ~container_element() - { - if (!is_detached()) - get_links().remove(*this); - } - - element_type& operator*() const - { - if (is_detached()) - return *ptr.get(); - return Policies::get_item(get_container(), index); - } - - element_type* get() const - { - if (is_detached()) - return ptr.get(); - return &Policies::get_item(get_container(), index); - } - - void - detach() - { - if (!is_detached()) - { - ptr.reset( - new element_type( - Policies::get_item(get_container(), index))); - container = object(); // free container. reset it to None - } - } - - bool - is_detached() const - { - return ptr.get() != 0; - } - - Container& - get_container() const - { - return extract(container)(); - } - - Index - get_index() const - { - return index; - } - - void - set_index(Index i) - { - index = i; - } - - static proxy_links& - get_links() - { - // All container_element(s) maintain links to - // its container in a global map (see proxy_links). - // This global "links" map is a singleton. - - static proxy_links links; - return links; // singleton - } - - private: - - container_element& operator=(container_element const& ce); - - scoped_ptr ptr; - object container; - Index index; - }; - - template < - class Container - , class DerivedPolicies - , class ContainerElement - , class Index - > - struct no_proxy_helper - { - static void - register_container_element() - { - } - - static object - base_get_item_(back_reference const& container, PyObject* i) - { - return object( - DerivedPolicies::get_item( - container.get(), DerivedPolicies:: - convert_index(container.get(), i))); - } - - static void - base_replace_indexes( - Container& container, Index from, - Index to, Index n) - { - } - - template - static void - base_erase_index( - Container& container, Index i, NoSlice no_slice) - { - } - - static void - base_erase_indexes(Container& container, Index from, Index to) - { - } - }; - - template < - class Container - , class DerivedPolicies - , class ContainerElement - , class Index - > - struct proxy_helper - { - static void - register_container_element() - { - register_ptr_to_python(); - } - - static object - base_get_item_(back_reference const& container, PyObject* i) - { - // Proxy - Index idx = DerivedPolicies::convert_index(container.get(), i); - - if (PyObject* shared = - ContainerElement::get_links().find(container.get(), idx)) - { - handle<> h(python::borrowed(shared)); - return object(h); - } - else - { - object prox(ContainerElement(container.source(), idx)); - ContainerElement:: - get_links().add(prox.ptr(), container.get()); - return prox; - } - } - - static void - base_replace_indexes( - Container& container, Index from, - Index to, Index n) - { - ContainerElement::get_links().replace(container, from, to, n); - } - - template - static void - base_erase_index( - Container& container, Index i, NoSlice no_slice) - { - ContainerElement::get_links().erase(container, i, no_slice); - } - - static void - base_erase_indexes( - Container& container, Index from, Index to) - { - ContainerElement::get_links().erase(container, from, to); - } - }; - - template < - class Container - , class DerivedPolicies - , class ProxyHandler - , class Data - , class Index - > - struct slice_helper - { - static object - base_get_slice(Container& container, PySliceObject* slice) - { - Index from, to; - base_get_slice_data(container, slice, from, to); - return DerivedPolicies::get_slice(container, from, to); - } - - static void - base_get_slice_data( - Container& container, PySliceObject* slice, Index& from, Index& to) - { - if (Py_None == slice->start) - from = DerivedPolicies::get_min_index(container); - else - from = DerivedPolicies::convert_index(container, slice->start); - - if (Py_None == slice->stop) - to = DerivedPolicies::get_max_index(container); - else - to = DerivedPolicies::convert_index(container, slice->stop); - } - - static void - base_set_slice(Container& container, PySliceObject* slice, PyObject* v) - { - Index from, to; - base_get_slice_data(container, slice, from, to); - - extract elem(v); - // try if elem is an exact Data - if (elem.check()) - { - ProxyHandler::base_replace_indexes(container, from, to, 1); - DerivedPolicies::set_slice(container, from, to, elem()); - } - else - { - // try to convert elem to Data - extract elem(v); - if (elem.check()) - { - ProxyHandler::base_replace_indexes(container, from, to, 1); - DerivedPolicies::set_slice(container, from, to, elem()); - } - else - { - // Otherwise, it must be a list or some container - handle<> l_(python::borrowed(v)); - object l(l_); - - std::vector temp; - for (int i = 0; i < l.attr("__len__")(); i++) - { - object elem(l[i]); - extract x(elem); - // try if elem is an exact Data type - if (x.check()) - { - temp.push_back(x()); - } - else - { - // try to convert elem to Data type - extract x(elem); - if (x.check()) - { - temp.push_back(x()); - } - else - { - PyErr_SetString(PyExc_TypeError, - "Invalid sequence element"); - throw_error_already_set(); - } - } - } - - ProxyHandler::base_replace_indexes(container, from, to, - temp.end()-temp.begin()); - DerivedPolicies::set_slice(container, from, to, - temp.begin(), temp.end()); - } - } - } - - static void - base_delete_slice(Container& container, PySliceObject* slice) - { - Index from, to; - base_get_slice_data(container, slice, from, to); - ProxyHandler::base_erase_indexes(container, from, to); - DerivedPolicies::delete_slice(container, from, to); - } - }; - - template < - class Container - , class DerivedPolicies - , class ProxyHandler - , class Data - , class Index - > - struct no_slice_helper - { - static void - slicing_not_suported() - { - PyErr_SetString(PyExc_RuntimeError, "Slicing not supported"); - throw_error_already_set(); - } - - static object - base_get_slice(Container& container, PySliceObject* slice) - { - slicing_not_suported(); - return object(); - } - - static void - base_set_slice(Container& container, PySliceObject* slice, PyObject* v) - { - slicing_not_suported(); - } - - static void - base_delete_slice(Container& container, PySliceObject* slice) - { - slicing_not_suported(); - } - }; - - }} // namespace python::detail - - template - inline typename Policies::data_type* - get_pointer( - python::detail::container_element const& p) - { - // Get the pointer of a container_element smart pointer - return p.get(); - } - -} // namespace boost - -#endif // INDEXING_SUITE_DETAIL_JDG20036_HPP diff --git a/include/boost/python/suite/indexing/indexing_suite.hpp b/include/boost/python/suite/indexing/indexing_suite.hpp deleted file mode 100644 index 5fd8af22..00000000 --- a/include/boost/python/suite/indexing/indexing_suite.hpp +++ /dev/null @@ -1,294 +0,0 @@ -// (C) Copyright Joel de Guzman 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 INDEXING_SUITE_JDG20036_HPP -# define INDEXING_SUITE_JDG20036_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - - // indexing_suite class. This class is the protocol class for - // the management of C++ containers intended to be integrated - // to Python. The objective is make a C++ container look and - // feel and behave exactly as we'd expect a Python container. - // By default indexed elements are returned by proxy. This can be - // disabled by supplying *true* in the NoProxy template parameter. - // - // Derived classes provide the hooks needed by the indexing_suite - // to do its job: - // - // static data_type& - // get_item(Container& container, index_type i); - // - // static object - // get_slice(Container& container, index_type from, index_type to); - // - // static void - // set_item(Container& container, index_type i, data_type const& v); - // - // static void - // set_slice( - // Container& container, index_type from, - // index_type to, data_type const& v - // ); - // - // template - // static void - // set_slice(Container& container, index_type from, - // index_type to, Iter first, Iter last - // ); - // - // static void - // delete_item(Container& container, index_type i); - // - // static void - // delete_slice(Container& container, index_type from, index_type to); - // - // static size_t - // size(Container& container); - // - // template - // static bool - // contains(Container& container, T const& val); - // - // static index_type - // convert_index(Container& container, PyObject* i); - // - // static index_type - // adjust_index(index_type current, index_type from, - // index_type to, size_type len - // ); - // - // Most of these policies are self explanatory. convert_index and - // adjust_index, however, deserves some explanation. - // - // convert_index converts an Python index into a C++ index that the - // container can handle. For instance, negative indexes in Python, by - // convention, indexes from the right (e.g. C[-1] indexes the rightmost - // element in C). convert_index should handle the necessary conversion - // for the C++ container (e.g. convert -1 to C.size()-1). convert_index - // should also be able to convert the type of the index (A dynamic Python - // type) to the actual type that the C++ container expects. - // - // When a container expands or contracts, held indexes to its elements - // must be adjusted to follow the movement of data. For instance, if - // we erase 3 elements, starting from index 0 from a 5 element vector, - // what used to be at index 4 will now be at index 1: - // - // [a][b][c][d][e] ---> [d][e] - // ^ ^ - // 4 1 - // - // adjust_index takes care of the adjustment. Given a current index, - // the function should return the adjusted index when data in the - // container at index from..to is replaced by *len* elements. - // - - template < - class Container - , class DerivedPolicies - , bool NoProxy = false - , bool NoSlice = false - , class Data = typename Container::value_type - , class Index = typename Container::size_type - , class Key = typename Container::value_type - > - class indexing_suite - : public def_visitor< - indexing_suite< - Container - , DerivedPolicies - , NoProxy - , NoSlice - , Data - , Index - , Key - > > - { - private: - - typedef mpl::or_< - mpl::bool_ - , mpl::not_ > > - no_proxy; - - typedef detail::container_element - container_element_t; - - typedef typename mpl::if_< - no_proxy - , iterator - , iterator > >::type - def_iterator; - - typedef typename mpl::if_< - no_proxy - , detail::no_proxy_helper< - Container - , DerivedPolicies - , container_element_t - , Index> - , detail::proxy_helper< - Container - , DerivedPolicies - , container_element_t - , Index> >::type - proxy_handler; - - typedef typename mpl::if_< - mpl::bool_ - , detail::no_slice_helper< - Container - , DerivedPolicies - , proxy_handler - , Data - , Index> - , detail::slice_helper< - Container - , DerivedPolicies - , proxy_handler - , Data - , Index> >::type - slice_handler; - - public: - - template - void visit(Class& cl) const - { - // Hook into the class_ generic visitation .def function - proxy_handler::register_container_element(); - - cl - .def("__len__", base_size) - .def("__setitem__", &base_set_item) - .def("__delitem__", &base_delete_item) - .def("__getitem__", &base_get_item) - .def("__contains__", &base_contains) - -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 -// crazy VC6 doesn't like this! perhaps there's a better -// fix but this one will do for now. def __iter__ is just -// an optimization anyway. - .def("__iter__", def_iterator()) -#endif - ; - - DerivedPolicies::extension_def(cl); - } - - template - static void - extension_def(Class& cl) - { - // default. - // no more extensions - } - - private: - - static object - base_get_item(back_reference container, PyObject* i) - { - if (PySlice_Check(i)) - return slice_handler::base_get_slice( - container.get(), reinterpret_cast(i)); - - return proxy_handler::base_get_item_(container, i); - } - - static void - base_set_item(Container& container, PyObject* i, PyObject* v) - { - if (PySlice_Check(i)) - { - slice_handler::base_set_slice(container, - reinterpret_cast(i), v); - } - else - { - extract elem(v); - // try if elem is an exact Data - if (elem.check()) - { - DerivedPolicies:: - set_item(container, - DerivedPolicies:: - convert_index(container, i), elem()); - } - else - { - // try to convert elem to Data - extract elem(v); - if (elem.check()) - { - DerivedPolicies:: - set_item(container, - DerivedPolicies:: - convert_index(container, i), elem()); - } - else - { - PyErr_SetString(PyExc_TypeError, "Invalid assignment"); - throw_error_already_set(); - } - } - } - } - - static void - base_delete_item(Container& container, PyObject* i) - { - if (PySlice_Check(i)) - { - slice_handler::base_delete_slice( - container, reinterpret_cast(i)); - return; - } - - Index index = DerivedPolicies::convert_index(container, i); - proxy_handler::base_erase_index(container, index, mpl::bool_()); - DerivedPolicies::delete_item(container, index); - } - - static size_t - base_size(Container& container) - { - return DerivedPolicies::size(container); - } - - static bool - base_contains(Container& container, PyObject* key) - { - extract x(key); - // try if key is an exact Key type - if (x.check()) - { - return DerivedPolicies::contains(container, x()); - } - else - { - // try to convert key to Key type - extract x(key); - if (x.check()) - return DerivedPolicies::contains(container, x()); - else - return false; - } - } - }; - -}} // namespace boost::python - -#endif // INDEXING_SUITE_JDG20036_HPP diff --git a/include/boost/python/suite/indexing/map_indexing_suite.hpp b/include/boost/python/suite/indexing/map_indexing_suite.hpp deleted file mode 100644 index acdb664f..00000000 --- a/include/boost/python/suite/indexing/map_indexing_suite.hpp +++ /dev/null @@ -1,180 +0,0 @@ -// (C) Copyright Joel de Guzman 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 MAP_INDEXING_SUITE_JDG20038_HPP -# define MAP_INDEXING_SUITE_JDG20038_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - - // Forward declaration - template - class map_indexing_suite; - - namespace detail - { - template - class final_map_derived_policies - : public map_indexing_suite > {}; - } - - // The map_indexing_suite class is a predefined indexing_suite derived - // class for wrapping std::vector (and std::vector like) classes. It provides - // all the policies required by the indexing_suite (see indexing_suite). - // Example usage: - // - // class X {...}; - // - // ... - // - // class_ >("XMap") - // .def(map_indexing_suite >()) - // ; - // - // By default indexed elements are returned by proxy. This can be - // disabled by supplying *true* in the NoProxy template parameter. - // - template < - class Container, - bool NoProxy = false, - class DerivedPolicies - = detail::final_map_derived_policies > - class map_indexing_suite - : public indexing_suite< - Container - , DerivedPolicies - , NoProxy - , true - , typename Container::value_type::second_type - , typename Container::key_type - , typename Container::key_type - > - { - public: - - typedef typename Container::value_type value_type; - typedef typename Container::value_type::second_type data_type; - typedef typename Container::key_type key_type; - typedef typename Container::key_type index_type; - typedef typename Container::size_type size_type; - typedef typename Container::difference_type difference_type; - - template - static void - extension_def(Class& cl) - { - // Wrap the map's element (value_type) - std::string elem_name = "map_indexing_suite_"; - elem_name += cl.ptr()->ob_type->tp_name; // the class name - elem_name += "_entry"; - - typedef typename mpl::if_< - is_class - , return_internal_reference<> - , default_call_policies - >::type get_data_return_policy; - - class_(elem_name.c_str()) - .def("__repr__", &DerivedPolicies::print_elem) - .def("data", &DerivedPolicies::get_data, get_data_return_policy()) - .def("key", &DerivedPolicies::get_key) - ; - } - - static object - print_elem(typename Container::value_type const& e) - { - return "(%s, %s)" % make_tuple(e.first, e.second); - } - - static - typename mpl::if_< - is_class - , data_type& - , data_type - >::type - get_data(typename Container::value_type& e) - { - return e.second; - } - - static typename Container::key_type - get_key(typename Container::value_type& e) - { - return e.first; - } - - static data_type& - get_item(Container& container, index_type i_) - { - typename Container::iterator i = container.find(i_); - if (i == container.end()) - { - PyErr_SetString(PyExc_KeyError, "Invalid key"); - throw_error_already_set(); - } - return i->second; - } - - static void - set_item(Container& container, index_type i, data_type const& v) - { - container[i] = v; - } - - static void - delete_item(Container& container, index_type i) - { - container.erase(i); - } - - static size_t - size(Container& container) - { - return container.size(); - } - - static bool - contains(Container& container, key_type const& key) - { - return container.find(key) != container.end(); - } - - static bool - compare_index(Container& container, index_type a, index_type b) - { - return container.key_comp()(a, b); - } - - static index_type - convert_index(Container& container, PyObject* i_) - { - extract i(i_); - if (i.check()) - { - return i(); - } - else - { - extract i(i_); - if (i.check()) - return i(); - } - - PyErr_SetString(PyExc_TypeError, "Invalid index type"); - throw_error_already_set(); - return index_type(); - } - }; - -}} // namespace boost::python - -#endif // MAP_INDEXING_SUITE_JDG20038_HPP diff --git a/include/boost/python/suite/indexing/vector_indexing_suite.hpp b/include/boost/python/suite/indexing/vector_indexing_suite.hpp deleted file mode 100644 index 20c58af6..00000000 --- a/include/boost/python/suite/indexing/vector_indexing_suite.hpp +++ /dev/null @@ -1,227 +0,0 @@ -// (C) Copyright Joel de Guzman 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 VECTOR_INDEXING_SUITE_JDG20036_HPP -# define VECTOR_INDEXING_SUITE_JDG20036_HPP - -# include -# include -# include - -namespace boost { namespace python { - - // Forward declaration - template - class vector_indexing_suite; - - namespace detail - { - template - class final_vector_derived_policies - : public vector_indexing_suite > {}; - } - - // The vector_indexing_suite class is a predefined indexing_suite derived - // class for wrapping std::vector (and std::vector like) classes. It provides - // all the policies required by the indexing_suite (see indexing_suite). - // Example usage: - // - // class X {...}; - // - // ... - // - // class_ >("XVec") - // .def(vector_indexing_suite >()) - // ; - // - // By default indexed elements are returned by proxy. This can be - // disabled by supplying *true* in the NoProxy template parameter. - // - template < - class Container, - bool NoProxy = false, - class DerivedPolicies - = detail::final_vector_derived_policies > - class vector_indexing_suite - : public indexing_suite - { - public: - - typedef typename Container::value_type data_type; - typedef typename Container::value_type key_type; - typedef typename Container::size_type index_type; - typedef typename Container::size_type size_type; - typedef typename Container::difference_type difference_type; - - template - static void - extension_def(Class& cl) - { - cl - .def("append", &base_append) - .def("extend", &base_extend) - ; - } - - static - typename mpl::if_< - is_class - , data_type& - , data_type - >::type - get_item(Container& container, index_type i) - { - return container[i]; - } - - static object - get_slice(Container& container, index_type from, index_type to) - { - return object(Container(container.begin()+from, container.begin()+to)); - } - - static void - set_item(Container& container, index_type i, data_type const& v) - { - container[i] = v; - } - - static void - set_slice(Container& container, index_type from, - index_type to, data_type const& v) - { - container.erase(container.begin()+from, container.begin()+to); - container.insert(container.begin()+from, v); - } - - template - static void - set_slice(Container& container, index_type from, - index_type to, Iter first, Iter last) - { - container.erase(container.begin()+from, container.begin()+to); - container.insert(container.begin()+from, first, last); - } - - static void - delete_item(Container& container, index_type i) - { - container.erase(container.begin()+i); - } - - static void - delete_slice(Container& container, index_type from, index_type to) - { - container.erase(container.begin()+from, container.begin()+to); - } - - static size_t - size(Container& container) - { - return container.size(); - } - - static bool - contains(Container& container, key_type const& key) - { - return std::find(container.begin(), container.end(), key) - != container.end(); - } - - static index_type - get_min_index(Container& container) - { - return 0; - } - - static index_type - get_max_index(Container& container) - { - return container.size(); - } - - static bool - compare_index(Container& container, index_type a, index_type b) - { - return a < b; - } - - static index_type - convert_index(Container& container, PyObject* i_) - { - extract i(i_); - if (i.check()) - { - long index = i(); - if (index < 0) - index += DerivedPolicies::size(container); - if (index >= long(container.size()) || index < 0) - { - PyErr_SetString(PyExc_IndexError, "Index out of range"); - throw_error_already_set(); - } - return index; - } - - PyErr_SetString(PyExc_TypeError, "Invalid index type"); - throw_error_already_set(); - return index_type(); - } - - static void - append(Container& container, data_type const& v) - { - container.push_back(v); - } - - template - static void - extend(Container& container, Iter first, Iter last) - { - container.insert(container.end(), first, last); - } - - private: - - static void - base_append(Container& container, object v) - { - extract elem(v); - // try if elem is an exact Data - if (elem.check()) - { - DerivedPolicies::append(container, elem()); - } - else - { - // try to convert elem to data_type - extract elem(v); - if (elem.check()) - { - DerivedPolicies::append(container, elem()); - } - else - { - PyErr_SetString(PyExc_TypeError, - "Attempting to append an invalid type"); - throw_error_already_set(); - } - } - } - - static void - base_extend(Container& container, object v) - { - std::vector temp; - container_utils::extend_container(temp, v); - DerivedPolicies::extend(container, temp.begin(), temp.end()); - } - }; - -}} // namespace boost::python - -#endif // VECTOR_INDEXING_SUITE_JDG20036_HPP diff --git a/include/boost/python/tag.hpp b/include/boost/python/tag.hpp deleted file mode 100644 index ff27071b..00000000 --- a/include/boost/python/tag.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 TAG_DWA2002720_HPP -# define TAG_DWA2002720_HPP - -# include - -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 7d859025..00000000 --- a/include/boost/python/to_python_converter.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 TO_PYTHON_CONVERTER_DWA200221_HPP -# define TO_PYTHON_CONVERTER_DWA200221_HPP - -# include - -# 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 61dff0d5..00000000 --- a/include/boost/python/to_python_indirect.hpp +++ /dev/null @@ -1,116 +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 -# 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 f726ec9e..00000000 --- a/include/boost/python/to_python_value.hpp +++ /dev/null @@ -1,130 +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 -# 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 - { - typedef converter::registered r; -# if BOOST_WORKAROUND(__GNUC__, < 3) - // suppresses an ICE, somehow - (void)r::converters; -# endif - 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 ce2fa96f..00000000 --- a/include/boost/python/tuple.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 TUPLE_20020706_HPP -#define TUPLE_20020706_HPP - -# include - -#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 96ca44da..00000000 --- a/include/boost/python/type_id.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 TYPE_ID_DWA2002517_HPP -# define TYPE_ID_DWA2002517_HPP - -# include - -# include -# include -# include -# include -# include -# include - -# ifndef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE -# if defined(__GNUC__) \ - && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) -# define BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE -# endif -# endif - -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; -}; - -# ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS -# define BOOST_PYTHON_EXPLICIT_TT_DEF(T) ::boost::type* -# else -# define BOOST_PYTHON_EXPLICIT_TT_DEF(T) -# endif - -template -inline type_info type_id(BOOST_EXPLICIT_TEMPLATE_TYPE(T)) -{ - 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((boost::type*)0) -# 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_PYTHON_EXPLICIT_TT_DEF(T)) \ -{ \ - 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 -} - -# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE -namespace detail -{ - BOOST_PYTHON_DECL char const* gcc_demangle(char const*); -} -# endif - -inline char const* type_info::name() const -{ - char const* raw_name - = m_base_type -# ifndef BOOST_PYTHON_TYPE_ID_NAME - ->name() -# endif - ; - -# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE - return detail::gcc_demangle(raw_name); -# else - return raw_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 bc919360..00000000 --- a/include/boost/python/with_custodian_and_ward.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 WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP -# define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP - -# include - -# 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 40f1ae14..00000000 --- a/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - -Automatically loading index page... if nothing happens, please go to -doc/index.html. - - 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 bd49c832..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 BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return PyInt_AS_LONG(intermediate); - } - else - { - BOOST_PYTHON_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 BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate) - { - if (PyInt_Check(intermediate)) - { - return numeric_cast(PyInt_AS_LONG(intermediate)); - } - else - { - unsigned BOOST_PYTHON_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 d12fb756..00000000 --- a/src/converter/from_python.cpp +++ /dev/null @@ -1,292 +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 - -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 <= 1) - { - 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 2e747a14..00000000 --- a/src/converter/registry.cpp +++ /dev/null @@ -1,237 +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 - -#if defined(__APPLE__) && defined(__MACH__) && defined(__GNUC__) \ - && __GNUC__ == 3 && __GNUC_MINOR__ == 3 && !defined(__APPLE_CC__) -# define BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND -#endif - -#if defined(BOOST_PYTHON_TRACE_REGISTRY) \ - || defined(BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND) -# 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") - , this->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; - -#ifndef BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND - 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; - } -#else - registry_t& static_registry() - { - static registry_t result; - return result; - } - - bool static_builtin_converters_initialized() - { - static bool result = false; - if (result == false) { - result = true; - std::cout << std::flush; - return false; - } - return true; - } - - registry_t& entries() - { -# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION - if (!static_builtin_converters_initialized()) - { - initialize_builtin_converters(); - } -# ifdef BOOST_PYTHON_TRACE_REGISTRY - std::cout << "registry: "; - for (registry_t::iterator p = static_registry().begin(); p != static_registry().end(); ++p) - { - std::cout << p->target_type << "; "; - } - std::cout << '\n'; -# endif -# endif - return static_registry(); - } -#endif // BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND - - 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 - std::pair pos_ins - = entries().insert(entry(type)); - -# if __MWERKS__ >= 0x3000 - // do a little invariant checking if a change was made - if ( pos_ins.second ) - assert(entries().invariants()); -# endif - return const_cast(&*pos_ins.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 528c5129..00000000 --- a/src/converter/type_id.cpp +++ /dev/null @@ -1,131 +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 - -#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT -# include -#else -# include -#endif - - -# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE -# if defined(__GNUC__) && __GNUC__ >= 3 -# include -# endif -# endif - -namespace boost { namespace python { - -# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE -# ifdef __GNUC__ -# if __GNUC__ < 3 - -namespace cxxabi = :: ; -# else -namespace cxxabi = ::abi; // GCC 3.1 and later -# endif -# endif - -namespace -{ - struct compare_first_cstring - { - template - bool operator()(T const& x, T const& y) - { - return std::strcmp(x.first,y.first) < 0; - } - }; - - struct free_mem - { - free_mem(char*p) - : p(p) {} - - ~free_mem() - { - std::free(p); - } - char* p; - }; -} - -namespace detail -{ - BOOST_PYTHON_DECL char const* gcc_demangle(char const* mangled) - { - typedef std::vector< - std::pair - > mangling_map; - - static mangling_map demangler; - mangling_map::iterator p - = std::lower_bound( - demangler.begin(), demangler.end() - , std::make_pair(mangled, (char const*)0) - , compare_first_cstring()); - - if (p == demangler.end() || strcmp(p->first, mangled)) - { - int status; - free_mem keeper( - cxxabi::__cxa_demangle(mangled, 0, 0, &status) - ); - - assert(status != -3); // invalid argument error - - if (status == -1) - { - throw std::bad_alloc(); - } - else - { - char const* demangled - = status == -2 - // Invalid mangled name. Best we can do is to - // return it intact. - ? mangled - : keeper.p; - - p = demangler.insert(p, std::make_pair(mangled, demangled)); - keeper.p = 0; - } - } - - return p->second; - } -} -# endif - -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 6a23fc9a..00000000 --- a/src/errors.cpp +++ /dev/null @@ -1,98 +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 { - -error_already_set::~error_already_set() {} - -// 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_error_already_set() -{ - throw error_already_set(); -} - -namespace detail { - -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 30ee78a0..00000000 --- a/src/list.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 - -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; - -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); -} - -// For some reason, moving this to the end of the TU suppresses an ICE -// with vc6. -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; -} - -}}} // 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 18a5061a..00000000 --- a/src/module.cpp +++ /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. - -#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 { - -namespace detail -{ - BOOST_PYTHON_DECL PyObject* 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 0bc59c12..00000000 --- a/src/object/class.cpp +++ /dev/null @@ -1,686 +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 // #including this first is an intel6 workaround - -#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() -{ -} - -extern "C" -{ - // 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; - } - - // This is also copied from the Python sources. We can't implement - // static_data as a subclass property effectively without it. - typedef struct { - PyObject_HEAD - PyObject *prop_get; - PyObject *prop_set; - PyObject *prop_del; - PyObject *prop_doc; - } propertyobject; - - static PyObject * - static_data_descr_get(PyObject *self, PyObject *obj, PyObject * /*type*/) - { - propertyobject *gs = (propertyobject *)self; - - return PyObject_CallFunction(gs->prop_get, "()"); - } - - static int - static_data_descr_set(PyObject *self, PyObject *obj, PyObject *value) - { - propertyobject *gs = (propertyobject *)self; - PyObject *func, *res; - - if (value == NULL) - func = gs->prop_del; - else - func = gs->prop_set; - if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, - value == NULL ? - "can't delete attribute" : - "can't set attribute"); - return -1; - } - if (value == NULL) - res = PyObject_CallFunction(func, "()"); - else - res = PyObject_CallFunction(func, "(O)", value); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; - } -} - -static PyTypeObject static_data_object = { - PyObject_HEAD_INIT(0)//&PyType_Type) - 0, - "Boost.Python.StaticProperty", - 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, //&PyProperty_Type, /* tp_base */ - 0, /* tp_dict */ - static_data_descr_get, /* tp_descr_get */ - static_data_descr_set, /* 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 */ -}; - -namespace objects -{ - extern "C" - { - // This declaration needed due to broken Python 2.2 headers - extern DL_IMPORT(PyTypeObject) PyProperty_Type; - } - - BOOST_PYTHON_DECL PyObject* static_data() - { - if (static_data_object.tp_dict == 0) - { - static_data_object.ob_type = &PyType_Type; - static_data_object.tp_base = &PyProperty_Type; - if (PyType_Ready(&static_data_object)) - return 0; - } - return upcast(&static_data_object); - } -} - -extern "C" -{ - // Ordinarily, descriptors have a certain assymetry: you can use - // them to read attributes off the class object they adorn, but - // writing the same attribute on the class object always replaces - // the descriptor in the class __dict__. In order to properly - // represent C++ static data members, we need to allow them to be - // written through the class instance. This function of the - // metaclass makes it possible. - static int - class_setattro(PyObject *obj, PyObject *name, PyObject* value) - { - // Must use "private" Python implementation detail - // _PyType_Lookup instead of PyObject_GetAttr because the - // latter will always end up calling the descr_get function on - // any descriptor it finds; we need the unadulterated - // descriptor here. - PyObject* a = _PyType_Lookup(downcast(obj), name); - - // a is a borrowed reference or 0 - - // If we found a static data descriptor, call it directly to - // force it to set the static data member - if (a != 0 && PyObject_IsInstance(a, objects::static_data())) - return a->ob_type->tp_descr_set(a, obj, value); - else - return PyType_Type.tp_setattro(obj, name, value); - } -} - -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 */ - class_setattro, /* 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(); -// class_type_object.tp_setattro = class_setattro; - } - 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(type_info 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(type_info 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, type_info 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, type_info 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()); - } - - BOOST_PYTHON_DECL void copy_class_object(type_info const& src, type_info const& dst) - { - converter::registration& dst_converters - = const_cast(converter::registry::lookup(dst)); - - converter::registration const& src_converters = converter::registry::lookup(src); - - dst_converters.m_class_object = src_converters.m_class_object; - } - - void class_base::set_instance_size(std::size_t instance_size) - { - this->attr("__instance_size__") = instance_size; - } - - 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::add_static_property(char const* name, object const& fget) - { - object property( - (python::detail::new_reference) - PyObject_CallFunction(static_data(), "O", fget.ptr())); - - this->setattr(name, property); - } - - void class_base::add_static_property(char const* name, object const& fget, object const& fset) - { - object property( - (python::detail::new_reference) - PyObject_CallFunction(static_data(), "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(type_info 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 3f6cdcf6..00000000 --- a/src/object/function.cpp +++ /dev/null @@ -1,649 +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 - -#if BOOST_PYTHON_DEBUG_ERROR_MESSAGES -# include -#endif - -namespace boost { namespace python { namespace objects { - -py_function_impl_base::~py_function_impl_base() -{ -} - -unsigned py_function_impl_base::max_arity() const -{ - return this->min_arity(); -} - -extern PyTypeObject function_type; - -function::function( - py_function const& implementation -#if BOOST_WORKAROUND(__EDG_VERSION__, == 245) - , python::detail::keyword const* names_and_defaults -#else - , python::detail::keyword const* const names_and_defaults -#endif - , unsigned num_keywords - ) - : m_fn(implementation) - , m_nkeyword_values(0) -{ - if (names_and_defaults != 0) - { - unsigned int max_arity = m_fn.max_arity(); - unsigned int keyword_offset - = max_arity > num_keywords ? max_arity - num_keywords : 0; - - - unsigned tuple_size = num_keywords ? 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) - { - tuple kv; - - python::detail::keyword const* const p = names_and_defaults + i; - if (p->default_value) - { - kv = make_tuple(p->name, p->default_value); - ++m_nkeyword_values; - } - else - { - kv = make_tuple(p->name); - } - - PyTuple_SET_ITEM( - m_arg_names.ptr() - , i + keyword_offset - , incref(kv.ptr()) - ); - } - } - - 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 n_unnamed_actual = PyTuple_GET_SIZE(args); - std::size_t n_keyword_actual = keywords ? PyDict_Size(keywords) : 0; - std::size_t n_actual = n_unnamed_actual + n_keyword_actual; - - function const* f = this; - - // Try overloads looking for a match - do - { - // Check for a plausible number of arguments - unsigned min_arity = f->m_fn.min_arity(); - unsigned max_arity = f->m_fn.max_arity(); - - if (n_actual + f->m_nkeyword_values >= min_arity - && n_actual <= max_arity) - { - // This will be the args that actually get passed - handle<>inner_args(allow_null(borrowed(args))); - - if (n_keyword_actual > 0 // Keyword arguments were supplied - || n_actual < min_arity) // or default keyword values are needed - { - if (f->m_arg_names.ptr() == Py_None) - { - // this overload doesn't accept keywords - inner_args = handle<>(); - } - else - { - // "all keywords are none" is a special case - // indicating we will accept any number of keyword - // arguments - if (PyTuple_Size(f->m_arg_names.ptr()) == 0) - { - // no argument preprocessing - } - else if (n_actual > max_arity) - { - // too many arguments - inner_args = handle<>(); - } - else - { - // build a new arg tuple, will adjust its size later - inner_args = handle<>(PyTuple_New(max_arity)); - - // Fill in the positional arguments - for (std::size_t i = 0; i < n_unnamed_actual; ++i) - PyTuple_SET_ITEM(inner_args.get(), i, incref(PyTuple_GET_ITEM(args, i))); - - // Grab remaining arguments by name from the keyword dictionary - std::size_t n_actual_processed = n_unnamed_actual; - - for (std::size_t arg_pos = n_unnamed_actual; arg_pos < max_arity ; ++arg_pos) - { - // Get the keyword[, value pair] corresponding - PyObject* kv = PyTuple_GET_ITEM(f->m_arg_names.ptr(), arg_pos); - - // If there were any keyword arguments, - // look up the one we need for this - // argument position - PyObject* value = n_keyword_actual - ? PyDict_GetItem(keywords, PyTuple_GET_ITEM(kv, 0)) - : 0; - - if (!value) - { - // Not found; check if there's a default value - if (PyTuple_GET_SIZE(kv) > 1) - value = PyTuple_GET_ITEM(kv, 1); - - if (!value) - { - // still not found; matching fails - PyErr_Clear(); - inner_args = handle<>(); - break; - } - } - else - { - ++n_actual_processed; - } - - PyTuple_SET_ITEM(inner_args.get(), arg_pos, incref(value)); - } - - if (inner_args.get()) - { - //check if we proccessed all the arguments - if(n_actual_processed < n_actual) - inner_args = handle<>(); - } - } - } - } - - // Call the function. Pass keywords in case it's a - // function accepting any number of keywords - PyObject* result = inner_args ? f->m_fn(inner_args.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 -{ - static handle<> exception( - PyErr_NewException("Boost.Python.ArgumentError", PyExc_TypeError, 0)); - - object message = "Python argument types in\n %s.%s(" - % make_tuple(this->m_namespace, this->m_name); - - list actual; - for (int i = 0; i < PyTuple_Size(args); ++i) - { - char const* name = PyTuple_GetItem(args, i)->ob_type->tp_name; - actual.append(str(name)); - } - message += str(", ").join(actual); - message += ")\ndid not match C++ signature:\n "; - - list signatures; - for (function const* f = this; f; f = f->m_overloads.get()) - { - py_function const& impl = f->m_fn; - - python::detail::signature_element const* s - = impl.signature(); - - list formal; - if (impl.max_arity() == 0) - formal.append("void"); - - for (unsigned n = 1; n <= impl.max_arity(); ++n) - { - if (s[n].basename == 0) - { - formal.append("..."); - break; - } - - formal.append( - str(s[n].basename) + (s[n].lvalue ? " {lvalue}" : "") - ); - } - - signatures.append( - "%s(%s)" % make_tuple(f->m_name, str(", ").join(formal)) - ); - } - - message += str("\n ").join(signatures); - -#if BOOST_PYTHON_DEBUG_ERROR_MESSAGES - std::printf("\n--------\n%s\n--------\n", extract(message)()); -#endif - PyErr_SetObject(exception.get(), message.ptr()); - throw_error_already_set(); -} - -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(PyObject*, PyObject*) - { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - handle not_implemented_function() - { - - static object keeper( - function_object( - py_function(¬_implemented, mpl::vector1(), 2) - , 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(); - - handle<> existing(allow_null(::PyObject_GetItem(dict, name.ptr()))); - - if (existing) - { - if (existing->ob_type == &function_type) - { - new_func->add_overload( - handle( - borrowed( - downcast(existing.get()) - ) - ) - ); - } - 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; - - handle<> name_space_name( - allow_null(::PyObject_GetAttrString(name_space.ptr(), "__name__"))); - - if (name_space_name) - new_func->m_namespace = object(name_space_name); - } - - // The PyObject_GetAttrString() or PyObject_GetItem calls above may - // have 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 }, - {"func_name", (getter)function_get_name, 0 }, - {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, - {"func_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 - , python::detail::keyword_range const& keywords) -{ - return python::object( - python::detail::new_non_null_reference( - new function( - f, keywords.first, keywords.second - keywords.first))); -} - -object function_object(py_function const& f) -{ - return function_object(f, python::detail::keyword_range()); -} - - -handle<> function_handle_impl(py_function const& f) -{ - return python::handle<>( - allow_null( - new function(f, 0, 0))); -} - -} // namespace objects - -namespace detail -{ - object BOOST_PYTHON_DECL make_raw_function(objects::py_function f) - { - static keyword k; - - return objects::function_object( - f - , keyword_range(&k,&k)); - } - void BOOST_PYTHON_DECL pure_virtual_called() - { - PyErr_SetString(PyExc_RuntimeError, "Pure virtual function called"); - throw_error_already_set(); - } -} - -}} // namespace boost::python 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 bfde2680..00000000 --- a/src/object/iterator.cpp +++ /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. - -#include -#include -#include -#include - -namespace boost { namespace python { namespace objects { - -namespace -{ - 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( - py_function(&identity, mpl::vector2()) - ) - ); - 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 a7eca8f7..00000000 --- a/src/object/life_support.cpp +++ /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. -#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); - - // weakref has either taken ownership, or we have to release it - // anyway - Py_DECREF(system); - if (!weakref) - 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 fc29aa03..00000000 --- a/src/str.cpp +++ /dev/null @@ -1,316 +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)) -{} - -#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/Jamfile b/test/Jamfile deleted file mode 100644 index 9895e96a..00000000 --- a/test/Jamfile +++ /dev/null @@ -1,205 +0,0 @@ -# -# To run all tests quietly: jam test -# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test -# -subproject libs/python/test ; - -# bring in the rules for python -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; -# bring in rules for testing -SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; -include testing.jam ; - -# Convenience rule makes declaring tests faster -rule bpl-test ( name ? : files * : requirements * ) -{ - files ?= $(name).py $(name).cpp ; - - local modules ; - local py ; - for local f in $(files) - { - if $(f:S) = .py - { - if $(py) - { - EXIT too many python drivers specified: "$(py)" "$(f)" ; - } - py = $(f) ; - } - } - - name ?= $(py:S=) ; - - for local f in $(files) - { - if $(f:S) != .py - { - local m = $(f:S=) ; - - if $(m) = $(py:S=) - { - m = $(name) ; - - if $(m) = $(py:S=) - { - m = $(m)_ext ; - } - } - extension $(m) : $(f) ../build/boost_python : $(requirements) ; - modules += $(m) ; - } - } - - boost-python-runtest $(name) : $(py) $(modules) ; -} - -run ../test/embedding.cpp ../build/boost_python - : # program args - : # input files - : # requirements - $(PYTHON_PROPERTIES) - BOOST_PYTHON_STATIC_LIB - BOOST_PYTHON_STATIC_MODULE - $(PYTHON_LIB_PATH) - <$(gcc-compilers)>$(CYGWIN_PYTHON_DEBUG_DLL_PATH) - <$(gcc-compilers)><*>$(CYGWIN_PYTHON_DLL_PATH) - $(PYTHON_EMBEDDED_LIBRARY) ; - -bpl-test crossmod_exception - : crossmod_exception.py crossmod_exception_a.cpp crossmod_exception_b.cpp - ; - -bpl-test properties ; -bpl-test return_arg ; -bpl-test staticmethod ; -bpl-test shared_ptr ; -bpl-test polymorphism ; -bpl-test auto_ptr ; -bpl-test minimal ; -bpl-test args ; -bpl-test numpy ; -bpl-test enum ; -bpl-test exception_translator ; -bpl-test pearu1 : test_cltree.py cltree.cpp ; -bpl-test try : newtest.py m1.cpp m2.cpp ; - -bpl-test keywords : keywords.cpp keywords_test.py ; - -extension builtin_converters : test_builtin_converters.cpp ../build/boost_python ; -boost-python-runtest builtin_converters : test_builtin_converters.py builtin_converters ; - -bpl-test test_pointer_adoption ; -bpl-test operators ; -bpl-test callbacks ; -bpl-test defaults ; - -bpl-test object ; -bpl-test list ; -bpl-test long ; -bpl-test dict ; -bpl-test tuple ; -bpl-test str ; - -bpl-test virtual_functions ; -bpl-test back_reference ; -bpl-test implicit ; -bpl-test data_members ; - -bpl-test ben_scott1 ; - -bpl-test bienstman1 ; -bpl-test bienstman2 ; -bpl-test bienstman3 ; - -# A bug in the Win32 intel compilers causes compilation of one of our -# tests to take forever when debug symbols are enabled. This rule -# turns them off when added to the requirements section -rule turn-off-intel-debug-symbols ( toolset variant : properties * ) -{ - if $(NT) && [ MATCH (.*intel.*) : $(toolset) ] - { - properties = [ difference $(properties) : on ] off ; - } - return $(properties) ; -} - -bpl-test multi_arg_constructor - : # files - : # requirements - turn-off-intel-debug-symbols ; # debug symbols slow the build down too much - -bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ; - -bpl-test extract ; - -bpl-test opaque ; - -bpl-test pickle1 ; -bpl-test pickle2 ; -bpl-test pickle3 ; - -bpl-test nested ; - -bpl-test docstring ; - -bpl-test vector_indexing_suite ; -bpl-test map_indexing_suite ; - -if $(TEST_BIENSTMAN_NON_BUGS) -{ - bpl-test bienstman4 ; - bpl-test bienstman5 ; -} - -# --- unit tests of library components --- - -local UNIT_TEST_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION - [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; - -run indirect_traits_test.cpp ; -run destroy_test.cpp ; -run pointer_type_id_test.cpp ../../test/build/boost_test_exec_monitor : : : $(UNIT_TEST_PROPERTIES) ; -run member_function_cast.cpp ; -run bases.cpp : : : $(UNIT_TEST_PROPERTIES) ; -run if_else.cpp ; -run pointee.cpp : : : $(UNIT_TEST_PROPERTIES) ; -run result.cpp ; - -compile string_literal.cpp ; -compile borrowed.cpp : $(UNIT_TEST_PROPERTIES) ; -compile object_manager.cpp : $(UNIT_TEST_PROPERTIES) ; -compile copy_ctor_mutates_rhs.cpp : $(UNIT_TEST_PROPERTIES) ; - -run upcast.cpp ../../test/build/boost_test_exec_monitor - : # command-line args - : # input files - : $(UNIT_TEST_PROPERTIES) - ; - -run select_holder.cpp ../../test/build/boost_test_exec_monitor - : # command-line args - : # input files - : $(UNIT_TEST_PROPERTIES) - ; - - -run select_from_python_test.cpp ../src/converter/type_id.cpp ../../test/build/boost_test_exec_monitor - : # command-line args - : # input files - : $(UNIT_TEST_PROPERTIES) - ; - -run select_arg_to_python_test.cpp ../src/converter/type_id.cpp ../../test/build/boost_test_exec_monitor - : # command-line args - : # input files - : $(UNIT_TEST_PROPERTIES) - ; - -compile-fail ./raw_pyobject_fail1.cpp : $(PYTHON_PROPERTIES) ; -compile-fail ./raw_pyobject_fail2.cpp : $(PYTHON_PROPERTIES) ; -compile-fail ./as_to_python_function.cpp : $(PYTHON_PROPERTIES) ; -compile-fail ./object_fail1.cpp : $(PYTHON_PROPERTIES) ; - - diff --git a/test/args.cpp b/test/args.cpp deleted file mode 100644 index c494b9d7..00000000 --- a/test/args.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 -#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<>()); -} - -#include "module_tail.cpp" diff --git a/test/args.py b/test/args.py deleted file mode 100644 index 6cb66226..00000000 --- a/test/args.py +++ /dev/null @@ -1,179 +0,0 @@ -""" ->>> from args_ext import * - ->>> raw(3, 4, foo = 'bar', baz = 42) -((3, 4), {'foo': 'bar', 'baz': 42}) - - Prove that we can handle empty keywords and non-keywords - ->>> raw(3, 4) -((3, 4), {}) - ->>> raw(foo = 'bar') -((), {'foo': 'bar'}) - ->>> 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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 d8e416e9..00000000 --- a/test/auto_ptr.py +++ /dev/null @@ -1,79 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/back_reference.cpp b/test/back_reference.cpp deleted file mode 100644 index f2545f57..00000000 --- a/test/back_reference.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 -#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 - : mpl::true_ - { - }; - - template <> - struct has_back_reference - : mpl::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 61a56a62..00000000 --- a/test/back_reference.py +++ /dev/null @@ -1,31 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 14773617..00000000 --- a/test/bienstman1.py +++ /dev/null @@ -1,20 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 b1945331..00000000 --- a/test/bienstman2.py +++ /dev/null @@ -1,17 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 4629607a..00000000 --- a/test/bienstman3.py +++ /dev/null @@ -1,27 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 a42ea7f3..00000000 --- a/test/bienstman4.py +++ /dev/null @@ -1,20 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 4e35d970..00000000 --- a/test/bienstman5.py +++ /dev/null @@ -1,18 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 83e78099..00000000 --- a/test/callbacks.py +++ /dev/null @@ -1,144 +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 ReferenceError: pass # expected -... else: print 'expected an exception!' - ->>> try: apply_X_ref_handle(lambda ignored:X(42), None) -... except ReferenceError: pass # expected -... else: print 'expected an exception!' - ->>> x = X(42) ->>> x.y = X(7) ->>> apply_X_ref_handle(lambda z:z.y, x).value() -7 - ->>> 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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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/crossmod_exception.py b/test/crossmod_exception.py deleted file mode 100644 index c8430849..00000000 --- a/test/crossmod_exception.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2003 Rational Discovery LLC -# 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. - -print "running..." - -import crossmod_exception_a -import crossmod_exception_b - -try: - crossmod_exception_b.tossit() -except IndexError: - pass -try: - crossmod_exception_a.tossit() -except IndexError: - pass - -print "Done." diff --git a/test/crossmod_exception_a.cpp b/test/crossmod_exception_a.cpp deleted file mode 100755 index c39c41a9..00000000 --- a/test/crossmod_exception_a.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2003 Rational Discovery LLC -// 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 python = boost::python; - -void tossit(){ - PyErr_SetString(PyExc_IndexError,"a-blah!"); - throw python::error_already_set(); -} - -BOOST_PYTHON_MODULE(crossmod_exception_a) -{ - python::def("tossit",tossit); -} diff --git a/test/crossmod_exception_b.cpp b/test/crossmod_exception_b.cpp deleted file mode 100755 index 17c88617..00000000 --- a/test/crossmod_exception_b.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2003 Rational Discovery LLC -// 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 python = boost::python; - -void tossit(){ - PyErr_SetString(PyExc_IndexError,"b-blah!"); - throw python::error_already_set(); -} - -BOOST_PYTHON_MODULE(crossmod_exception_b) -{ - python::def("tossit",tossit); -} diff --git a/test/data_members.cpp b/test/data_members.cpp deleted file mode 100644 index 3ebe9d7d..00000000 --- a/test/data_members.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 -#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; - -struct Y : test_class<1> -{ - Y(int v) : test_class<1>(v) {} - Y& operator=(Y const& rhs) { x = rhs.x; return *this; } -}; - -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; - - static int static1; - static Y static2; -}; - -int Var::static1 = 0; -Y Var::static2(0); - -// Compilability regression tests -namespace -{ - struct trivial - { - trivial() : value(123) {} - double value; - }; - - struct Color3 - { - static const Color3 black; - }; - - const Color3 Color3::black -#if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(3)) - = {} -#endif - ; - - void compilability_test() - { - class_("trivial") - .add_property("property", make_getter(&trivial::value, return_value_policy())) - .def_readonly("readonly", &trivial::value) - ; - - class_< Color3 >("Color3", init< const Color3 & >()) - .def_readonly("BLACK", &Color3::black) // line 17 - ; - } -} - -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) - - // Test static data members - .def_readonly("ro1a", &Var::static1) - .def_readonly("ro1b", Var::static1) - .def_readwrite("rw1a", &Var::static1) - .def_readwrite("rw1b", Var::static1) - - .def_readonly("ro2a", &Var::static2) - .def_readonly("ro2b", Var::static2) - .def_readwrite("rw2a", &Var::static2) - .def_readwrite("rw2b", Var::static2) - ; -} - -#include "module_tail.cpp" diff --git a/test/data_members.py b/test/data_members.py deleted file mode 100644 index ad6cf3c3..00000000 --- a/test/data_members.py +++ /dev/null @@ -1,203 +0,0 @@ -''' ->>> from data_members_ext import * - - ---- Test static data members --- - ->>> v = Var('slim shady') - ->>> Var.ro2a.x -0 ->>> Var.ro2b.x -0 ->>> Var.rw2a.x -0 ->>> Var.rw2b.x -0 ->>> v.ro2a.x -0 ->>> v.ro2b.x -0 ->>> v.rw2a.x -0 ->>> v.rw2b.x -0 ->>> Var.rw2a.x = 777 ->>> Var.ro2a.x -777 ->>> Var.ro2b.x -777 ->>> Var.rw2a.x -777 ->>> Var.rw2b.x -777 ->>> v.ro2a.x -777 ->>> v.ro2b.x -777 ->>> v.rw2a.x -777 ->>> v.rw2b.x -777 ->>> Var.rw2b = Y(888) ->>> Var.ro2a.x -888 ->>> Var.ro2b.x -888 ->>> Var.rw2a.x -888 ->>> Var.rw2b.x -888 ->>> v.ro2a.x -888 ->>> v.ro2b.x -888 ->>> v.rw2a.x -888 ->>> v.rw2b.x -888 ->>> v.rw2b.x = 999 ->>> Var.ro2a.x -999 ->>> Var.ro2b.x -999 ->>> Var.rw2a.x -999 ->>> Var.rw2b.x -999 ->>> v.ro2a.x -999 ->>> v.ro2b.x -999 ->>> v.rw2a.x -999 ->>> v.rw2b.x -999 - - ->>> Var.ro1a -0 ->>> Var.ro1b -0 ->>> Var.rw1a -0 ->>> Var.rw1b -0 ->>> v.ro1a -0 ->>> v.ro1b -0 ->>> v.rw1a -0 ->>> v.rw1b -0 ->>> Var.rw1a = 777 ->>> Var.ro1a -777 ->>> Var.ro1b -777 ->>> Var.rw1a -777 ->>> Var.rw1b -777 ->>> v.ro1a -777 ->>> v.ro1b -777 ->>> v.rw1a -777 ->>> v.rw1b -777 ->>> Var.rw1b = 888 ->>> Var.ro1a -888 ->>> Var.ro1b -888 ->>> Var.rw1a -888 ->>> Var.rw1b -888 ->>> v.ro1a -888 ->>> v.ro1b -888 ->>> v.rw1a -888 ->>> v.rw1b -888 ->>> v.rw1b = 999 ->>> Var.ro1a -999 ->>> Var.ro1b -999 ->>> Var.rw1a -999 ->>> Var.rw1b -999 ->>> v.ro1a -999 ->>> v.ro1b -999 ->>> v.rw1a -999 ->>> v.rw1b -999 - - - - ----------------- - ->>> 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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 26c7fc30..00000000 --- a/test/defaults.py +++ /dev/null @@ -1,176 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/destroy_test.cpp b/test/destroy_test.cpp deleted file mode 100644 index eaf121aa..00000000 --- a/test/destroy_test.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -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; -}; - -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); - - 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 2b003afa..00000000 --- a/test/dict.py +++ /dev/null @@ -1,43 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/docstring.cpp b/test/docstring.cpp deleted file mode 100644 index 6501e10f..00000000 --- a/test/docstring.cpp +++ /dev/null @@ -1,59 +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" - -// 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 9c948bec..00000000 --- a/test/docstring.py +++ /dev/null @@ -1,56 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/embedding.cpp b/test/embedding.cpp deleted file mode 100644 index e3940c50..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 9569e3b3..00000000 --- a/test/enum.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 -#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_); - -#if BOOST_WORKAROUND(__MWERKS__, <=0x2407) - color colorized::*px = &colorized::x; - class_("colorized") - .def_readwrite("x", px) - ; -#else - class_("colorized") - .def_readwrite("x", &colorized::x) - ; -#endif -} - -#include "module_tail.cpp" diff --git a/test/enum.py b/test/enum.py deleted file mode 100644 index 19107037..00000000 --- a/test/enum.py +++ /dev/null @@ -1,61 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 835c7172..00000000 --- a/test/exception_translator.py +++ /dev/null @@ -1,24 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/extract.cpp b/test/extract.cpp deleted file mode 100644 index b0b28342..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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test_class.hpp" - -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 505bdf07..00000000 --- a/test/extract.py +++ /dev/null @@ -1,104 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 90a6b09e..00000000 --- a/test/implicit.py +++ /dev/null @@ -1,28 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 e4021e83..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 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 28153e6c..00000000 --- a/test/iterator.py +++ /dev/null @@ -1,74 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/keywords.cpp b/test/keywords.cpp deleted file mode 100755 index 36205656..00000000 --- a/test/keywords.cpp +++ /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. -#include -#include - -struct Foo -{ - Foo( - int a = 0 - , double b = 0 - , const std::string &n = std::string() - ) : - a_(a) - , b_(b) - , n_(n) - {} - - void set(int a=0, double b=0, const std::string &n=std::string()) - { - a_ = a; - b_ = b; - n_ = n; - } - - int geta() const { return a_; } - - double getb() const { return b_; } - - std::string getn() const { return n_; } - -private: - int a_; - double b_; - std::string n_; -}; - -struct Bar -{ - Bar( - int a = 0 - , double b = 0 - , const std::string &n = std::string() - ) : - a_(a) - , b_(b) - , n_(n) - {} - - void set(int a=0, double b=0, const std::string &n=std::string()) - { - a_ = a; - b_ = b; - n_ = n; - } - - int geta() const { return a_; } - - double getb() const { return b_; } - - std::string getn() const { return n_; } - -private: - int a_; - double b_; - std::string n_; -}; - -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(bar_set, Bar::set, 0,3) - -using namespace boost::python; -#if BOOST_WORKAROUND(__GNUC__, == 2) -using boost::python::arg; -#endif -BOOST_PYTHON_MODULE(keywords) -{ - class_("Foo" , init< - int - , double - , const std::string & - >( - ( arg("a") = 0 - , arg("b") = 0.0 - , arg("n") = std::string() - ) - )) - - .def("set", &Foo::set, (arg("a") = 0, arg("b") = 0.0, arg("n") = std::string()) ) - .def("a", &Foo::geta) - .def("b", &Foo::getb) - .def("n", &Foo::getn) - ; - - class_("Bar" , init - >() - ) - - .def("set", &Bar::set, bar_set()) - .def("a", &Bar::geta) - .def("b", &Bar::getb) - .def("n", &Bar::getn) - ; - -} - - - -#include "module_tail.cpp" diff --git a/test/keywords_test.py b/test/keywords_test.py deleted file mode 100644 index 79cdf148..00000000 --- a/test/keywords_test.py +++ /dev/null @@ -1,96 +0,0 @@ -''' ->>> from keywords import * ->>> f = Foo() ->>> f.a(), f.b(), f.n() -(0, 0.0, '') ->>> f = Foo(1) ->>> f.a(), f.b(), f.n() -(1, 0.0, '') ->>> f = Foo(1,1.0) ->>> f.a(), f.b(), f.n() -(1, 1.0, '') ->>> f = Foo(1,1.0,"1") ->>> f.a(), f.b(), f.n() -(1, 1.0, '1') ->>> f = Foo(a=1) ->>> f.a(), f.b(), f.n() -(1, 0.0, '') ->>> f = Foo(b=1) ->>> f.a(), f.b(), f.n() -(0, 1.0, '') ->>> f = Foo(n="1") ->>> f.a(), f.b(), f.n() -(0, 0.0, '1') ->>> f = Foo(1,n="1") ->>> f.a(), f.b(), f.n() -(1, 0.0, '1') ->>> f.set() ->>> f.a(), f.b(), f.n() -(0, 0.0, '') ->>> f.set(1) ->>> f.a(), f.b(), f.n() -(1, 0.0, '') ->>> f.set(1,1.0) ->>> f.a(), f.b(), f.n() -(1, 1.0, '') ->>> f.set(1,1.0,"1") ->>> f.a(), f.b(), f.n() -(1, 1.0, '1') ->>> f.set(a=1) ->>> f.a(), f.b(), f.n() -(1, 0.0, '') ->>> f.set(b=1) ->>> f.a(), f.b(), f.n() -(0, 1.0, '') ->>> f.set(n="1") ->>> f.a(), f.b(), f.n() -(0, 0.0, '1') ->>> f.set(1,n="1") ->>> f.a(), f.b(), f.n() -(1, 0.0, '1') - -# lets see how badly we've broken the 'regular' functions ->>> f = Bar() ->>> f.a(), f.b(), f.n() -(0, 0.0, '') ->>> f = Bar(1) ->>> f.a(), f.b(), f.n() -(1, 0.0, '') ->>> f = Bar(1,1.0) ->>> f.a(), f.b(), f.n() -(1, 1.0, '') ->>> f = Bar(1,1.0,"1") ->>> f.a(), f.b(), f.n() -(1, 1.0, '1') ->>> f.set() ->>> f.a(), f.b(), f.n() -(0, 0.0, '') ->>> f.set(1) ->>> f.a(), f.b(), f.n() -(1, 0.0, '') ->>> f.set(1,1.0) ->>> f.a(), f.b(), f.n() -(1, 1.0, '') ->>> f.set(1,1.0,"1") ->>> f.a(), f.b(), f.n() -(1, 1.0, '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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) - 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 194eef32..00000000 --- a/test/list.py +++ /dev/null @@ -1,115 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/long.cpp b/test/long.cpp deleted file mode 100644 index 1fb96e50..00000000 --- a/test/long.cpp +++ /dev/null @@ -1,62 +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 - -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; -} - -// tests for accepting objects (and derived classes) in constructors -// from "Milind Patil" - -struct Y -{ - Y(boost::python::long_) {} -}; - -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); - - class_< Y >("Y", init< boost::python::long_ >()) - ; -} - diff --git a/test/long.py b/test/long.py deleted file mode 100644 index 9aeab91c..00000000 --- a/test/long.py +++ /dev/null @@ -1,30 +0,0 @@ -''' ->>> from long_ext import * ->>> new_long() -0L ->>> longify(42) -42L ->>> longify_string('300') -300L ->>> is_long(20L) -'yes' ->>> is_long('20') -0 - ->>> x = Y(4294967295) -''' - -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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/m1.cpp b/test/m1.cpp deleted file mode 100644 index 45dbf58b..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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "simple_type.hpp" -#include "complicated.hpp" - -// 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/map_indexing_suite.cpp b/test/map_indexing_suite.cpp deleted file mode 100644 index 604303a8..00000000 --- a/test/map_indexing_suite.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include - -using namespace boost::python; - -struct X // a container element -{ - std::string s; - X():s("default") {} - X(std::string s):s(s) {} - std::string repr() const { return s; } - void reset() { s = "reset"; } - void foo() { s = "foo"; } - bool operator==(X const& x) const { return s == x.s; } - bool operator!=(X const& x) const { return s != x.s; } -}; - -std::string x_value(X const& x) -{ - return "gotya " + x.s; -} - -BOOST_PYTHON_MODULE(map_indexing_suite_ext) -{ - class_("X") - .def(init<>()) - .def(init()) - .def(init()) - .def("__repr__", &X::repr) - .def("reset", &X::reset) - .def("foo", &X::foo) - ; - - def("x_value", x_value); - implicitly_convertible(); - - class_ >("XMap") - .def(map_indexing_suite >()) - ; - - // Compile check only... - class_ >("IntMap") - .def(map_indexing_suite >()) - ; -} - diff --git a/test/map_indexing_suite.py b/test/map_indexing_suite.py deleted file mode 100644 index f6752684..00000000 --- a/test/map_indexing_suite.py +++ /dev/null @@ -1,209 +0,0 @@ -''' - -##################################################################### -# Check an object that we will use as container element -##################################################################### - ->>> from map_indexing_suite_ext import * ->>> x = X('hi') ->>> x -hi ->>> x.reset() # a member function that modifies X ->>> x -reset ->>> x.foo() # another member function that modifies X ->>> x -foo - -# test that a string is implicitly convertible -# to an X ->>> x_value('bochi bochi') -'gotya bochi bochi' - -##################################################################### -# Iteration -##################################################################### ->>> def print_xmap(xmap): -... s = '[ ' -... for x in xmap: -... s += repr(x) -... s += ' ' -... s += ']' -... print s - -##################################################################### -# Setting (adding entries) -##################################################################### ->>> xm = XMap() ->>> xm['joel'] = 'apple' ->>> xm['tenji'] = 'orange' ->>> xm['mariel'] = 'grape' ->>> xm['tutit'] = 'banana' ->>> xm['kim'] = 'kiwi' - ->>> print_xmap(xm) -[ (joel, apple) (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ] - -##################################################################### -# Changing an entry -##################################################################### ->>> xm['joel'] = 'pineapple' ->>> print_xmap(xm) -[ (joel, pineapple) (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ] - -##################################################################### -# Deleting an entry -##################################################################### ->>> del xm['joel'] ->>> print_xmap(xm) -[ (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ] - -##################################################################### -# adding an entry -##################################################################### ->>> xm['joel'] = 'apple' ->>> print_xmap(xm) -[ (joel, apple) (kim, kiwi) (mariel, grape) (tenji, orange) (tutit, banana) ] - -##################################################################### -# Indexing -##################################################################### ->>> len(xm) -5 ->>> xm['joel'] -apple ->>> xm['tenji'] -orange ->>> xm['mariel'] -grape ->>> xm['tutit'] -banana ->>> xm['kim'] -kiwi - -##################################################################### -# Calling a mutating function of a container element -##################################################################### ->>> xm['joel'].reset() ->>> xm['joel'] -reset - -##################################################################### -# Copying a container element -##################################################################### ->>> x = X(xm['mariel']) ->>> x -grape ->>> x.foo() ->>> x -foo ->>> xm['mariel'] # should not be changed to 'foo' -grape - -##################################################################### -# Referencing a container element -##################################################################### ->>> x = xm['mariel'] ->>> x -grape ->>> x.foo() ->>> x -foo ->>> xm['mariel'] # should be changed to 'foo' -foo - ->>> xm['mariel'] = 'grape' # take it back ->>> xm['joel'] = 'apple' # take it back - -##################################################################### -# Contains -##################################################################### ->>> assert 'joel' in xm ->>> assert 'mariel' in xm ->>> assert 'tenji' in xm ->>> assert 'tutit' in xm ->>> assert 'kim' in xm ->>> assert not 'X' in xm ->>> assert not 12345 in xm - -##################################################################### -# Some references to the container elements -##################################################################### - ->>> z0 = xm['joel'] ->>> z1 = xm['mariel'] ->>> z2 = xm['tenji'] ->>> z3 = xm['tutit'] ->>> z4 = xm['kim'] - ->>> z0 # proxy -apple ->>> z1 # proxy -grape ->>> z2 # proxy -orange ->>> z3 # proxy -banana ->>> z4 # proxy -kiwi - -##################################################################### -# Delete some container element -##################################################################### - ->>> del xm['tenji'] ->>> print_xmap(xm) -[ (joel, apple) (kim, kiwi) (mariel, grape) (tutit, banana) ] - ->>> del xm['tutit'] ->>> print_xmap(xm) -[ (joel, apple) (kim, kiwi) (mariel, grape) ] - -##################################################################### -# Show that the references are still valid -##################################################################### ->>> z0 # proxy -apple ->>> z1 # proxy -grape ->>> z2 # proxy detached -orange ->>> z3 # proxy detached -banana ->>> z4 # proxy -kiwi - -##################################################################### -# Show that iteration allows mutable access to the elements -##################################################################### ->>> for x in xm: -... x.data().reset() ->>> print_xmap(xm) -[ (joel, reset) (kim, reset) (mariel, reset) ] - -##################################################################### -# END.... -##################################################################### - -''' - - -def run(args = None): - import sys - import doctest - - if args is not None: - sys.argxm = args - return doctest.testmod(sys.modules.get(__name__)) - -if __name__ == '__main__': - print 'running...' - import sys - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) - - - - - 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 0c0164a2..00000000 --- a/test/multi_arg_constructor.py +++ /dev/null @@ -1,18 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 e10d4582..00000000 --- a/test/nested.py +++ /dev/null @@ -1,37 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/newtest.py b/test/newtest.py deleted file mode 100644 index 29ff271b..00000000 --- a/test/newtest.py +++ /dev/null @@ -1,201 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 c81c8f82..00000000 --- a/test/numpy.py +++ /dev/null @@ -1,177 +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 - status = _run() - if (status == 0): print "Done." - sys.exit(status) 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 73d72329..00000000 --- a/test/object.py +++ /dev/null @@ -1,128 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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/opaque.cpp b/test/opaque.cpp deleted file mode 100644 index cb92e9cd..00000000 --- a/test/opaque.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright David Abrahams and Gottfried Ganssauge 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 - -typedef struct opaque_ *opaque; -typedef struct opaque2_ *opaque2; - -opaque the_op = ((opaque) 0x47110815); -opaque2 the_op2 = ((opaque2) 0x08154711); - -opaque get() { return the_op; } - -void use(opaque op) -{ - if (op != the_op) - throw std::runtime_error (std::string ("failed")); -} - -int useany(opaque op) -{ - return op ? 1 : 0; -} - -opaque getnull() -{ - return 0; -} - -void failuse (opaque op) -{ - if (op == the_op) - throw std::runtime_error (std::string ("success")); -} - -opaque2 get2 () { return the_op2; } - -void use2 (opaque2 op) -{ - if (op != the_op2) - throw std::runtime_error (std::string ("failed")); -} - -void failuse2 (opaque2 op) -{ - if (op == the_op2) - throw std::runtime_error (std::string ("success")); -} - -BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) -BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque2_) - -namespace bpl = boost::python; - -BOOST_PYTHON_MODULE(opaque_ext) -{ - bpl::def ( - "get", &::get, bpl::return_value_policy()); - bpl::def ("use", &::use); - bpl::def ("useany", &::useany); - bpl::def ("getnull", &::getnull, bpl::return_value_policy()); - bpl::def ("failuse", &::failuse); - - bpl::def ( - "get2", - &::get2, - bpl::return_value_policy()); - bpl::def ("use2", &::use2); - bpl::def ("failuse2", &::failuse2); -} - -# include "module_tail.cpp" diff --git a/test/opaque.py b/test/opaque.py deleted file mode 100644 index 6d994bd7..00000000 --- a/test/opaque.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: iso-latin-1 -*- -# Copyright Gottfried Ganßauge 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. - -""" ->>> from opaque_ext import * - - - Check for correct conversion - ->>> use(get()) - - Check that None is converted to a NULL opaque pointer - ->>> useany(get()) -1 ->>> useany(None) -0 - - Check that we don't lose type information by converting NULL - opaque pointers to None - ->>> assert getnull() is None ->>> useany(getnull()) -0 - ->>> failuse(get()) -Traceback (most recent call last): - ... -RuntimeError: success - - Check that there is no conversion from integers ... - ->>> try: use(0) -... except TypeError: pass -... else: print 'expected a TypeError' - - ... and from strings to opaque objects - ->>> try: use("") -... except TypeError: pass -... else: print 'expected a TypeError' - - Now check the same for another opaque pointer type - ->>> use2(get2()) ->>> failuse2(get2()) -Traceback (most recent call last): - ... -RuntimeError: success ->>> try: use2(0) -... except TypeError: pass -... else: print 'expected a TypeError' ->>> try: use2("") -... except TypeError: pass -... else: print 'expected a TypeError' - - Check that opaque types are distinct - ->>> try: use(get2()) -... except TypeError: pass -... else: print 'expected a TypeError' ->>> try: use2(get()) -... except TypeError: pass -... else: print 'expected a TypeError' -""" -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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/operators.cpp b/test/operators.cpp deleted file mode 100755 index ca55315a..00000000 --- a/test/operators.cpp +++ /dev/null @@ -1,93 +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 - -// 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 7a0680cf..00000000 --- a/test/operators.py +++ /dev/null @@ -1,91 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 963d406b..00000000 --- a/test/pickle1.py +++ /dev/null @@ -1,33 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/pickle2.cpp b/test/pickle2.cpp deleted file mode 100644 index 363f5e83..00000000 --- a/test/pickle2.cpp +++ /dev/null @@ -1,97 +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 - -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 5afebe53..00000000 --- a/test/pickle2.py +++ /dev/null @@ -1,47 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/pickle3.cpp b/test/pickle3.cpp deleted file mode 100644 index e8112535..00000000 --- a/test/pickle3.cpp +++ /dev/null @@ -1,105 +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 - -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 a3510f06..00000000 --- a/test/pickle3.py +++ /dev/null @@ -1,42 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 48d269fb..00000000 --- a/test/polymorphism.cpp +++ /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. -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::python; - -struct Callback -{ - Callback(PyObject* o) : mSelf(o) {} - PyObject* mSelf; -}; - -struct P -{ - virtual ~P(){} - virtual std::string f() = 0; -}; - -struct PCallback : P, Callback -{ - PCallback (PyObject* self) : Callback(self) {} - - std::string f() - { - return call_method(mSelf, "f"); - } -}; - -struct Q : P -{ - std::string f() { return "Q::f()"; } -}; - -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()"; } -}; - -struct D : A -{ - virtual std::string f() { return "D::f()"; } - std::string g() { return "D::g()"; } -}; - -struct DCallback : D, Callback -{ - DCallback (PyObject* self) : Callback(self) {} - - std::string f() - { - return call_method(mSelf, "f"); - } - - std::string default_f() - { - return A::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; -} - -A* pass_a(A* x) { return x; } - -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) - ; - - class_,DCallback,boost::noncopyable>("D") - .def("f", &D::f, &DCallback::default_f) - .def("g", &D::g) - ; - - def("pass_a", &pass_a, return_internal_reference<>()); - - def("getCCppObj", getCCppObj, return_value_policy()); - - def("factory", factory, return_value_policy()); - - def("call_f", call_f); - - class_("P") - .def("f", pure_virtual(&P::f)) - ; - - class_ >("Q") - ; -} - -//#include "module_tail.cpp" diff --git a/test/polymorphism.py b/test/polymorphism.py deleted file mode 100644 index 6d518c99..00000000 --- a/test/polymorphism.py +++ /dev/null @@ -1,71 +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 test_return_py(self): - - class X(A): - def f(self): - return 'X.f' - - x = X() - - self.failUnlessEqual ('X.f', x.f()) - self.failUnlessEqual ('X.f', call_f(x)) - - def test_wrapper_downcast(self): - a = pass_a(D()) - self.failUnlessEqual('D::g()', a.g()) - - def test_pure_virtual(self): - p = P() - self.assertRaises(RuntimeError, p.f) - - q = Q() - self.failUnlessEqual ('Q::f()', q.f()) - - class R(P): - def f(self): - return 'R.f' - - r = R() - self.failUnlessEqual ('R.f', r.f()) - - -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/properties.cpp b/test/properties.cpp deleted file mode 100755 index fdfa43a5..00000000 --- a/test/properties.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include - -using namespace boost::python; - -struct X -{ - X( int value ) : m_value( value ) - { ++s_count; } - - X( const X &other ) : m_value( other.m_value ) - { ++s_count; } - - ~X() - { --s_count; } - - int get_value() const - { return m_value; } - - void set_value(int new_value) - { m_value = new_value; } - - static int get_instance_count() - { return s_count; } - - int m_value; - - static int s_count; -}; - -int X::s_count = 0; - -int get_X_instance_count() -{ return X::get_instance_count(); } - - - -BOOST_PYTHON_MODULE(properties_ext) -{ - typedef return_value_policy return_by_value_t; - typedef return_internal_reference<> return_by_internal_reference_t; - class_("X", init() ) - //defining read only property - .add_property( "value_r", &X::get_value ) - //defining read \ write property - .add_property( "value_rw", &X::get_value, &X::set_value ) - //defining read \ write property using make_getter and make_setter - .add_property( "value_direct", - make_getter( &X::m_value, return_by_value_t() ), - make_setter( &X::m_value, return_by_internal_reference_t() ) ) - //defining read only property for static member - .add_static_property( "instance_count", &X::get_instance_count ) - //defining read \ write property for static member using make_getter and make_setter - .add_static_property( "instance_count_direct", - make_getter( &X::s_count, return_by_value_t() ), - make_setter( &X::s_count, return_by_internal_reference_t() ) ) - //defining class property using a global function - .add_static_property( "instance_count_injected", &get_X_instance_count ); -} - -#include "module_tail.cpp" diff --git a/test/properties.py b/test/properties.py deleted file mode 100644 index ffceb4d6..00000000 --- a/test/properties.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -This is test module for properies. - ->>> X = properties.X - ->>> x1 = X(1) - -value read only ->>> x1.value_r -1 - -value read - write ->>> x1.value_rw -1 - -value direct access ->>> x1.value_direct -1 - -class instance count read - only ->>> X.instance_count -1 - -class instance count direct ->>> X.instance_count_direct -1 - -class instance count injected ->>> X.instance_count_injected -1 - -class instance count from object ->>> x1.instance_count -1 - -class instance count from object ->>> x1.instance_count_direct -1 - -class instance count from object: ->>> x1.instance_count_injected -1 - -as expected you can't assign new value to read only property ->>> x1.value_r = 2 -Traceback (most recent call last): - File "properties.py", line 49, in ? - x1.value_r = 2 -AttributeError: can't set attribute - -setting value_rw to 2. value_direct: ->>> x1.value_rw = 2 ->>> x1.value_rw -2 - -setting value_direct to 3. value_direct: ->>> x1.value_direct = 3 ->>> x1.value_direct -3 - ->>> assert x1.value_r == 3 - ->>> x2 = X(2) - -after creating second intstance of X instances count is 2 ->>> x2.instance_count -2 - ->>> del x2 ->>> assert x1.instance_count == 1 -""" - -#import sys; sys.path.append(r'P:\Actimize4.0\smart_const\py_smart_const___Win32_Debug') -import properties_ext as properties - - -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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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/register_ptr.cpp b/test/register_ptr.cpp deleted file mode 100644 index f65599d9..00000000 --- a/test/register_ptr.cpp +++ /dev/null @@ -1,52 +0,0 @@ - -#include -#include - -using namespace boost; -using namespace python; - -struct A -{ - virtual int f() { return 0; } -}; - -shared_ptr New() { return shared_ptr( new A() ); } - -int Call( const shared_ptr & a ) -{ - return a->f(); -} - -int Fail( shared_ptr & a ) -{ - return a->f(); -} - -struct A_Wrapper: A -{ - A_Wrapper(PyObject* self_): self(self_) {} - A_Wrapper(PyObject* self_, const A& a): self(self_), A(a) {} - - int f() - { - return call_method(self, "f"); - } - - int default_f() - { - return A::f(); - } - - PyObject* self; -}; - -BOOST_PYTHON_MODULE(register_ptr) -{ - class_("A") - .def("f", &A::f, &A_Wrapper::default_f) - ; - register_ptr_to_python< shared_ptr >(); - def("New", &New); - def("Call", &Call); - def("Fail", &Fail); -} diff --git a/test/register_ptr_test.py b/test/register_ptr_test.py deleted file mode 100644 index f0472993..00000000 --- a/test/register_ptr_test.py +++ /dev/null @@ -1,22 +0,0 @@ -import unittest -from register_ptr import * - -class RegisterPtrTest(unittest.TestCase): - - def testIt(self): - - class B(A): - def f(self): - return 10 - - a = New() # this must work - b = B() - self.assertEqual(Call(a), 0) - self.assertEqual(Call(b), 10) - def fails(): - Fail(A()) - self.assertRaises(TypeError, fails) - self.assertEqual(Fail(a), 0) # ok, since a is held by shared_ptr - -if __name__ == '__main__': - unittest.main() 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/return_arg.cpp b/test/return_arg.cpp deleted file mode 100755 index 0412d511..00000000 --- a/test/return_arg.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright David Abrahams and Nikolay Mladenov 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 Widget -{ - Widget() - : sensitive_(true) - {} - - bool get_sensitive() const - { - return sensitive_; - } - - void set_sensitive(bool s) - { - this->sensitive_ = s; - } - - private: - bool sensitive_; -}; - -struct Label : Widget -{ - Label() {} - - std::string get_label() const - { - return label_; - } - - void set_label(const std::string &l) - { - label_ = l; - } - - private: - std::string label_; -}; - -void return_arg_f(boost::python::object) {} - -using namespace boost::python; -BOOST_PYTHON_MODULE(return_arg_ext) -{ - class_("Widget") - .def("sensitive", &Widget::get_sensitive) - .def("sensitive", &Widget::set_sensitive, return_self<>()) - ; - - class_ >("Label") - .def("label", &Label::get_label)//,return_arg<0>()) //error(s) - .def("label", &Label::set_label, return_self<>()) - ; - - def("return_arg", return_arg_f, return_arg<1>()); -} - -#include "module_tail.cpp" diff --git a/test/return_arg.py b/test/return_arg.py deleted file mode 100644 index 4cbc89f4..00000000 --- a/test/return_arg.py +++ /dev/null @@ -1,24 +0,0 @@ -''' ->>> from return_arg_ext import * ->>> l1=Label() ->>> assert l1 is l1.label("bar") ->>> assert l1 is l1.label("bar").sensitive(0) ->>> assert l1.label("foo").sensitive(0) is l1.sensitive(1).label("bar") ->>> assert return_arg is return_arg(return_arg) - -''' - -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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 93d57f11..00000000 --- a/test/select_holder.cpp +++ /dev/null @@ -1,86 +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 - -#define BOOST_INCLUDE_MAIN -#include - -struct BR {}; - -struct Base {}; -struct Derived : Base {}; - -namespace boost { namespace python -{ - // specialization - template <> - struct has_back_reference
- : mpl::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 2d0f0ec7..00000000 --- a/test/shared_ptr.cpp +++ /dev/null @@ -1,200 +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()); - } - - template - static void expose(C const& c) - { - def("look", &look); - def("store", &store); - def("modify", &modify); - def("identity", &identity); - def("null", &null); - - const_cast(c) - .def("look", &look) - .staticmethod("look") - .def("store", &store) - .staticmethod("store") - .def("modify", &modify) - .staticmethod("modify") - .def("look_store", &look_store) - .staticmethod("look_store") - .def("identity", &identity) - .staticmethod("identity") - .def("null", &null) - .staticmethod("null") - .def("get", &get) - .staticmethod("get") - .def("count", &T::count) - .staticmethod("count") - .def("release", &release_store) - .staticmethod("release") - ; - } - - static shared_ptr identity(shared_ptr x) { return x; } - static shared_ptr null(T const&) { return shared_ptr(); } - - - 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) {} -}; - -struct YYY : Y -{ - YYY(int n) : Y(n) {} -}; - -shared_ptr factory(int n) -{ - return shared_ptr(n < 42 ? new Y(n) : new YY(n)); -} - -// regressions from Nicodemus - struct A - { - virtual int f() = 0; - static int call_f(shared_ptr& a) { return a->f(); } - }; - - struct B: A - { - int f() { return 1; } - }; - - boost::shared_ptr New(bool make) - { - return boost::shared_ptr( make ? new B() : 0 ); - } - - struct A_Wrapper: A - { - A_Wrapper(PyObject* self_): - A(), self(self_) {} - - int f() { - return call_method< int >(self, "f"); - } - - PyObject* self; - }; - -// ------ - -BOOST_PYTHON_MODULE(shared_ptr_ext) -{ - class_, boost::noncopyable>("A") - .def("call_f", &A::call_f) - .staticmethod("call_f") - ; - - // This is the ugliness required to register a to-python converter - // for shared_ptr. - objects::class_value_wrapper< - shared_ptr - , objects::make_ptr_instance,A> > - >(); - - def("New", &New); - - def("factory", factory); - - functions::expose( - class_("X", init()) - .def("value", &X::value) - ); - - functions::expose( - class_ >("Y", init()) - .def("value", &Y::value) - ); - - class_, boost::noncopyable>("YY", init()) - ; - - class_, bases >("YYY", init()) - ; - - functions::expose( - class_("Z", init()) - .def("value", &Z::value) - .def("v", &Z::v, &ZWrap::default_v) - ); -} - -#include "module_tail.cpp" - diff --git a/test/shared_ptr.py b/test/shared_ptr.py deleted file mode 100644 index cabb134a..00000000 --- a/test/shared_ptr.py +++ /dev/null @@ -1,127 +0,0 @@ -''' ->>> from shared_ptr_ext import * - - Test that shared_ptr can be converted to shared_ptr - ->>> Y.store(YYY(42)) - ->>> x = X(17) ->>> null_x = null(x) ->>> null_x # should be None ->>> identity(null_x) # should also be None - ->>> a = New(1) ->>> A.call_f(a) -1 ->>> New(0) - ->>> 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 ->>> Z.get().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' - ->>> Z.get() # should be None ->>> store(z) ->>> assert Z.get() is z # show that deleter introspection works ->>> del z ->>> Z.get().value() -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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 e9e9e697..00000000 --- a/test/staticmethod.py +++ /dev/null @@ -1,54 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/str.cpp b/test/str.cpp deleted file mode 100644 index 9e675208..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(7L)); - - 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 bf7a86ed..00000000 --- a/test/str.py +++ /dev/null @@ -1,54 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/test/string_literal.cpp b/test/string_literal.cpp deleted file mode 100644 index e64f40f5..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 6301a6d0..00000000 --- a/test/test_builtin_converters.cpp +++ /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. -#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 1304ea32..00000000 --- a/test/test_builtin_converters.py +++ /dev/null @@ -1,240 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 dfd8b4b0..00000000 --- a/test/test_pointer_adoption.py +++ /dev/null @@ -1,90 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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 acf5a55f..00000000 --- a/test/tuple.py +++ /dev/null @@ -1,34 +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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) 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/vector_indexing_suite.cpp b/test/vector_indexing_suite.cpp deleted file mode 100644 index 07fc5e91..00000000 --- a/test/vector_indexing_suite.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include - -using namespace boost::python; - -struct X // a container element -{ - std::string s; - X():s("default") {} - X(std::string s):s(s) {} - std::string repr() const { return s; } - void reset() { s = "reset"; } - void foo() { s = "foo"; } - bool operator==(X const& x) const { return s == x.s; } - bool operator!=(X const& x) const { return s != x.s; } -}; - -std::string x_value(X const& x) -{ - return "gotya " + x.s; -} - -BOOST_PYTHON_MODULE(vector_indexing_suite_ext) -{ - class_("X") - .def(init<>()) - .def(init()) - .def(init()) - .def("__repr__", &X::repr) - .def("reset", &X::reset) - .def("foo", &X::foo) - ; - - def("x_value", x_value); - implicitly_convertible(); - - class_ >("XVec") - .def(vector_indexing_suite >()) - ; - - // Compile check only... - class_ >("FloatVec") - .def(vector_indexing_suite >()) - ; - - // Compile check only... - class_ >("BoolVec") - .def(vector_indexing_suite >()) - ; -} - diff --git a/test/vector_indexing_suite.py b/test/vector_indexing_suite.py deleted file mode 100644 index 42dbfdba..00000000 --- a/test/vector_indexing_suite.py +++ /dev/null @@ -1,346 +0,0 @@ -''' - -##################################################################### -# Check an object that we will use as container element -##################################################################### - ->>> from vector_indexing_suite_ext import * ->>> x = X('hi') ->>> x -hi ->>> x.reset() # a member function that modifies X ->>> x -reset ->>> x.foo() # another member function that modifies X ->>> x -foo - -# test that a string is implicitly convertible -# to an X ->>> x_value('bochi bochi') -'gotya bochi bochi' - -##################################################################### -# Iteration -##################################################################### ->>> def print_xvec(xvec): -... s = '[ ' -... for x in xvec: -... s += repr(x) -... s += ' ' -... s += ']' -... print s - -##################################################################### -# Replace all the contents using slice syntax -##################################################################### - ->>> v = XVec() ->>> v[:] = [X('a'),X('b'),X('c'),X('d'),X('e')] ->>> print_xvec(v) -[ a b c d e ] - -##################################################################### -# Indexing -##################################################################### ->>> len(v) -5 ->>> v[0] -a ->>> v[1] -b ->>> v[2] -c ->>> v[3] -d ->>> v[4] -e ->>> v[-1] -e ->>> v[-2] -d ->>> v[-3] -c ->>> v[-4] -b ->>> v[-5] -a - -##################################################################### -# Deleting an element -##################################################################### - ->>> del v[0] ->>> v[0] = 'yaba' # must do implicit conversion ->>> print_xvec(v) -[ yaba c d e ] - -##################################################################### -# Calling a mutating function of a container element -##################################################################### ->>> v[3].reset() ->>> v[3] -reset - -##################################################################### -# Copying a container element -##################################################################### ->>> x = X(v[3]) ->>> x -reset ->>> x.foo() ->>> x -foo ->>> v[3] # should not be changed to 'foo' -reset - -##################################################################### -# Referencing a container element -##################################################################### ->>> x = v[3] ->>> x -reset ->>> x.foo() ->>> x -foo ->>> v[3] # should be changed to 'foo' -foo - -##################################################################### -# Slice -##################################################################### - ->>> sl = v[0:2] ->>> print_xvec(sl) -[ yaba c ] ->>> sl[0].reset() ->>> sl[0] -reset - -##################################################################### -# Reset the container again -##################################################################### ->>> v[:] = ['a','b','c','d','e'] # perform implicit conversion to X ->>> print_xvec(v) -[ a b c d e ] - -##################################################################### -# Slice: replace [1:3] with an element -##################################################################### ->>> v[1:3] = X('z') ->>> print_xvec(v) -[ a z d e ] - -##################################################################### -# Slice: replace [0:2] with a list -##################################################################### ->>> v[0:2] = ['1','2','3','4'] # perform implicit conversion to X ->>> print_xvec(v) -[ 1 2 3 4 d e ] - -##################################################################### -# Slice: delete [3:4] -##################################################################### ->>> del v[3:4] ->>> print_xvec(v) -[ 1 2 3 d e ] - -##################################################################### -# Slice: set [3:] to a list -##################################################################### ->>> v[3:] = [X('trailing'), X('stuff')] # a list ->>> print_xvec(v) -[ 1 2 3 trailing stuff ] - -##################################################################### -# Slice: delete [:3] -##################################################################### ->>> del v[:3] ->>> print_xvec(v) -[ trailing stuff ] - -##################################################################### -# Slice: insert a tuple to [0:0] -##################################################################### ->>> v[0:0] = ('leading','stuff') # can also be a tuple ->>> print_xvec(v) -[ leading stuff trailing stuff ] - -##################################################################### -# Reset the container again -##################################################################### ->>> v[:] = ['a','b','c','d','e'] - -##################################################################### -# Some references to the container elements -##################################################################### ->>> z0 = v[0] ->>> z1 = v[1] ->>> z2 = v[2] ->>> z3 = v[3] ->>> z4 = v[4] - ->>> z0 # proxy -a ->>> z1 # proxy -b ->>> z2 # proxy -c ->>> z3 # proxy -d ->>> z4 # proxy -e - -##################################################################### -# Delete a container element -##################################################################### - ->>> del v[2] ->>> print_xvec(v) -[ a b d e ] - -##################################################################### -# Show that the references are still valid -##################################################################### ->>> z0 # proxy -a ->>> z1 # proxy -b ->>> z2 # proxy detached -c ->>> z3 # proxy index adjusted -d ->>> z4 # proxy index adjusted -e - -##################################################################### -# Delete all container elements -##################################################################### ->>> del v[:] ->>> print_xvec(v) -[ ] - -##################################################################### -# Show that the references are still valid -##################################################################### ->>> z0 # proxy detached -a ->>> z1 # proxy detached -b ->>> z2 # proxy detached -c ->>> z3 # proxy detached -d ->>> z4 # proxy detached -e - -##################################################################### -# Reset the container again -##################################################################### ->>> v[:] = ['a','b','c','d','e'] - -##################################################################### -# renew the references to the container elements -##################################################################### ->>> z0 = v[0] ->>> z1 = v[1] ->>> z2 = v[2] ->>> z3 = v[3] ->>> z4 = v[4] - ->>> z0 # proxy -a ->>> z1 # proxy -b ->>> z2 # proxy -c ->>> z3 # proxy -d ->>> z4 # proxy -e - -##################################################################### -# Set [2:4] to a list such that there will be more elements -##################################################################### ->>> v[2:4] = ['x','y','v'] ->>> print_xvec(v) -[ a b x y v e ] - -##################################################################### -# Show that the references are still valid -##################################################################### ->>> z0 # proxy -a ->>> z1 # proxy -b ->>> z2 # proxy detached -c ->>> z3 # proxy detached -d ->>> z4 # proxy index adjusted -e - -##################################################################### -# Contains -##################################################################### ->>> v[:] = ['a','b','c','d','e'] # reset again - ->>> assert 'a' in v ->>> assert 'b' in v ->>> assert 'c' in v ->>> assert 'd' in v ->>> assert 'e' in v ->>> assert not 'X' in v ->>> assert not 12345 in v - -##################################################################### -# Show that iteration allows mutable access to the elements -##################################################################### ->>> v[:] = ['a','b','c','d','e'] # reset again ->>> for x in v: -... x.reset() ->>> print_xvec(v) -[ reset reset reset reset reset ] - -##################################################################### -# append -##################################################################### ->>> v[:] = ['a','b','c','d','e'] # reset again ->>> v.append('f') ->>> print_xvec(v) -[ a b c d e f ] - -##################################################################### -# extend -##################################################################### ->>> v[:] = ['a','b','c','d','e'] # reset again ->>> v.extend(['f','g','h','i','j']) ->>> print_xvec(v) -[ a b c d e f g h i j ] - -##################################################################### -# END.... -##################################################################### - -''' - - -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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) - - - - - diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp deleted file mode 100644 index 3e26708d..00000000 --- a/test/virtual_functions.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. -#include -#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; - abstract& call_g(Y const& y) { return g(y); } - virtual abstract& g(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)); - } - - abstract& g(Y const& y) - { - return call_method(self, "g", 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("call_g", &abstract::call_g, return_internal_reference<>()) - .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 268af45c..00000000 --- a/test/virtual_functions.py +++ /dev/null @@ -1,107 +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 -... def g(self, y): -... return self - ->>> class A2(abstract): -... pass - - ->>> y1 = Y(16) ->>> y2 = Y(17) - - - -# -# Test abstract with f,g overridden -# ->>> a1 = A1(42) ->>> a1.value() -42 - -# Call f,g indirectly from C++ ->>> a1.call_f(y1) -32 ->>> assert type(a1.call_g(y1)) is abstract - -# 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 - status = run()[0] - if (status == 0): print "Done." - sys.exit(status) diff --git a/todo.html b/todo.html deleted file mode 100755 index 5ada8b25..00000000 --- a/todo.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - -Boost.Python TODO list Boost - - - - - - - - diff --git a/todo.txt b/todo.txt deleted file mode 100644 index 8b7456e7..00000000 --- a/todo.txt +++ /dev/null @@ -1,154 +0,0 @@ -.. -*- mode: rst -*- - -==================================== - Boost.Python_ TODO list |(logo)|__ -==================================== - -.. |(logo)| image:: ../../c++boost.gif - :alt: Boost - -__ ../../index.htm - -.. _`Boost.Python`: index.html - -:copyright: Copyright David Abrahams 2003. See accompanying - license_ for terms of use. - -.. contents:: Outline - -.. _license: ../../LICENSE - -Class Support -============= - -Base Class for Virtual Function Callback Wrappers -------------------------------------------------- - -* http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1456023 - (bottom of message) - -* http://mail.python.org/pipermail/c++-sig/2003-August/005297.html - (search for ``VirtualDispatcher``) describes how callback classes - can swap ownership relationship with their Python wrappers. - - - -Functions -========= - -Wrapping Function Objects --------------------------- - - It should be possible to wrap classes which support ``operator()`` - as Python methods. - - http://mail.python.org/pipermail/c++-sig/2003-August/005184.html - - -"Best Match" Overload Resolution --------------------------------- - - Overload resolution currently depends on the order in which ``def`` - calls are made (preferring later overloads). This should be - changed so that the best-matching overload is always selected. - This may await Langbinding_ integration, since the technology is - already in Luabind_. - - .. _Luabind: http://luabind.sf.net - -Injected Constructors ---------------------- - - Enabling the addition of new constructor functors or factory - constructors which aren't in the underlying C++ interface. - Interface still to be decided. Here is a discussion of it: - - http://aspn.activestate.com/ASPN/Mail/Message/1744280 - - However, I'm pretty sure we can't use the init<>(f) interface here - because it will have to instantiate the code for the wrapped - class' default constructor, which may not exist. - - - - -Type Converters -=============== - -Lvalue conversions from non-const ``PyTypeObject*``\ s ------------------------------------------------------- - - http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1662717 - -Converter Scoping ------------------ - - http://article.gmane.org/gmane.comp.python.c++/2044 - - If this gets done at all, it is going to happen in conjunction - with `Luabind integration`__. - - __ Langbinding_ - -``FILE* conversions`` ---------------------- - - http://aspn.activestate.com/ASPN/Mail/Message/1411366 - -Post-Call Actions ------------------ - - From-Python converters should be passed an extra reference to a - chain of post-call actions in the Policies object, where they can - register an additional action. See the end of - http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1755435 - -``PyUnicode`` Support ---------------------- - - Review and possibly incorporate changes from `Lijun Qin`_ at - http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1771145 - - .. _`Lijun Qin`: mailto:qinlj-at-solidshare.com - -Documentation -============= - -Builtin Converters ------------------- - - Builtin correspondences between builtiin Python types and C++ - types need to be documented - -Internals ---------- - - The structure of the framework needs to get documented; `Brett - Calcott`_ has promised to turn `this document`__ into something fit - for users - - __ doc/internals.html - - .. _`Brett Calcott`: mailto:brett.calcott-at-paradise.net.nz - - -Large Scale -=========== - -Langbinding ------------ - - This project to generalizes Boost.Python to work for other - languages, initially Lua. See discussions at - http://lists.sourceforge.net/lists/listinfo/boost-langbinding - -Refactoring and Reorganization ------------------------------- - - http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1673338 - -NumArray Support Enhancements ------------------------------ - - Consider integrating the enhancements described in - http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1757092