summaryrefslogtreecommitdiff
path: root/libs/python
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-06-25 22:59:01 +0000
committer <>2013-09-27 11:49:28 +0000
commit8c4528713d907ee2cfd3bfcbbad272c749867f84 (patch)
treec09e2ce80f47b90c85cc720f5139089ad9c8cfff /libs/python
downloadboost-tarball-baserock/morph.tar.gz
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_54_0.tar.bz2.boost_1_54_0baserock/morph
Diffstat (limited to 'libs/python')
-rw-r--r--libs/python/build/Jamfile.v2151
-rw-r--r--libs/python/build/python_v1.zipbin0 -> 236665 bytes
-rw-r--r--libs/python/class.cpp28
-rw-r--r--libs/python/doc/Jamfile23
-rw-r--r--libs/python/doc/PyConDC_2003/bpl.html22
-rw-r--r--libs/python/doc/PyConDC_2003/bpl.pdfbin0 -> 7316 bytes
-rw-r--r--libs/python/doc/PyConDC_2003/bpl.txt5
-rw-r--r--libs/python/doc/PyConDC_2003/bpl_mods.txt911
-rw-r--r--libs/python/doc/PyConDC_2003/default.css188
-rw-r--r--libs/python/doc/PyConDC_2003/python_cpp_mix.jpgbin0 -> 22831 bytes
-rw-r--r--libs/python/doc/PyConDC_2003/python_cpp_mix.pngbin0 -> 6293 bytes
-rw-r--r--libs/python/doc/boost.css63
-rw-r--r--libs/python/doc/building.html636
-rw-r--r--libs/python/doc/building.rst680
-rw-r--r--libs/python/doc/index.html184
-rw-r--r--libs/python/doc/internals.html186
-rw-r--r--libs/python/doc/internals.rst182
-rw-r--r--libs/python/doc/news.html371
-rw-r--r--libs/python/doc/polymorphism.txt222
-rw-r--r--libs/python/doc/projects.html472
-rw-r--r--libs/python/doc/support.html74
-rw-r--r--libs/python/doc/tutorial/doc/Jamfile.v218
-rw-r--r--libs/python/doc/tutorial/doc/html/images/alert.pngbin0 -> 603 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/home.pngbin0 -> 358 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/jam.pngbin0 -> 3884 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/next.pngbin0 -> 336 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/note.pngbin0 -> 658 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/prev.pngbin0 -> 334 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/python.pngbin0 -> 14699 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/smiley.pngbin0 -> 867 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/tip.pngbin0 -> 640 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/images/up.pngbin0 -> 370 bytes
-rw-r--r--libs/python/doc/tutorial/doc/html/index.html142
-rw-r--r--libs/python/doc/tutorial/doc/html/python/embedding.html269
-rw-r--r--libs/python/doc/tutorial/doc/html/python/exception.html63
-rw-r--r--libs/python/doc/tutorial/doc/html/python/exposing.html591
-rw-r--r--libs/python/doc/tutorial/doc/html/python/functions.html586
-rw-r--r--libs/python/doc/tutorial/doc/html/python/hello.html195
-rw-r--r--libs/python/doc/tutorial/doc/html/python/iterators.html187
-rw-r--r--libs/python/doc/tutorial/doc/html/python/object.html360
-rw-r--r--libs/python/doc/tutorial/doc/html/python/techniques.html440
-rw-r--r--libs/python/doc/tutorial/doc/tutorial.qbk1985
-rw-r--r--libs/python/doc/tutorial/index.html18
-rw-r--r--libs/python/doc/v2/Apr2002.html166
-rw-r--r--libs/python/doc/v2/CallPolicies.html165
-rw-r--r--libs/python/doc/v2/Dereferenceable.html74
-rw-r--r--libs/python/doc/v2/Extractor.html96
-rw-r--r--libs/python/doc/v2/HolderGenerator.html74
-rw-r--r--libs/python/doc/v2/Jun2002.html229
-rw-r--r--libs/python/doc/v2/Mar2002.html237
-rw-r--r--libs/python/doc/v2/May2002.html311
-rw-r--r--libs/python/doc/v2/ObjectWrapper.html153
-rw-r--r--libs/python/doc/v2/ResultConverter.html124
-rw-r--r--libs/python/doc/v2/acknowledgments.html135
-rw-r--r--libs/python/doc/v2/args.html199
-rw-r--r--libs/python/doc/v2/call.html85
-rw-r--r--libs/python/doc/v2/call_method.html161
-rw-r--r--libs/python/doc/v2/callbacks.html254
-rw-r--r--libs/python/doc/v2/callbacks.txt92
-rw-r--r--libs/python/doc/v2/class.html790
-rw-r--r--libs/python/doc/v2/configuration.html217
-rw-r--r--libs/python/doc/v2/copy_const_reference.html149
-rw-r--r--libs/python/doc/v2/copy_non_const_reference.html149
-rw-r--r--libs/python/doc/v2/data_members.html229
-rw-r--r--libs/python/doc/v2/def.html191
-rw-r--r--libs/python/doc/v2/def_visitor.html137
-rw-r--r--libs/python/doc/v2/default_call_policies.html173
-rw-r--r--libs/python/doc/v2/definitions.html102
-rw-r--r--libs/python/doc/v2/dict.html152
-rw-r--r--libs/python/doc/v2/docstring_options.html386
-rw-r--r--libs/python/doc/v2/enum.html234
-rw-r--r--libs/python/doc/v2/errors.html289
-rw-r--r--libs/python/doc/v2/exception_translator.html150
-rw-r--r--libs/python/doc/v2/exec.html163
-rw-r--r--libs/python/doc/v2/extract.html232
-rw-r--r--libs/python/doc/v2/faq.html861
-rw-r--r--libs/python/doc/v2/feb2002.html367
-rw-r--r--libs/python/doc/v2/function_doc_signature.html216
-rw-r--r--libs/python/doc/v2/handle.html336
-rw-r--r--libs/python/doc/v2/has_back_reference.html225
-rw-r--r--libs/python/doc/v2/implicit.html163
-rw-r--r--libs/python/doc/v2/import.html90
-rw-r--r--libs/python/doc/v2/index.html20
-rw-r--r--libs/python/doc/v2/indexing.html695
-rw-r--r--libs/python/doc/v2/init.html251
-rw-r--r--libs/python/doc/v2/instance_holder.html219
-rw-r--r--libs/python/doc/v2/iterator.html398
-rw-r--r--libs/python/doc/v2/list.html142
-rw-r--r--libs/python/doc/v2/long.html119
-rw-r--r--libs/python/doc/v2/lvalue_from_pytype.html301
-rw-r--r--libs/python/doc/v2/make_function.html207
-rw-r--r--libs/python/doc/v2/manage_new_object.html145
-rw-r--r--libs/python/doc/v2/module.html110
-rw-r--r--libs/python/doc/v2/numeric.html276
-rw-r--r--libs/python/doc/v2/object.html1121
-rw-r--r--libs/python/doc/v2/opaque.html138
-rw-r--r--libs/python/doc/v2/operators.html921
-rw-r--r--libs/python/doc/v2/overloads.html229
-rw-r--r--libs/python/doc/v2/pickle.html280
-rw-r--r--libs/python/doc/v2/platforms.html135
-rw-r--r--libs/python/doc/v2/pointee.html119
-rw-r--r--libs/python/doc/v2/progress_reports.html47
-rw-r--r--libs/python/doc/v2/ptr.html265
-rw-r--r--libs/python/doc/v2/python.html110
-rw-r--r--libs/python/doc/v2/pytype_function.html370
-rw-r--r--libs/python/doc/v2/raw_function.html118
-rw-r--r--libs/python/doc/v2/reference.html1192
-rw-r--r--libs/python/doc/v2/reference_existing_object.html180
-rw-r--r--libs/python/doc/v2/register_ptr_to_python.html162
-rw-r--r--libs/python/doc/v2/return_arg.html224
-rw-r--r--libs/python/doc/v2/return_by_value.html149
-rw-r--r--libs/python/doc/v2/return_internal_reference.html230
-rw-r--r--libs/python/doc/v2/return_opaque_pointer.html192
-rw-r--r--libs/python/doc/v2/return_value_policy.html167
-rw-r--r--libs/python/doc/v2/scope.html173
-rw-r--r--libs/python/doc/v2/slice.html246
-rw-r--r--libs/python/doc/v2/ssize_t.html96
-rw-r--r--libs/python/doc/v2/stl_iterator.html273
-rw-r--r--libs/python/doc/v2/str.html237
-rw-r--r--libs/python/doc/v2/to_python_converter.html227
-rw-r--r--libs/python/doc/v2/to_python_indirect.html196
-rw-r--r--libs/python/doc/v2/to_python_value.html103
-rw-r--r--libs/python/doc/v2/tuple.html139
-rw-r--r--libs/python/doc/v2/type_id.html224
-rw-r--r--libs/python/doc/v2/with_custodian_and_ward.html370
-rw-r--r--libs/python/doc/v2/wrapper.html238
-rw-r--r--libs/python/example/Jamroot40
-rw-r--r--libs/python/example/README16
-rw-r--r--libs/python/example/boost-build.jam7
-rw-r--r--libs/python/example/getting_started1.cpp25
-rw-r--r--libs/python/example/getting_started2.cpp41
-rw-r--r--libs/python/example/project.zipbin0 -> 1469 bytes
-rw-r--r--libs/python/example/quickstart/Jamroot43
-rw-r--r--libs/python/example/quickstart/boost-build.jam7
-rw-r--r--libs/python/example/quickstart/embedding.cpp154
-rw-r--r--libs/python/example/quickstart/extending.cpp41
-rw-r--r--libs/python/example/quickstart/script.py6
-rw-r--r--libs/python/example/quickstart/test_extending.py36
-rw-r--r--libs/python/example/std_pair.cpp49
-rw-r--r--libs/python/example/test_getting_started1.py21
-rw-r--r--libs/python/example/test_getting_started2.py34
-rw-r--r--libs/python/example/test_std_pair.py6
-rw-r--r--libs/python/example/tutorial/Jamroot48
-rw-r--r--libs/python/example/tutorial/hello.cpp20
-rwxr-xr-xlibs/python/example/tutorial/hello.py7
-rw-r--r--libs/python/index.html12
-rw-r--r--libs/python/pyste/NEWS212
-rw-r--r--libs/python/pyste/README35
-rw-r--r--libs/python/pyste/TODO18
-rw-r--r--libs/python/pyste/dist/create_build.py55
-rw-r--r--libs/python/pyste/dist/setup.py10
-rw-r--r--libs/python/pyste/doc/adding_new_methods.html79
-rw-r--r--libs/python/pyste/doc/exporting_an_entire_header.html85
-rw-r--r--libs/python/pyste/doc/global_variables.html49
-rw-r--r--libs/python/pyste/doc/inserting_code.html72
-rw-r--r--libs/python/pyste/doc/introduction.html73
-rw-r--r--libs/python/pyste/doc/policies.html90
-rw-r--r--libs/python/pyste/doc/pyste.txt664
-rw-r--r--libs/python/pyste/doc/renaming_and_excluding.html87
-rw-r--r--libs/python/pyste/doc/running_pyste.html200
-rw-r--r--libs/python/pyste/doc/smart_pointers.html84
-rw-r--r--libs/python/pyste/doc/templates.html102
-rw-r--r--libs/python/pyste/doc/the_interface_files.html102
-rw-r--r--libs/python/pyste/doc/theme/alert.gifbin0 -> 577 bytes
-rw-r--r--libs/python/pyste/doc/theme/arrow.gifbin0 -> 70 bytes
-rw-r--r--libs/python/pyste/doc/theme/bkd.gifbin0 -> 1317 bytes
-rw-r--r--libs/python/pyste/doc/theme/bkd2.gifbin0 -> 2543 bytes
-rw-r--r--libs/python/pyste/doc/theme/bulb.gifbin0 -> 944 bytes
-rw-r--r--libs/python/pyste/doc/theme/bullet.gifbin0 -> 152 bytes
-rw-r--r--libs/python/pyste/doc/theme/l_arr.gifbin0 -> 147 bytes
-rw-r--r--libs/python/pyste/doc/theme/l_arr_disabled.gifbin0 -> 91 bytes
-rw-r--r--libs/python/pyste/doc/theme/note.gifbin0 -> 151 bytes
-rw-r--r--libs/python/pyste/doc/theme/r_arr.gifbin0 -> 147 bytes
-rw-r--r--libs/python/pyste/doc/theme/r_arr_disabled.gifbin0 -> 91 bytes
-rw-r--r--libs/python/pyste/doc/theme/smiley.gifbin0 -> 879 bytes
-rw-r--r--libs/python/pyste/doc/theme/style.css178
-rw-r--r--libs/python/pyste/doc/theme/u_arr.gifbin0 -> 170 bytes
-rw-r--r--libs/python/pyste/doc/wrappers.html124
-rw-r--r--libs/python/pyste/index.html90
-rw-r--r--libs/python/pyste/install/pyste.py8
-rw-r--r--libs/python/pyste/install/setup.py20
-rw-r--r--libs/python/pyste/src/Pyste/ClassExporter.py918
-rw-r--r--libs/python/pyste/src/Pyste/CodeExporter.py26
-rw-r--r--libs/python/pyste/src/Pyste/CppParser.py247
-rw-r--r--libs/python/pyste/src/Pyste/EnumExporter.py58
-rw-r--r--libs/python/pyste/src/Pyste/Exporter.py94
-rw-r--r--libs/python/pyste/src/Pyste/FunctionExporter.py92
-rw-r--r--libs/python/pyste/src/Pyste/GCCXMLParser.py478
-rw-r--r--libs/python/pyste/src/Pyste/HeaderExporter.py81
-rw-r--r--libs/python/pyste/src/Pyste/MultipleCodeUnit.py135
-rw-r--r--libs/python/pyste/src/Pyste/SingleCodeUnit.py121
-rw-r--r--libs/python/pyste/src/Pyste/SmartFile.py60
-rw-r--r--libs/python/pyste/src/Pyste/VarExporter.py40
-rw-r--r--libs/python/pyste/src/Pyste/__init__.py6
-rw-r--r--libs/python/pyste/src/Pyste/declarations.py653
-rw-r--r--libs/python/pyste/src/Pyste/exporters.py12
-rw-r--r--libs/python/pyste/src/Pyste/exporterutils.py87
-rw-r--r--libs/python/pyste/src/Pyste/infos.py259
-rw-r--r--libs/python/pyste/src/Pyste/policies.py95
-rw-r--r--libs/python/pyste/src/Pyste/pyste.py424
-rw-r--r--libs/python/pyste/src/Pyste/settings.py21
-rw-r--r--libs/python/pyste/src/Pyste/utils.py78
-rw-r--r--libs/python/pyste/tests/GCCXMLParserUT.py341
-rw-r--r--libs/python/pyste/tests/SmartFileUT.py84
-rw-r--r--libs/python/pyste/tests/abstract_test.h22
-rw-r--r--libs/python/pyste/tests/abstract_test.pyste3
-rw-r--r--libs/python/pyste/tests/abstract_testUT.py26
-rw-r--r--libs/python/pyste/tests/add_test.h18
-rw-r--r--libs/python/pyste/tests/add_test.pyste2
-rw-r--r--libs/python/pyste/tests/add_testUT.py16
-rw-r--r--libs/python/pyste/tests/basic.cpp13
-rw-r--r--libs/python/pyste/tests/basic.h69
-rw-r--r--libs/python/pyste/tests/basic.pyste5
-rw-r--r--libs/python/pyste/tests/basicUT.py73
-rw-r--r--libs/python/pyste/tests/code_test.h8
-rw-r--r--libs/python/pyste/tests/code_test.pyste9
-rw-r--r--libs/python/pyste/tests/code_testUT.py18
-rw-r--r--libs/python/pyste/tests/enums.h34
-rw-r--r--libs/python/pyste/tests/enums.pyste8
-rw-r--r--libs/python/pyste/tests/enumsUT.py24
-rw-r--r--libs/python/pyste/tests/header_test.h43
-rw-r--r--libs/python/pyste/tests/header_test.pyste4
-rw-r--r--libs/python/pyste/tests/header_testUT.py27
-rw-r--r--libs/python/pyste/tests/infosUT.py55
-rw-r--r--libs/python/pyste/tests/inherit.cpp8
-rw-r--r--libs/python/pyste/tests/inherit.h43
-rw-r--r--libs/python/pyste/tests/inherit.pyste8
-rw-r--r--libs/python/pyste/tests/inherit2.h35
-rw-r--r--libs/python/pyste/tests/inherit2.pyste2
-rw-r--r--libs/python/pyste/tests/inherit2UT.py31
-rw-r--r--libs/python/pyste/tests/inherit3.h46
-rw-r--r--libs/python/pyste/tests/inherit3.pyste2
-rw-r--r--libs/python/pyste/tests/inherit3UT.py27
-rw-r--r--libs/python/pyste/tests/inherit4.h23
-rw-r--r--libs/python/pyste/tests/inherit4.pyste3
-rw-r--r--libs/python/pyste/tests/inherit4UT.py31
-rw-r--r--libs/python/pyste/tests/inheritUT.py33
-rw-r--r--libs/python/pyste/tests/nested.cpp9
-rw-r--r--libs/python/pyste/tests/nested.h32
-rw-r--r--libs/python/pyste/tests/nested.pyste1
-rw-r--r--libs/python/pyste/tests/nestedUT.py19
-rw-r--r--libs/python/pyste/tests/opaque.h57
-rw-r--r--libs/python/pyste/tests/opaque.pyste7
-rw-r--r--libs/python/pyste/tests/opaqueUT.py24
-rw-r--r--libs/python/pyste/tests/operators.cpp8
-rw-r--r--libs/python/pyste/tests/operators.h52
-rw-r--r--libs/python/pyste/tests/operators.pyste2
-rw-r--r--libs/python/pyste/tests/operatorsUT.py30
-rw-r--r--libs/python/pyste/tests/policiesUT.py67
-rw-r--r--libs/python/pyste/tests/runtests.py21
-rw-r--r--libs/python/pyste/tests/smart_ptr.h50
-rw-r--r--libs/python/pyste/tests/smart_ptr.pyste13
-rw-r--r--libs/python/pyste/tests/smart_ptrUT.py22
-rw-r--r--libs/python/pyste/tests/templates.h15
-rw-r--r--libs/python/pyste/tests/templates.pyste8
-rw-r--r--libs/python/pyste/tests/templatesUT.py30
-rw-r--r--libs/python/pyste/tests/test_all.py140
-rw-r--r--libs/python/pyste/tests/vars.cpp12
-rw-r--r--libs/python/pyste/tests/vars.h24
-rw-r--r--libs/python/pyste/tests/vars.pyste1
-rw-r--r--libs/python/pyste/tests/varsUT.py22
-rw-r--r--libs/python/pyste/tests/virtual.cpp75
-rw-r--r--libs/python/pyste/tests/virtual.h41
-rw-r--r--libs/python/pyste/tests/virtual.pyste6
-rw-r--r--libs/python/pyste/tests/virtual2.h34
-rw-r--r--libs/python/pyste/tests/virtual2.pyste6
-rw-r--r--libs/python/pyste/tests/virtual2UT.py40
-rw-r--r--libs/python/pyste/tests/virtualUT.py55
-rw-r--r--libs/python/pyste/tests/wrappertest.h51
-rw-r--r--libs/python/pyste/tests/wrappertest.pyste21
-rw-r--r--libs/python/pyste/tests/wrappertestUT.py24
-rw-r--r--libs/python/pyste/tests/wrappertest_wrappers.h33
-rw-r--r--libs/python/release_notes.txt223
-rw-r--r--libs/python/src/converter/arg_to_python_base.cpp28
-rw-r--r--libs/python/src/converter/builtin_converters.cpp570
-rw-r--r--libs/python/src/converter/from_python.cpp303
-rw-r--r--libs/python/src/converter/registry.cpp306
-rw-r--r--libs/python/src/converter/type_id.cpp212
-rw-r--r--libs/python/src/dict.cpp184
-rw-r--r--libs/python/src/errors.cpp105
-rw-r--r--libs/python/src/exec.cpp108
-rw-r--r--libs/python/src/import.cpp25
-rw-r--r--libs/python/src/list.cpp170
-rw-r--r--libs/python/src/long.cpp39
-rw-r--r--libs/python/src/module.cpp73
-rw-r--r--libs/python/src/numeric.cpp325
-rw-r--r--libs/python/src/object/class.cpp764
-rw-r--r--libs/python/src/object/enum.cpp246
-rw-r--r--libs/python/src/object/function.cpp793
-rw-r--r--libs/python/src/object/function_doc_signature.cpp344
-rw-r--r--libs/python/src/object/inheritance.cpp495
-rw-r--r--libs/python/src/object/iterator.cpp39
-rw-r--r--libs/python/src/object/life_support.cpp121
-rw-r--r--libs/python/src/object/pickle_support.cpp78
-rw-r--r--libs/python/src/object/stl_iterator.cpp48
-rw-r--r--libs/python/src/object_operators.cpp85
-rw-r--r--libs/python/src/object_protocol.cpp197
-rw-r--r--libs/python/src/slice.cpp37
-rw-r--r--libs/python/src/str.cpp403
-rw-r--r--libs/python/src/tuple.cpp35
-rw-r--r--libs/python/src/wrapper.cpp66
-rw-r--r--libs/python/test/Jamfile.v2236
-rw-r--r--libs/python/test/a_map_indexing_suite.cpp92
-rw-r--r--libs/python/test/andreas_beyer.cpp61
-rw-r--r--libs/python/test/andreas_beyer.py24
-rw-r--r--libs/python/test/args.cpp99
-rw-r--r--libs/python/test/args.py147
-rw-r--r--libs/python/test/as_to_python_function.cpp13
-rw-r--r--libs/python/test/auto_ptr.cpp90
-rw-r--r--libs/python/test/auto_ptr.py100
-rw-r--r--libs/python/test/back_reference.cpp112
-rw-r--r--libs/python/test/back_reference.py37
-rw-r--r--libs/python/test/bases.cpp62
-rw-r--r--libs/python/test/ben_scott1.cpp54
-rw-r--r--libs/python/test/ben_scott1.py17
-rw-r--r--libs/python/test/bienstman1.cpp40
-rw-r--r--libs/python/test/bienstman1.py23
-rw-r--r--libs/python/test/bienstman2.cpp28
-rw-r--r--libs/python/test/bienstman2.py20
-rw-r--r--libs/python/test/bienstman3.cpp26
-rw-r--r--libs/python/test/bienstman3.py30
-rw-r--r--libs/python/test/bienstman4.cpp39
-rw-r--r--libs/python/test/bienstman4.py23
-rw-r--r--libs/python/test/bienstman5.cpp23
-rw-r--r--libs/python/test/bienstman5.py21
-rw-r--r--libs/python/test/borrowed.cpp33
-rw-r--r--libs/python/test/callbacks.cpp150
-rw-r--r--libs/python/test/callbacks.py147
-rw-r--r--libs/python/test/calling_conventions.cpp158
-rw-r--r--libs/python/test/calling_conventions.py81
-rw-r--r--libs/python/test/calling_conventions_mf.cpp159
-rw-r--r--libs/python/test/calling_conventions_mf.py84
-rw-r--r--libs/python/test/class.cpp28
-rwxr-xr-xlibs/python/test/class.py40
-rw-r--r--libs/python/test/cltree.cpp74
-rw-r--r--libs/python/test/complicated.hpp38
-rw-r--r--libs/python/test/const_argument.cpp30
-rw-r--r--libs/python/test/const_argument.py23
-rw-r--r--libs/python/test/copy_ctor_mutates_rhs.cpp23
-rw-r--r--libs/python/test/crossmod_exception.py19
-rw-r--r--libs/python/test/crossmod_exception_a.cpp18
-rw-r--r--libs/python/test/crossmod_exception_b.cpp18
-rw-r--r--libs/python/test/crossmod_opaque.py16
-rw-r--r--libs/python/test/crossmod_opaque_a.cpp26
-rw-r--r--libs/python/test/crossmod_opaque_b.cpp26
-rw-r--r--libs/python/test/data_members.cpp132
-rw-r--r--libs/python/test/data_members.py215
-rw-r--r--libs/python/test/defaults.cpp173
-rw-r--r--libs/python/test/defaults.py140
-rw-r--r--libs/python/test/destroy_test.cpp59
-rw-r--r--libs/python/test/dict.cpp91
-rw-r--r--libs/python/test/dict.py45
-rw-r--r--libs/python/test/docstring.cpp116
-rw-r--r--libs/python/test/docstring.py153
-rw-r--r--libs/python/test/enable_shared_from_this.cpp48
-rwxr-xr-xlibs/python/test/enable_shared_from_this.py26
-rw-r--r--libs/python/test/enum.cpp55
-rw-r--r--libs/python/test/enum.py85
-rw-r--r--libs/python/test/exception_translator.cpp28
-rw-r--r--libs/python/test/exception_translator.py27
-rw-r--r--libs/python/test/exec.cpp193
-rw-r--r--libs/python/test/exec.py6
-rw-r--r--libs/python/test/extract.cpp143
-rw-r--r--libs/python/test/extract.py107
-rw-r--r--libs/python/test/if_else.cpp44
-rw-r--r--libs/python/test/implicit.cpp48
-rw-r--r--libs/python/test/implicit.py44
-rw-r--r--libs/python/test/import_.cpp70
-rw-r--r--libs/python/test/import_.py5
-rw-r--r--libs/python/test/indirect_traits_test.cpp117
-rw-r--r--libs/python/test/injected.cpp39
-rw-r--r--libs/python/test/injected.py28
-rw-r--r--libs/python/test/input_iterator.cpp48
-rw-r--r--libs/python/test/int_map_indexing_suite.cpp16
-rw-r--r--libs/python/test/iterator.cpp137
-rw-r--r--libs/python/test/iterator.py77
-rw-r--r--libs/python/test/keywords.cpp118
-rw-r--r--libs/python/test/keywords_test.py106
-rw-r--r--libs/python/test/list.cpp154
-rw-r--r--libs/python/test/list.py118
-rw-r--r--libs/python/test/long.cpp63
-rw-r--r--libs/python/test/long.py33
-rw-r--r--libs/python/test/m1.cpp344
-rw-r--r--libs/python/test/m2.cpp108
-rw-r--r--libs/python/test/map_indexing_suite.cpp68
-rw-r--r--libs/python/test/map_indexing_suite.py242
-rw-r--r--libs/python/test/minimal.cpp16
-rw-r--r--libs/python/test/minimal.py7
-rw-r--r--libs/python/test/module_tail.cpp58
-rw-r--r--libs/python/test/multi_arg_constructor.cpp27
-rw-r--r--libs/python/test/multi_arg_constructor.py21
-rw-r--r--libs/python/test/nested.cpp51
-rw-r--r--libs/python/test/nested.py40
-rw-r--r--libs/python/test/newtest.py206
-rw-r--r--libs/python/test/numarray_tests.py63
-rw-r--r--libs/python/test/numeric_tests.py39
-rw-r--r--libs/python/test/numpy.cpp136
-rw-r--r--libs/python/test/numpy.py87
-rw-r--r--libs/python/test/object.cpp392
-rw-r--r--libs/python/test/object.py179
-rw-r--r--libs/python/test/object_fail1.cpp11
-rw-r--r--libs/python/test/object_manager.cpp33
-rw-r--r--libs/python/test/opaque.cpp76
-rw-r--r--libs/python/test/opaque.py87
-rw-r--r--libs/python/test/operators.cpp175
-rw-r--r--libs/python/test/operators.py102
-rw-r--r--libs/python/test/operators_wrapper.cpp42
-rw-r--r--libs/python/test/operators_wrapper.py11
-rw-r--r--libs/python/test/pickle1.cpp62
-rw-r--r--libs/python/test/pickle1.py41
-rw-r--r--libs/python/test/pickle2.cpp97
-rw-r--r--libs/python/test/pickle2.py50
-rw-r--r--libs/python/test/pickle3.cpp107
-rw-r--r--libs/python/test/pickle3.py45
-rw-r--r--libs/python/test/pickle4.cpp44
-rw-r--r--libs/python/test/pickle4.py39
-rw-r--r--libs/python/test/pointee.cpp34
-rw-r--r--libs/python/test/pointer_type_id_test.cpp43
-rw-r--r--libs/python/test/pointer_vector.cpp52
-rw-r--r--libs/python/test/pointer_vector.py31
-rw-r--r--libs/python/test/polymorphism.cpp162
-rw-r--r--libs/python/test/polymorphism.py74
-rw-r--r--libs/python/test/polymorphism2.cpp172
-rw-r--r--libs/python/test/polymorphism2.py94
-rw-r--r--libs/python/test/polymorphism2_auto_ptr.cpp6
-rw-r--r--libs/python/test/polymorphism2_auto_ptr.py5
-rw-r--r--libs/python/test/printer.py13
-rw-r--r--libs/python/test/properties.cpp100
-rw-r--r--libs/python/test/properties.py106
-rw-r--r--libs/python/test/pyrun.py7
-rw-r--r--libs/python/test/pytype_function.cpp85
-rwxr-xr-xlibs/python/test/pytype_function.py32
-rw-r--r--libs/python/test/raw_ctor.cpp43
-rw-r--r--libs/python/test/raw_ctor.py76
-rw-r--r--libs/python/test/raw_pyobject_fail1.cpp11
-rw-r--r--libs/python/test/raw_pyobject_fail2.cpp13
-rw-r--r--libs/python/test/register_ptr.cpp55
-rw-r--r--libs/python/test/register_ptr_test.py25
-rw-r--r--libs/python/test/result.cpp111
-rw-r--r--libs/python/test/return_arg.cpp67
-rw-r--r--libs/python/test/return_arg.py27
-rw-r--r--libs/python/test/select_arg_to_python_test.cpp70
-rw-r--r--libs/python/test/select_from_python_test.cpp161
-rw-r--r--libs/python/test/select_holder.cpp76
-rw-r--r--libs/python/test/shared_ptr.cpp217
-rw-r--r--libs/python/test/shared_ptr.py130
-rw-r--r--libs/python/test/simple_type.hpp13
-rw-r--r--libs/python/test/slice.cpp140
-rw-r--r--libs/python/test/slice.py72
-rw-r--r--libs/python/test/staticmethod.cpp48
-rw-r--r--libs/python/test/staticmethod.py57
-rw-r--r--libs/python/test/stl_iterator.cpp33
-rw-r--r--libs/python/test/stl_iterator.py39
-rw-r--r--libs/python/test/str.cpp84
-rw-r--r--libs/python/test/str.py53
-rw-r--r--libs/python/test/string_literal.cpp42
-rw-r--r--libs/python/test/test_builtin_converters.cpp152
-rw-r--r--libs/python/test/test_builtin_converters.py302
-rw-r--r--libs/python/test/test_class.hpp32
-rw-r--r--libs/python/test/test_cltree.py43
-rw-r--r--libs/python/test/test_overload_resolution.cpp53
-rw-r--r--libs/python/test/test_pointer_adoption.cpp125
-rw-r--r--libs/python/test/test_pointer_adoption.py93
-rw-r--r--libs/python/test/tuple.cpp33
-rw-r--r--libs/python/test/tuple.py37
-rw-r--r--libs/python/test/upcast.cpp19
-rw-r--r--libs/python/test/vector_indexing_suite.cpp62
-rw-r--r--libs/python/test/vector_indexing_suite.py370
-rw-r--r--libs/python/test/virtual_functions.cpp125
-rw-r--r--libs/python/test/virtual_functions.py110
-rw-r--r--libs/python/test/voidptr.cpp43
-rw-r--r--libs/python/test/voidptr.py54
-rw-r--r--libs/python/test/wrapper_held_type.cpp69
-rw-r--r--libs/python/test/wrapper_held_type.py34
-rw-r--r--libs/python/todo.html240
-rw-r--r--libs/python/todo.txt206
476 files changed, 58967 insertions, 0 deletions
diff --git a/libs/python/build/Jamfile.v2 b/libs/python/build/Jamfile.v2
new file mode 100644
index 000000000..32bffb0f7
--- /dev/null
+++ b/libs/python/build/Jamfile.v2
@@ -0,0 +1,151 @@
+# Copyright David Abrahams 2001-2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import os ;
+import indirect ;
+import modules ;
+import feature ;
+
+import python ;
+
+if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
+{
+ # Attempt default configuration of python
+ import toolset : using ;
+ using python ;
+}
+
+if [ python.configured ] || ( --without-python in [ modules.peek : ARGV ] )
+{
+ alias config-warning ;
+}
+else
+{
+ message config-warning
+ : "warning: No python installation configured and autoconfiguration"
+ : "note: failed. See http://www.boost.org/libs/python/doc/building.html"
+ : "note: for configuration instructions or pass --without-python to"
+ : "note: suppress this message and silently skip all Boost.Python targets"
+ ;
+}
+
+rule find-py3-version
+{
+ local versions = [ feature.values python ] ;
+ local py3ver ;
+ for local v in $(versions)
+ {
+ if $(v) >= 3.0
+ {
+ py3ver = $(v) ;
+ }
+ }
+ return $(py3ver) ;
+}
+
+py3-version = [ find-py3-version ] ;
+
+project boost/python
+ : source-location ../src
+ : requirements
+ -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
+ <tag>@$(__name__).tag
+ ;
+
+rule tag ( name : type ? : property-set )
+{
+ local result = $(name) ;
+ if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
+ {
+ if $(name) = boost_python && $(PYTHON_ID)
+ {
+ result = $(result)-$(PYTHON_ID) ;
+ }
+ }
+
+ # forward to the boost tagging rule
+ return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
+ $(result) : $(type) : $(property-set) ] ;
+}
+
+rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
+rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
+
+rule lib_boost_python ( is-py3 ? )
+{
+
+ lib [ cond $(is-py3) : boost_python3 : boost_python ]
+ : # sources
+ numeric.cpp
+ list.cpp
+ long.cpp
+ dict.cpp
+ tuple.cpp
+ str.cpp
+ slice.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/stl_iterator.cpp
+ object_protocol.cpp
+ object_operators.cpp
+ wrapper.cpp
+ import.cpp
+ exec.cpp
+ object/function_doc_signature.cpp
+ : # requirements
+ <link>static:<define>BOOST_PYTHON_STATIC_LIB
+ <define>BOOST_PYTHON_SOURCE
+
+ # On Windows, all code using Python has to link to the Python
+ # import library.
+ #
+ # On *nix we never link libboost_python to libpython. When
+ # extending Python, all Python symbols are provided by the
+ # Python interpreter executable. When embedding Python, the
+ # client executable is expected to explicitly link to
+ # /python//python (the target representing libpython) itself.
+ #
+ # python_for_extensions is a target defined by Boost.Build to
+ # provide the Python include paths, and on Windows, the Python
+ # import library, as usage requirements.
+ [ cond [ python.configured ] : <library>/python//python_for_extensions ]
+
+ # we prevent building when there is no python available
+ # as it's not possible anyway, and to cause dependents to
+ # fail to build
+ [ unless [ python.configured ] : <build>no ]
+ <dependency>config-warning
+
+ <python-debugging>on:<define>BOOST_DEBUG_PYTHON
+ [ cond $(is-py3) : <python>$(py3-version) ]
+ : # default build
+ <link>shared
+ : # usage requirements
+ <link>static:<define>BOOST_PYTHON_STATIC_LIB
+ <python-debugging>on:<define>BOOST_DEBUG_PYTHON
+ ;
+
+}
+
+lib_boost_python ;
+boost-install boost_python ;
+
+if $(py3-version)
+{
+ lib_boost_python yes ;
+ boost-install boost_python3 ;
+}
diff --git a/libs/python/build/python_v1.zip b/libs/python/build/python_v1.zip
new file mode 100644
index 000000000..0377a07bb
--- /dev/null
+++ b/libs/python/build/python_v1.zip
Binary files differ
diff --git a/libs/python/class.cpp b/libs/python/class.cpp
new file mode 100644
index 000000000..078bebdf6
--- /dev/null
+++ b/libs/python/class.cpp
@@ -0,0 +1,28 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/class.hpp>
+
+using namespace boost::python;
+
+struct X
+{
+ int x;
+ X(int n) : x(n) { }
+};
+
+int x_function(X& x)
+{ return x.x;
+}
+
+
+BOOST_PYTHON_MODULE(class_ext)
+{
+ class_<X>("X", init<int>());
+ def("x_function", x_function);
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/doc/Jamfile b/libs/python/doc/Jamfile
new file mode 100644
index 000000000..9b7c8841a
--- /dev/null
+++ b/libs/python/doc/Jamfile
@@ -0,0 +1,23 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+import docutils ;
+
+import path ;
+sources = building.rst ;
+bases = $(sources:S=) ;
+
+# This is a path relative to the html/ subdirectory where the
+# generated output will eventually be moved.
+stylesheet = "--stylesheet=../../../rst.css" ;
+
+for local b in $(bases)
+{
+ html $(b) : $(b).rst :
+
+ <docutils-html>"-gdt --source-url="./$(b).rst" --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
+ ;
+}
+
+alias htmls : $(bases) ;
+stage . : $(bases) ;
diff --git a/libs/python/doc/PyConDC_2003/bpl.html b/libs/python/doc/PyConDC_2003/bpl.html
new file mode 100644
index 000000000..32b655bd9
--- /dev/null
+++ b/libs/python/doc/PyConDC_2003/bpl.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="refresh" content="0; URL=http://www.boost-consulting.com/writing/bpl.html">
+
+ <title>Loading: &ldquo;Building Hybrid Systems With Boost.Python&rdquo;</title>
+ </head>
+
+ <body>
+ Loading...; if nothing happens, please go to <a href= "http://www.boost-consulting.com/writing/bpl.html">http://www.boost-consulting.com/writing/bpl.html</a>.
+ </body>
+</html>
+
diff --git a/libs/python/doc/PyConDC_2003/bpl.pdf b/libs/python/doc/PyConDC_2003/bpl.pdf
new file mode 100644
index 000000000..09827aff0
--- /dev/null
+++ b/libs/python/doc/PyConDC_2003/bpl.pdf
Binary files differ
diff --git a/libs/python/doc/PyConDC_2003/bpl.txt b/libs/python/doc/PyConDC_2003/bpl.txt
new file mode 100644
index 000000000..d6921b124
--- /dev/null
+++ b/libs/python/doc/PyConDC_2003/bpl.txt
@@ -0,0 +1,5 @@
+.. Copyright David Abrahams 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+This file has been moved to http://www.boost-consulting.com/writing/bpl.txt.
diff --git a/libs/python/doc/PyConDC_2003/bpl_mods.txt b/libs/python/doc/PyConDC_2003/bpl_mods.txt
new file mode 100644
index 000000000..d42f00f8b
--- /dev/null
+++ b/libs/python/doc/PyConDC_2003/bpl_mods.txt
@@ -0,0 +1,911 @@
+Copyright David Abrahams 2006. Distributed under the Boost
+Software License, Version 1.0. (See accompanying
+file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+.. 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`_
+: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 <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 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
+necessary 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.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 BPL. 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 BPL 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 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>("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. 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>("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)
+
+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>("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, 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 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
+ necessary 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 "<stdin>", 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<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``.
+
+Admittedly, this formula is tedious to repeat, especially on a project
+with many polymorphic classes; that it is necessary 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 <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. 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<T>`` class template can be used to convert Python objects
+to C++ types::
+
+ double x = extract<double>(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<World>(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<T>`` 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/libs/python/doc/PyConDC_2003/default.css b/libs/python/doc/PyConDC_2003/default.css
new file mode 100644
index 000000000..f8109bbd3
--- /dev/null
+++ b/libs/python/doc/PyConDC_2003/default.css
@@ -0,0 +1,188 @@
+/*
+:Author: David Goodger
+:Contact: goodger@users.sourceforge.net
+:copyright: This stylesheet has been placed in the public domain.
+
+boostinspect:nolicense
+
+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/libs/python/doc/PyConDC_2003/python_cpp_mix.jpg b/libs/python/doc/PyConDC_2003/python_cpp_mix.jpg
new file mode 100644
index 000000000..755a9605b
--- /dev/null
+++ b/libs/python/doc/PyConDC_2003/python_cpp_mix.jpg
Binary files differ
diff --git a/libs/python/doc/PyConDC_2003/python_cpp_mix.png b/libs/python/doc/PyConDC_2003/python_cpp_mix.png
new file mode 100644
index 000000000..fd74cbb22
--- /dev/null
+++ b/libs/python/doc/PyConDC_2003/python_cpp_mix.png
Binary files differ
diff --git a/libs/python/doc/boost.css b/libs/python/doc/boost.css
new file mode 100644
index 000000000..6c3e9808e
--- /dev/null
+++ b/libs/python/doc/boost.css
@@ -0,0 +1,63 @@
+/* Copyright David Abrahams 2006. Distributed under the Boost
+ Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+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/libs/python/doc/building.html b/libs/python/doc/building.html
new file mode 100644
index 000000000..e2c48847f
--- /dev/null
+++ b/libs/python/doc/building.html
@@ -0,0 +1,636 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
+<title>Boost C++ Libraries: Boost.Python Build and Test HOWTO</title>
+<link rel="stylesheet" href="../../../rst.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="logo-boost-python-build-and-test-howto">
+<h1 class="title"><a class="reference external" href="../index.html"><img alt="Boost C++ Libraries:" class="boost-logo" src="../../../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at -->
+<!-- http://www.boost.org/LICENSE_1_0.txt) -->
+<div class="contents sidebar small topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="auto-toc simple">
+<li><a class="reference internal" href="#requirements" id="id25">1&nbsp;&nbsp;&nbsp;Requirements</a></li>
+<li><a class="reference internal" href="#background" id="id26">2&nbsp;&nbsp;&nbsp;Background</a></li>
+<li><a class="reference internal" href="#no-install-quickstart" id="id27">3&nbsp;&nbsp;&nbsp;No-Install Quickstart</a><ul class="auto-toc">
+<li><a class="reference internal" href="#basic-procedure" id="id28">3.1&nbsp;&nbsp;&nbsp;Basic Procedure</a></li>
+<li><a class="reference internal" href="#in-case-of-trouble" id="id29">3.2&nbsp;&nbsp;&nbsp;In Case of Trouble</a></li>
+<li><a class="reference internal" href="#in-case-everything-seemed-to-work" id="id30">3.3&nbsp;&nbsp;&nbsp;In Case Everything Seemed to Work</a></li>
+<li><a class="reference internal" href="#modifying-the-example-project" id="id31">3.4&nbsp;&nbsp;&nbsp;Modifying the Example Project</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#installing-boost-python-on-your-system" id="id32">4&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></li>
+<li><a class="reference internal" href="#configuring-boost-build" id="id33">5&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a><ul class="auto-toc">
+<li><a class="reference internal" href="#python-configuration-parameters" id="id34">5.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></li>
+<li><a class="reference internal" href="#examples" id="id35">5.2&nbsp;&nbsp;&nbsp;Examples</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#choosing-a-boost-python-library-binary" id="id36">6&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a><ul class="auto-toc">
+<li><a class="reference internal" href="#the-dynamic-binary" id="id37">6.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></li>
+<li><a class="reference internal" href="#the-static-binary" id="id38">6.2&nbsp;&nbsp;&nbsp;The Static Binary</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#include-issues" id="id39">7&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">#include</span></tt> Issues</a></li>
+<li><a class="reference internal" href="#python-debugging-builds" id="id40">8&nbsp;&nbsp;&nbsp;Python Debugging Builds</a></li>
+<li><a class="reference internal" href="#testing-boost-python" id="id41">9&nbsp;&nbsp;&nbsp;Testing Boost.Python</a></li>
+<li><a class="reference internal" href="#notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users" id="id42">10&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></li>
+</ul>
+</div>
+<div class="section" id="requirements">
+<h1><a class="toc-backref" href="#id25">1&nbsp;&nbsp;&nbsp;Requirements</a></h1>
+<p>Boost.Python requires <a class="reference external" href="http://www.python.org/2.2">Python 2.2</a><a class="footnote-reference" href="#id22" id="id2"><sup>1</sup></a> <em>or</em> <a class="reference external" href="http://www.python.org"><em>newer</em></a>.</p>
+</div>
+<div class="section" id="background">
+<h1><a class="toc-backref" href="#id26">2&nbsp;&nbsp;&nbsp;Background</a></h1>
+<p>There are two basic models for combining C++ and Python:</p>
+<ul class="simple">
+<li><a class="reference external" href="http://www.python.org/doc/current/ext/intro.html">extending</a>, in which the end-user launches the Python interpreter
+executable and imports Python “extension modules†written in C++.
+Think of taking a library written in C++ and giving it a Python
+interface so Python programmers can use it. From Python, these
+modules look just like regular Python modules.</li>
+<li><a class="reference external" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a>, in which the end-user launches a program written
+in C++ that in turn invokes the Python interpreter as a library
+subroutine. Think of adding scriptability to an existing
+application.</li>
+</ul>
+<p>The key distinction between extending and embedding is the location
+of the C++ <tt class="docutils literal"><span class="pre">main()</span></tt> function: in the Python interpreter executable,
+or in some other program, respectively. Note that even when
+embedding Python in another program, <a class="reference external" href="http://www.python.org/doc/current/ext/extending-with-embedding.html">extension modules are often
+the best way to make C/C++ functionality accessible to Python
+code</a>, so the use of extension modules is really at the heart of
+both models.</p>
+<p>Except in rare cases, extension modules are built as
+dynamically-loaded libraries with a single entry point, which means
+you can change them without rebuilding either the other extension
+modules or the executable containing <tt class="docutils literal"><span class="pre">main()</span></tt>.</p>
+</div>
+<div class="section" id="no-install-quickstart">
+<span id="quickstart"></span><h1><a class="toc-backref" href="#id27">3&nbsp;&nbsp;&nbsp;No-Install Quickstart</a></h1>
+<p>There is no need to “install Boost†in order to get started using
+Boost.Python. These instructions use <a class="reference external" href="../../../tools/build/index.html">Boost.Build</a> projects,
+which will build those binaries as soon as they're needed. Your
+first tests may take a little longer while you wait for
+Boost.Python to build, but doing things this way will save you from
+worrying about build intricacies like which library binaries to use
+for a specific compiler configuration and figuring out the right
+compiler options to use yourself.</p>
+<!-- .. raw:: html
+
+<div style="width:50%"> -->
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p>Of course it's possible to use other build systems to
+build Boost.Python and its extensions, but they are not
+officially supported by Boost. Moreover <strong>99% of all “I can't
+build Boost.Python†problems come from trying to use another
+build system</strong> without first following these instructions.</p>
+<p>If you want to use another system anyway, we suggest that you
+follow these instructions, and then invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> with the</p>
+<pre class="literal-block">
+<tt class="docutils literal"><span class="pre">-a</span> <span class="pre">-o</span></tt><em>filename</em>
+</pre>
+<p class="last">options to dump the build commands it executes to a file, so
+you can see what your alternate build system needs to do.</p>
+</div>
+<!-- .. raw:: html
+
+</div> -->
+<div class="section" id="basic-procedure">
+<h2><a class="toc-backref" href="#id28">3.1&nbsp;&nbsp;&nbsp;Basic Procedure</a></h2>
+<ol class="arabic">
+<li><p class="first">Get Boost; see sections 1 and 2 [<a class="reference external" href="../../../more/getting_started/unix-variants.html#get-boost">Unix/Linux</a>, <a class="reference external" href="../../../more/getting_started/windows.html#get-boost">Windows</a>] of the
+Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a>.</p>
+</li>
+<li><p class="first">Get the <tt class="docutils literal"><span class="pre">bjam</span></tt> build driver. See section 5 [<a class="reference external" href="../../../more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary">Unix/Linux</a>,
+<a class="reference external" href="../../../more/getting_started/windows.html#prepare-to-use-a-boost-library-binary">Windows</a>] of the Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a>.</p>
+</li>
+<li><p class="first">cd into the <tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory of your
+Boost installation, which contains a small example project.</p>
+</li>
+<li><p class="first">Invoke <tt class="docutils literal"><span class="pre">bjam</span></tt>. Replace the “<tt class="docutils literal"><span class="pre">stage</span></tt>“ argument from the
+example invocation from section 5 of the <a class="reference external" href="../../../more/getting_started/index.html">Getting Started
+Guide</a> with “<tt class="docutils literal"><span class="pre">test</span></tt>,“ to build all the test targets. Also add
+the argument “<tt class="docutils literal"><span class="pre">--verbose-test</span></tt>†to see the output generated by
+the tests when they are run.</p>
+<p>On Windows, your <tt class="docutils literal"><span class="pre">bjam</span></tt> invocation might look something like:</p>
+<pre class="literal-block">
+C:\boost_1_34_0\…\quickstart&gt; <strong>bjam toolset=msvc --verbose-test test</strong>
+</pre>
+<p>and on Unix variants, perhaps,</p>
+<pre class="literal-block">
+~/boost_1_34_0/…/quickstart$ <strong>bjam toolset=gcc --verbose-test test</strong>
+</pre>
+</li>
+</ol>
+<div class="admonition-note-to-windows-users admonition">
+<p class="first admonition-title">Note to Windows Users</p>
+<p class="last">For the sake of concision, the rest of this guide will use
+unix-style forward slashes in pathnames instead of the
+backslashes with which you may be more familiar. The forward
+slashes should work everywhere except in <a class="reference external" href="../../../more/getting_started/windows.html#command-prompt">Command Prompt</a>
+windows, where you should use backslashes.</p>
+</div>
+<p>If you followed this procedure successfully, you will have built an
+extension module called <tt class="docutils literal"><span class="pre">extending</span></tt> and tested it by running a
+Python script called <tt class="docutils literal"><span class="pre">test_extending.py</span></tt>. You will also have
+built and run a simple application called <tt class="docutils literal"><span class="pre">embedding</span></tt> that embeds
+python.</p>
+</div>
+<div class="section" id="in-case-of-trouble">
+<h2><a class="toc-backref" href="#id29">3.2&nbsp;&nbsp;&nbsp;In Case of Trouble</a></h2>
+<p>If you're seeing lots of compiler and/or linker error messages,
+it's probably because Boost.Build is having trouble finding your
+Python installation. You might want to pass the
+<tt class="docutils literal"><span class="pre">--debug-configuration</span></tt> option to <tt class="docutils literal"><span class="pre">bjam</span></tt> the first few times
+you invoke it, to make sure that Boost.Build is correctly locating
+all the parts of your Python installation. If it isn't, consider
+<a class="reference internal" href="#configuring-boost-build">Configuring Boost.Build</a> as detailed below.</p>
+<p>If you're still having trouble, Someone on one of the following
+mailing lists may be able to help:</p>
+<ul class="simple">
+<li>The <a class="reference external" href="http://www.boost.org/more/mailing_lists.htm#jamboost">Boost.Build mailing list</a> for issues related to Boost.Build</li>
+<li>The Python <a class="reference external" href="http://www.boost.org/more/mailing_lists.htm#cplussig">C++ Sig</a> for issues specifically related to Boost.Python</li>
+</ul>
+</div>
+<div class="section" id="in-case-everything-seemed-to-work">
+<h2><a class="toc-backref" href="#id30">3.3&nbsp;&nbsp;&nbsp;In Case Everything Seemed to Work</a></h2>
+<p>Rejoice! If you're new to Boost.Python, at this point it might be
+a good idea to ignore build issues for a while and concentrate on
+learning the library by going through the <a class="reference external" href="tutorial/index.html">tutorial</a> and perhaps
+some of the <a class="reference external" href="v2/reference.html">reference documentation</a>, trying out what you've
+learned about the API by modifying the quickstart project.</p>
+</div>
+<div class="section" id="modifying-the-example-project">
+<h2><a class="toc-backref" href="#id31">3.4&nbsp;&nbsp;&nbsp;Modifying the Example Project</a></h2>
+<p>If you're content to keep your extension module forever in one
+source file called <a class="reference external" href="../example/quickstart/extending.cpp"><tt class="docutils literal"><span class="pre">extending.cpp</span></tt></a>, inside your Boost
+distribution, and import it forever as <tt class="docutils literal"><span class="pre">extending</span></tt>, then you can
+stop here. However, it's likely that you will want to make a few
+changes. There are a few things you can do without having to learn
+<a class="reference external" href="../../../tools/build/index.html">Boost.Build</a> in depth.</p>
+<p>The project you just built is specified in two files in the current
+directory: <a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a>, which tells <tt class="docutils literal"><span class="pre">bjam</span></tt> where it can
+find the interpreted code of the Boost build system, and
+<a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, which describes the targets you just built. These
+files are heavily commented, so they should be easy to modify.
+Take care, however, to preserve whitespace. Punctuation such as
+<tt class="docutils literal"><span class="pre">;</span></tt> will not be recognized as intended by <tt class="docutils literal"><span class="pre">bjam</span></tt> if it is not
+surrounded by whitespace.</p>
+<div class="section" id="relocate-the-project">
+<h3>Relocate the Project</h3>
+<p>You'll probably want to copy this project elsewhere so you can
+change it without modifying your Boost distribution. To do that,
+simply</p>
+<ol class="loweralpha simple">
+<li>copy the entire <tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory
+into a new directory.</li>
+<li>In the new copies of <a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a> and <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, locate
+the relative path near the top of the file that is clearly
+marked by a comment, and edit that path so that it refers to the
+same directory your Boost distribution as it referred to when
+the file was in its original location in the
+<tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory.</li>
+</ol>
+<p>For example, if you moved the project from
+<tt class="docutils literal"><span class="pre">/home/dave/boost_1_34_0/libs/python/example/quickstart</span></tt> to
+<tt class="docutils literal"><span class="pre">/home/dave/my-project</span></tt>, you could change the first path in
+<a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a> from</p>
+<pre class="literal-block">
+<strong>../../../..</strong>/tools/build/v2
+</pre>
+<p>to</p>
+<pre class="literal-block">
+<strong>/home/dave/boost_1_34_0</strong>/tools/build/v2
+</pre>
+<p>and change the first path in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> from</p>
+<pre class="literal-block">
+<strong>../../../..</strong>
+</pre>
+<p>to</p>
+<pre class="literal-block">
+<strong>/home/dave/boost_1_34_0</strong>
+</pre>
+</div>
+<div class="section" id="add-new-or-change-names-of-existing-source-files">
+<h3>Add New or Change Names of Existing Source Files</h3>
+<p>The names of additional source files involved in building your
+extension module or embedding application can be listed in
+<a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> right alongside <tt class="docutils literal"><span class="pre">extending.cpp</span></tt> or <tt class="docutils literal"><span class="pre">embedding.cpp</span></tt>
+respectively. Just be sure to leave whitespace around each
+filename:</p>
+<pre class="literal-block">
+… file1.cpp file2.cpp file3.cpp …
+</pre>
+<p>Naturally, if you want to change the name of a source file you can
+tell Boost.Build about it by editing the name in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>.</p>
+</div>
+<div class="section" id="change-the-name-of-your-extension-module">
+<h3>Change the Name of your Extension Module</h3>
+<p>The name of the extension module is determined by two things:</p>
+<ol class="arabic simple">
+<li>the name in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> immediately following <tt class="docutils literal"><span class="pre">python-extension</span></tt>, and</li>
+<li>the name passed to <tt class="docutils literal"><span class="pre">BOOST_PYTHON_MODULE</span></tt> in <a class="reference external" href="../example/quickstart/extending.cpp"><tt class="docutils literal"><span class="pre">extending.cpp</span></tt></a>.</li>
+</ol>
+<p>To change the name of the extension module from <tt class="docutils literal"><span class="pre">extending</span></tt> to
+<tt class="docutils literal"><span class="pre">hello</span></tt>, you'd edit <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, changing</p>
+<pre class="literal-block">
+python-extension <strong>extending</strong> : extending.cpp ;
+</pre>
+<p>to</p>
+<pre class="literal-block">
+python-extension <strong>hello</strong> : extending.cpp ;
+</pre>
+<p>and you'd edit extending.cpp, changing</p>
+<pre class="literal-block">
+BOOST_PYTHON_MODULE(<strong>extending</strong>)
+</pre>
+<p>to</p>
+<pre class="literal-block">
+BOOST_PYTHON_MODULE(<strong>hello</strong>)
+</pre>
+</div>
+</div>
+</div>
+<div class="section" id="installing-boost-python-on-your-system">
+<h1><a class="toc-backref" href="#id32">4&nbsp;&nbsp;&nbsp;Installing Boost.Python on your System</a></h1>
+<p>Since Boost.Python is a separately-compiled (as opposed to
+<a class="reference external" href="../../../more/getting_started/windows.html#header-only-libraries">header-only</a>) library, its user relies on the services of a
+Boost.Python library binary.</p>
+<p>If you need a regular installation of the Boost.Python library
+binaries on your system, the Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a> will
+walk you through the steps of creating one. If building binaries
+from source, you might want to supply the <tt class="docutils literal"><span class="pre">--with-python</span></tt>
+argument to <tt class="docutils literal"><span class="pre">bjam</span></tt> (or the <tt class="docutils literal"><span class="pre">--with-libraries=python</span></tt> argument
+to <tt class="docutils literal"><span class="pre">configure</span></tt>), so only the Boost.Python binary will be built,
+rather than all the Boost binaries.</p>
+</div>
+<div class="section" id="configuring-boost-build">
+<h1><a class="toc-backref" href="#id33">5&nbsp;&nbsp;&nbsp;Configuring Boost.Build</a></h1>
+<p>As described in the <a class="reference external" href="http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration">Boost.Build reference manual</a>, a file called
+<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home directory<a class="footnote-reference" href="#home-dir" id="id11"><sup>6</sup></a> is used to
+specify the tools and libraries available to the build system. You
+may need to create or edit <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> to tell Boost.Build
+how to invoke Python, <tt class="docutils literal"><span class="pre">#include</span></tt> its headers, and link with its
+libraries.</p>
+<div class="admonition-users-of-unix-variant-oses admonition">
+<p class="first admonition-title">Users of Unix-Variant OSes</p>
+<p class="last">If you are using a unix-variant OS and you ran Boost's
+<tt class="docutils literal"><span class="pre">configure</span></tt> script, it may have generated a
+<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> for you.<a class="footnote-reference" href="#overwrite" id="id13"><sup>4</sup></a> If your <tt class="docutils literal"><span class="pre">configure</span></tt>/<tt class="docutils literal"><span class="pre">make</span></tt> sequence was successful and Boost.Python binaries
+were built, your <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file is probably already
+correct.</p>
+</div>
+<p>If you have one fairly “standard†python installation for your
+platform, you might not need to do anything special to describe it. If
+you haven't configured python in <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> (and you don't
+specify <tt class="docutils literal"><span class="pre">--without-python</span></tt> on the Boost.Build command line),
+Boost.Build will automatically execute the equivalent of</p>
+<pre class="literal-block">
+import toolset : using ;
+using python ;
+</pre>
+<p>which automatically looks for Python in the most likely places.
+However, that only happens when using the Boost.Python project file
+(e.g. when referred to by another project as in the <a class="reference internal" href="#quickstart">quickstart</a>
+method). If instead you are linking against separately-compiled
+Boost.Python binaries, you should set up a <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file
+with at least the minimal incantation above.</p>
+<div class="section" id="python-configuration-parameters">
+<h2><a class="toc-backref" href="#id34">5.1&nbsp;&nbsp;&nbsp;Python Configuration Parameters</a></h2>
+<p>If you have several versions of Python installed, or Python is
+installed in an unusual way, you may want to supply any or all of
+the following optional parameters to <tt class="docutils literal"><span class="pre">using</span> <span class="pre">python</span></tt>.</p>
+<dl class="docutils">
+<dt>version</dt>
+<dd>the version of Python to use. Should be in Major.Minor
+format, for example, <tt class="docutils literal"><span class="pre">2.3</span></tt>. Do not include the subminor
+version (i.e. <em>not</em> <tt class="docutils literal"><span class="pre">2.5.1</span></tt>). If you have multiple Python
+versions installed, the version will usually be the only
+configuration argument required.</dd>
+<dt>cmd-or-prefix</dt>
+<dd>preferably, a command that invokes a Python interpreter.
+Alternatively, the installation prefix for Python libraries and
+header files. Only use the alternative formulation if there is
+no appropriate Python executable available.</dd>
+<dt>includes</dt>
+<dd>the <tt class="docutils literal"><span class="pre">#include</span></tt> paths for Python headers. Normally the correct
+path(s) will be automatically deduced from <tt class="docutils literal"><span class="pre">version</span></tt> and/or
+<tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>.</dd>
+<dt>libraries</dt>
+<dd>the path to Python library binaries. On MacOS/Darwin,
+you can also pass the path of the Python framework. Normally the
+correct path(s) will be automatically deduced from <tt class="docutils literal"><span class="pre">version</span></tt>
+and/or <tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>.</dd>
+<dt>condition</dt>
+<dd>if specified, should be a set of Boost.Build
+properties that are matched against the build configuration when
+Boost.Build selects a Python configuration to use. See examples
+below for details.</dd>
+<dt>extension-suffix</dt>
+<dd>A string to append to the name of extension
+modules before the true filename extension. You almost certainly
+don't need to use this. Usually this suffix is only used when
+targeting a Windows debug build of Python, and will be set
+automatically for you based on the value of the
+<a class="reference internal" href="#python-debugging"><tt class="docutils literal"><span class="pre">&lt;python-debugging&gt;</span></tt></a> feature. However, at least one Linux
+distribution (Ubuntu Feisty Fawn) has a specially configured
+<a class="reference external" href="https://wiki.ubuntu.com/PyDbgBuilds">python-dbg</a> package that claims to use such a suffix.</dd>
+</dl>
+</div>
+<div class="section" id="examples">
+<h2><a class="toc-backref" href="#id35">5.2&nbsp;&nbsp;&nbsp;Examples</a></h2>
+<p>Note that in the examples below, case and <em>especially whitespace</em> are
+significant.</p>
+<ul>
+<li><p class="first">If you have both python 2.5 and python 2.4 installed,
+<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> might contain:</p>
+<pre class="literal-block">
+using python : 2.5 ; # Make both versions of Python available
+
+using python : 2.4 ; # To build with python 2.4, add python=2.4
+ # to your command line.
+</pre>
+<p>The first version configured (2.5) becomes the default. To build
+against python 2.4, add <tt class="docutils literal"><span class="pre">python=2.4</span></tt> to the <tt class="docutils literal"><span class="pre">bjam</span></tt> command line.</p>
+</li>
+<li><p class="first">If you have python installed in an unusual location, you might
+supply the path to the interpreter in the <tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>
+parameter:</p>
+<pre class="literal-block">
+using python : : /usr/local/python-2.6-beta/bin/python ;
+</pre>
+</li>
+<li><p class="first">If you have a separate build of Python for use with a particular
+toolset, you might supply that toolset in the <tt class="docutils literal"><span class="pre">condition</span></tt>
+parameter:</p>
+<pre class="literal-block">
+using python ; # use for most toolsets
+
+# Use with Intel C++ toolset
+using python
+ : # version
+ : c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
+ : # includes
+ : # libraries
+ : &lt;toolset&gt;intel # condition
+ ;
+</pre>
+</li>
+<li><p class="first">If you have downloaded the Python sources and built both the
+normal and the “<a class="reference internal" href="#id19">python debugging</a>†builds from source on
+Windows, you might see:</p>
+<pre class="literal-block">
+using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
+using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
+ : # includes
+ : # libs
+ : &lt;python-debugging&gt;on ;
+</pre>
+</li>
+<li><p class="first">You can set up your user-config.jam so a bjam built under Windows
+can build/test both Windows and <a class="reference external" href="http://cygwin.com">Cygwin</a> python extensions. Just pass
+<tt class="docutils literal"><span class="pre">&lt;target-os&gt;cygwin</span></tt> in the <tt class="docutils literal"><span class="pre">condition</span></tt> parameter
+for the cygwin python installation:</p>
+<pre class="literal-block">
+# windows installation
+using python ;
+
+# cygwin installation
+using python : : c:\\cygwin\\bin\\python2.5 : : : &lt;target-os&gt;cygwin ;
+</pre>
+<p>when you put target-os=cygwin in your build request, it should build
+with the cygwin version of python:<a class="footnote-reference" href="#flavor" id="id15"><sup>5</sup></a></p>
+<blockquote>
+<p>bjam target-os=cygwin toolset=gcc</p>
+</blockquote>
+<p>This is supposed to work the other way, too (targeting windows
+python with a <a class="reference external" href="http://cygwin.com">Cygwin</a> bjam) but it seems as though the support in
+Boost.Build's toolsets for building that way is broken at the
+time of this writing.</p>
+</li>
+<li><p class="first">Note that because of <a class="reference external" href="http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection">the way Boost.Build currently selects target
+alternatives</a>, you might have be very explicit in your build
+requests. For example, given:</p>
+<pre class="literal-block">
+using python : 2.5 ; # a regular windows build
+using python : 2.4 : : : : &lt;target-os&gt;cygwin ;
+</pre>
+<p>building with</p>
+<pre class="literal-block">
+bjam target-os=cygwin
+</pre>
+<p>will yield an error. Instead, you'll need to write:</p>
+<pre class="literal-block">
+bjam target-os=cygwin/python=2.4
+</pre>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" id="choosing-a-boost-python-library-binary">
+<h1><a class="toc-backref" href="#id36">6&nbsp;&nbsp;&nbsp;Choosing a Boost.Python Library Binary</a></h1>
+<p>If—instead of letting Boost.Build construct and link with the right
+libraries automatically—you choose to use a pre-built Boost.Python
+library, you'll need to think about which one to link with. The
+Boost.Python binary comes in both static and dynamic flavors. Take
+care to choose the right flavor for your application.<a class="footnote-reference" href="#naming" id="id17"><sup>2</sup></a></p>
+<div class="section" id="the-dynamic-binary">
+<h2><a class="toc-backref" href="#id37">6.1&nbsp;&nbsp;&nbsp;The Dynamic Binary</a></h2>
+<p>The dynamic library is the safest and most-versatile choice:</p>
+<ul class="simple">
+<li>A single copy of the library code is used by all extension
+modules built with a given toolset.<a class="footnote-reference" href="#toolset-specific" id="id18"><sup>3</sup></a></li>
+<li>The library contains a type conversion registry. Because one
+registry is shared among all extension modules, instances of a
+class exposed to Python in one dynamically-loaded extension
+module can be passed to functions exposed in another such module.</li>
+</ul>
+</div>
+<div class="section" id="the-static-binary">
+<h2><a class="toc-backref" href="#id38">6.2&nbsp;&nbsp;&nbsp;The Static Binary</a></h2>
+<p>It might be appropriate to use the static Boost.Python library in
+any of the following cases:</p>
+<ul class="simple">
+<li>You are <a class="reference external" href="http://www.python.org/doc/current/ext/intro.html">extending</a> python and the types exposed in your
+dynamically-loaded extension module don't need to be used by any
+other Boost.Python extension modules, and you don't care if the
+core library code is duplicated among them.</li>
+<li>You are <a class="reference external" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a> python in your application and either:<ul>
+<li>You are targeting a Unix variant OS other than MacOS or AIX,
+where the dynamically-loaded extension modules can “see†the
+Boost.Python library symbols that are part of the executable.</li>
+<li>Or, you have statically linked some Boost.Python extension
+modules into your application and you don't care if any
+dynamically-loaded Boost.Python extension modules are able to
+use the types exposed by your statically-linked extension
+modules (and vice-versa).</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" id="include-issues">
+<h1><a class="toc-backref" href="#id39">7&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">#include</span></tt> Issues</a></h1>
+<ol class="arabic simple">
+<li>If you should ever have occasion to <tt class="docutils literal"><span class="pre">#include</span> <span class="pre">&quot;python.h&quot;</span></tt>
+directly in a translation unit of a program using Boost.Python,
+use <tt class="docutils literal"><span class="pre">#include</span> <span class="pre">&quot;boost/python/detail/wrap_python.hpp&quot;</span></tt> instead.
+It handles several issues necessary for use with Boost.Python,
+one of which is mentioned in the next section.</li>
+<li>Be sure not to <tt class="docutils literal"><span class="pre">#include</span></tt> any system headers before
+<tt class="docutils literal"><span class="pre">wrap_python.hpp</span></tt>. This restriction is actually imposed by
+Python, or more properly, by Python's interaction with your
+operating system. See
+<a class="reference external" href="http://docs.python.org/ext/simpleExample.html">http://docs.python.org/ext/simpleExample.html</a> for details.</li>
+</ol>
+</div>
+<div class="section" id="python-debugging-builds">
+<span id="id19"></span><span id="python-debugging"></span><h1><a class="toc-backref" href="#id40">8&nbsp;&nbsp;&nbsp;Python Debugging Builds</a></h1>
+<p>Python can be built in a special “python debugging†configuration
+that adds extra checks and instrumentation that can be very useful
+for developers of extension modules. The data structures used by
+the debugging configuration contain additional members, so <strong>a
+Python executable built with python debugging enabled cannot be
+used with an extension module or library compiled without it, and
+vice-versa.</strong></p>
+<p>Since pre-built “python debugging†versions of the Python
+executable and libraries are not supplied with most distributions
+of Python,<a class="footnote-reference" href="#get-debug-build" id="id20"><sup>7</sup></a> and we didn't want to force our users
+to build them, Boost.Build does not automatically enable python
+debugging in its <tt class="docutils literal"><span class="pre">debug</span></tt> build variant (which is the default).
+Instead there is a special build property called
+<tt class="docutils literal"><span class="pre">python-debugging</span></tt> that, when used as a build property, will
+define the right preprocessor symbols and select the right
+libraries to link with.</p>
+<p>On unix-variant platforms, the debugging versions of Python's data
+structures will only be used if the symbol <tt class="docutils literal"><span class="pre">Py_DEBUG</span></tt> is defined.
+On many windows compilers, when extension modules are built with
+the preprocessor symbol <tt class="docutils literal"><span class="pre">_DEBUG</span></tt>, Python defaults to force
+linking with a special debugging version of the Python DLL. Since
+that symbol is very commonly used even when Python is not present,
+Boost.Python temporarily undefines _DEBUG when Python.h
+is #included from <tt class="docutils literal"><span class="pre">boost/python/detail/wrap_python.hpp</span></tt> - unless
+<tt class="docutils literal"><span class="pre">BOOST_DEBUG_PYTHON</span></tt> is defined. The upshot is that if you want
+“python debuggingâ€and you aren't using Boost.Build, you should make
+sure <tt class="docutils literal"><span class="pre">BOOST_DEBUG_PYTHON</span></tt> is defined, or python debugging will be
+suppressed.</p>
+</div>
+<div class="section" id="testing-boost-python">
+<h1><a class="toc-backref" href="#id41">9&nbsp;&nbsp;&nbsp;Testing Boost.Python</a></h1>
+<p>To run the full test suite for Boost.Python, invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> in the
+<tt class="docutils literal"><span class="pre">libs/python/test</span></tt> subdirectory of your Boost distribution.</p>
+</div>
+<div class="section" id="notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users">
+<h1><a class="toc-backref" href="#id42">10&nbsp;&nbsp;&nbsp;Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></h1>
+<p>If you are using a version of Python prior to 2.4.1 with a MinGW
+prior to 3.0.0 (with binutils-2.13.90-20030111-1), 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 <a class="reference external" href="http://www.python.org/doc/current/inst/index.html">Installing
+Python Modules</a> to create <tt class="docutils literal"><span class="pre">libpythonXX.a</span></tt>, where <tt class="docutils literal"><span class="pre">XX</span></tt>
+corresponds to the major and minor version numbers of your Python
+installation.</p>
+<hr class="docutils" />
+<table class="docutils footnote" frame="void" id="id22" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id2">[1]</a></td><td>Note that although we tested earlier versions of
+Boost.Python with Python 2.2, and we don't <em>think</em> we've done
+anything to break compatibility, this release of Boost.Python
+may not have been tested with versions of Python earlier than
+2.4, so we're not 100% sure that python 2.2 and 2.3 are
+supported.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="naming" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id17">[2]</a></td><td><p class="first">Information about how to identify the
+static and dynamic builds of Boost.Python:</p>
+<ul class="simple">
+<li><a class="reference external" href="../../../more/getting_started/windows.html#library-naming">on Windows</a></li>
+<li><a class="reference external" href="../../../more/getting_started/unix-variants.html#library-naming">on Unix variants</a></li>
+</ul>
+</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="toolset-specific" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id18">[3]</a></td><td>Because of the way most *nix platforms
+share symbols among dynamically-loaded objects, I'm not certain
+that extension modules built with different compiler toolsets
+will always use different copies of the Boost.Python library
+when loaded into the same Python instance. Not using different
+libraries could be a good thing if the compilers have compatible
+ABIs, because extension modules built with the two libraries
+would be interoperable. Otherwise, it could spell disaster,
+since an extension module and the Boost.Python library would
+have different ideas of such things as class layout. I would
+appreciate someone doing the experiment to find out what
+happens.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="overwrite" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id13">[4]</a></td><td><tt class="docutils literal"><span class="pre">configure</span></tt> overwrites the existing
+<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home directory
+(if any) after making a backup of the old version.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="flavor" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id15">[5]</a></td><td>Note that the <tt class="docutils literal"><span class="pre">&lt;target-os&gt;cygwin</span></tt> feature is
+different from the <tt class="docutils literal"><span class="pre">&lt;flavor&gt;cygwin</span></tt> subfeature of the <tt class="docutils literal"><span class="pre">gcc</span></tt>
+toolset, and you might need handle both explicitly if you also
+have a MinGW GCC installed.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="home-dir" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id11">[6]</a></td><td><p class="first">Windows users, your home directory can be
+found by typing:</p>
+<pre class="literal-block">
+ECHO %HOMEDRIVE%%HOMEPATH%
+</pre>
+<p class="last">into a <a class="reference external" href="../../../more/getting_started/windows.html#command-prompt">command prompt</a> window.</p>
+</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="get-debug-build" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id20">[7]</a></td><td>On Unix and similar platforms, a debugging
+python and associated libraries are built by adding
+<tt class="docutils literal"><span class="pre">--with-pydebug</span></tt> when configuring the Python build. On
+Windows, the debugging version of Python is generated by
+the &quot;Win32 Debug&quot; target of the Visual Studio project in the
+PCBuild subdirectory of a full Python source code distribution.
+</td></tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="footer">
+<hr class="footer" />
+<a class="reference external" href="./building.rst">View document source</a>.
+Generated on: 2007-07-02 13:46 UTC.
+Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/building.rst b/libs/python/doc/building.rst
new file mode 100644
index 000000000..1e2c7d42f
--- /dev/null
+++ b/libs/python/doc/building.rst
@@ -0,0 +1,680 @@
+.. Copyright David Abrahams 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at
+.. http://www.boost.org/LICENSE_1_0.txt)
+
+==============================================
+ |(logo)|__ Boost.Python Build and Test HOWTO
+==============================================
+
+.. |(logo)| image:: ../../../boost.png
+ :alt: Boost C++ Libraries:
+ :class: boost-logo
+
+__ ../index.html
+
+
+.. section-numbering::
+ :depth: 2
+
+.. contents:: Contents
+ :depth: 2
+ :class: sidebar small
+
+.. |newer| replace:: *newer*
+
+Requirements
+============
+
+Boost.Python requires `Python 2.2`_ [#2.2]_ *or* |newer|__.
+
+.. _Python 2.2: http://www.python.org/2.2
+__ http://www.python.org
+
+Background
+==========
+
+There are two basic models for combining C++ and Python:
+
+- extending_, in which the end-user launches the Python interpreter
+ executable and imports Python “extension modules†written in C++.
+ Think of taking a library written in C++ and giving it a Python
+ interface so Python programmers can use it. From Python, these
+ modules look just like regular Python modules.
+
+- embedding_, in which the end-user launches a program written
+ in C++ that in turn invokes the Python interpreter as a library
+ subroutine. Think of adding scriptability to an existing
+ application.
+
+.. _extending: http://www.python.org/doc/current/ext/intro.html
+.. _embedding: http://www.python.org/doc/current/ext/embedding.html
+
+The key distinction between extending and embedding is the location
+of the C++ ``main()`` function: in the Python interpreter executable,
+or in some other program, respectively. Note that even when
+embedding Python in another program, `extension modules are often
+the best way to make C/C++ functionality accessible to Python
+code`__, so the use of extension modules is really at the heart of
+both models.
+
+__ http://www.python.org/doc/current/ext/extending-with-embedding.html
+
+Except in rare cases, extension modules are built as
+dynamically-loaded libraries with a single entry point, which means
+you can change them without rebuilding either the other extension
+modules or the executable containing ``main()``.
+
+.. _quickstart:
+
+No-Install Quickstart
+=====================
+
+There is no need to “install Boost†in order to get started using
+Boost.Python. These instructions use Boost.Build_ projects,
+which will build those binaries as soon as they're needed. Your
+first tests may take a little longer while you wait for
+Boost.Python to build, but doing things this way will save you from
+worrying about build intricacies like which library binaries to use
+for a specific compiler configuration and figuring out the right
+compiler options to use yourself.
+
+.. .. raw:: html
+
+ <div style="width:50%">
+
+.. Note:: Of course it's possible to use other build systems to
+ build Boost.Python and its extensions, but they are not
+ officially supported by Boost. Moreover **99% of all “I can't
+ build Boost.Python†problems come from trying to use another
+ build system** without first following these instructions.
+
+ If you want to use another system anyway, we suggest that you
+ follow these instructions, and then invoke ``bjam`` with the
+
+ .. parsed-literal::
+
+ ``-a -o``\ *filename*
+
+ options to dump the build commands it executes to a file, so
+ you can see what your alternate build system needs to do.
+
+.. .. raw:: html
+
+ </div>
+
+.. _Boost.Build: ../../../tools/build/index.html
+
+Basic Procedure
+---------------
+
+1. Get Boost; see sections 1 and 2 [`Unix/Linux`__, `Windows`__\ ] of the
+ Boost `Getting Started Guide`_.
+
+ __ ../../../more/getting_started/unix-variants.html#get-boost
+ __ ../../../more/getting_started/windows.html#get-boost
+
+2. Get the ``bjam`` build driver. See section 5 [`Unix/Linux`__,
+ `Windows`__\ ] of the Boost `Getting Started Guide`_.
+
+ __ ../../../more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary
+ __ ../../../more/getting_started/windows.html#prepare-to-use-a-boost-library-binary
+
+
+3. cd into the ``libs/python/example/quickstart/`` directory of your
+ Boost installation, which contains a small example project.
+
+4. Invoke ``bjam``. Replace the “\ ``stage``\ “ argument from the
+ example invocation from section 5 of the `Getting Started
+ Guide`_ with “\ ``test``\ ,“ to build all the test targets. Also add
+ the argument “\ ``--verbose-test``\ †to see the output generated by
+ the tests when they are run.
+
+ On Windows, your ``bjam`` invocation might look something like:
+
+ .. parsed-literal::
+
+ C:\\boost_1_34_0\\…\\quickstart> **bjam toolset=msvc --verbose-test test**
+
+ and on Unix variants, perhaps,
+
+ .. parsed-literal::
+
+ ~/boost_1_34_0/…/quickstart$ **bjam toolset=gcc --verbose-test test**
+
+.. Admonition:: Note to Windows Users
+
+ For the sake of concision, the rest of this guide will use
+ unix-style forward slashes in pathnames instead of the
+ backslashes with which you may be more familiar. The forward
+ slashes should work everywhere except in `Command Prompt`_
+ windows, where you should use backslashes.
+
+ .. _Command Prompt: ../../../more/getting_started/windows.html#command-prompt
+
+If you followed this procedure successfully, you will have built an
+extension module called ``extending`` and tested it by running a
+Python script called ``test_extending.py``. You will also have
+built and run a simple application called ``embedding`` that embeds
+python.
+
+.. _Getting Started Guide: ../../../more/getting_started/index.html
+
+In Case of Trouble
+------------------
+
+If you're seeing lots of compiler and/or linker error messages,
+it's probably because Boost.Build is having trouble finding your
+Python installation. You might want to pass the
+``--debug-configuration`` option to ``bjam`` the first few times
+you invoke it, to make sure that Boost.Build is correctly locating
+all the parts of your Python installation. If it isn't, consider
+`Configuring Boost.Build`_ as detailed below.
+
+If you're still having trouble, Someone on one of the following
+mailing lists may be able to help:
+
+* The `Boost.Build mailing list`__ for issues related to Boost.Build
+* The Python `C++ Sig`__ for issues specifically related to Boost.Python
+
+__ http://www.boost.org/more/mailing_lists.htm#jamboost
+__ http://www.boost.org/more/mailing_lists.htm#cplussig
+
+In Case Everything Seemed to Work
+---------------------------------
+
+Rejoice! If you're new to Boost.Python, at this point it might be
+a good idea to ignore build issues for a while and concentrate on
+learning the library by going through the tutorial_ and perhaps
+some of the `reference documentation`_, trying out what you've
+learned about the API by modifying the quickstart project.
+
+.. _reference documentation: v2/reference.html
+.. _tutorial: tutorial/index.html
+
+Modifying the Example Project
+-----------------------------
+
+If you're content to keep your extension module forever in one
+source file called |extending.cpp|_, inside your Boost
+distribution, and import it forever as ``extending``, then you can
+stop here. However, it's likely that you will want to make a few
+changes. There are a few things you can do without having to learn
+Boost.Build_ in depth.
+
+The project you just built is specified in two files in the current
+directory: |boost-build.jam|_, which tells ``bjam`` where it can
+find the interpreted code of the Boost build system, and
+|Jamroot|_, which describes the targets you just built. These
+files are heavily commented, so they should be easy to modify.
+Take care, however, to preserve whitespace. Punctuation such as
+``;`` will not be recognized as intended by ``bjam`` if it is not
+surrounded by whitespace.
+
+.. |boost-build.jam| replace:: ``boost-build.jam``
+.. _boost-build.jam: ../example/quickstart/boost-build.jam
+
+.. |Jamroot| replace:: ``Jamroot``
+.. _Jamroot: ../example/quickstart/Jamroot
+
+.. |extending.cpp| replace:: ``extending.cpp``
+.. _extending.cpp: ../example/quickstart/extending.cpp
+
+Relocate the Project
+....................
+
+You'll probably want to copy this project elsewhere so you can
+change it without modifying your Boost distribution. To do that,
+simply
+
+a. copy the entire ``libs/python/example/quickstart/`` directory
+ into a new directory.
+
+b. In the new copies of |boost-build.jam|_ and |Jamroot|_, locate
+ the relative path near the top of the file that is clearly
+ marked by a comment, and edit that path so that it refers to the
+ same directory your Boost distribution as it referred to when
+ the file was in its original location in the
+ ``libs/python/example/quickstart/`` directory.
+
+For example, if you moved the project from
+``/home/dave/boost_1_34_0/libs/python/example/quickstart`` to
+``/home/dave/my-project``, you could change the first path in
+|boost-build.jam|_ from
+
+.. parsed-literal::
+
+ **../../../..**\ /tools/build/v2
+
+to
+
+.. parsed-literal::
+
+ **/home/dave/boost_1_34_0**\ /tools/build/v2
+
+and change the first path in |Jamroot|_ from
+
+.. parsed-literal::
+
+ **../../../..**
+
+to
+
+.. parsed-literal::
+
+ **/home/dave/boost_1_34_0**
+
+Add New or Change Names of Existing Source Files
+................................................
+
+The names of additional source files involved in building your
+extension module or embedding application can be listed in
+|Jamroot|_ right alongside ``extending.cpp`` or ``embedding.cpp``
+respectively. Just be sure to leave whitespace around each
+filename::
+
+ … file1.cpp file2.cpp file3.cpp …
+
+Naturally, if you want to change the name of a source file you can
+tell Boost.Build about it by editing the name in |Jamroot|_.
+
+Change the Name of your Extension Module
+........................................
+
+The name of the extension module is determined by two things:
+
+1. the name in |Jamroot|_ immediately following ``python-extension``, and
+2. the name passed to ``BOOST_PYTHON_MODULE`` in |extending.cpp|_.
+
+To change the name of the extension module from ``extending`` to
+``hello``, you'd edit |Jamroot|_, changing
+
+.. parsed-literal::
+
+ python-extension **extending** : extending.cpp ;
+
+to
+
+.. parsed-literal::
+
+ python-extension **hello** : extending.cpp ;
+
+and you'd edit extending.cpp, changing
+
+.. parsed-literal::
+
+ BOOST_PYTHON_MODULE(\ **extending**\ )
+
+to
+
+.. parsed-literal::
+
+ BOOST_PYTHON_MODULE(\ **hello**\ )
+
+Installing Boost.Python on your System
+======================================
+
+Since Boost.Python is a separately-compiled (as opposed to
+`header-only`_) library, its user relies on the services of a
+Boost.Python library binary.
+
+.. _header-only: ../../../more/getting_started/windows.html#header-only-libraries
+
+If you need a regular installation of the Boost.Python library
+binaries on your system, the Boost `Getting Started Guide`_ will
+walk you through the steps of creating one. If building binaries
+from source, you might want to supply the ``--with-python``
+argument to ``bjam`` (or the ``--with-libraries=python`` argument
+to ``configure``), so only the Boost.Python binary will be built,
+rather than all the Boost binaries.
+
+
+Configuring Boost.Build
+=======================
+
+As described in the `Boost.Build reference manual`__, a file called
+``user-config.jam`` in your home directory [#home-dir]_ is used to
+specify the tools and libraries available to the build system. You
+may need to create or edit ``user-config.jam`` to tell Boost.Build
+how to invoke Python, ``#include`` its headers, and link with its
+libraries.
+
+__ http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration
+
+.. Admonition:: Users of Unix-Variant OSes
+
+ If you are using a unix-variant OS and you ran Boost's
+ ``configure`` script, it may have generated a
+ ``user-config.jam`` for you. [#overwrite]_ If your ``configure``\
+ /\ ``make`` sequence was successful and Boost.Python binaries
+ were built, your ``user-config.jam`` file is probably already
+ correct.
+
+If you have one fairly “standard†python installation for your
+platform, you might not need to do anything special to describe it. If
+you haven't configured python in ``user-config.jam`` (and you don't
+specify ``--without-python`` on the Boost.Build command line),
+Boost.Build will automatically execute the equivalent of ::
+
+ import toolset : using ;
+ using python ;
+
+which automatically looks for Python in the most likely places.
+However, that only happens when using the Boost.Python project file
+(e.g. when referred to by another project as in the quickstart_
+method). If instead you are linking against separately-compiled
+Boost.Python binaries, you should set up a ``user-config.jam`` file
+with at least the minimal incantation above.
+
+Python Configuration Parameters
+-------------------------------
+
+If you have several versions of Python installed, or Python is
+installed in an unusual way, you may want to supply any or all of
+the following optional parameters to ``using python``.
+
+version
+ the version of Python to use. Should be in Major.Minor
+ format, for example, ``2.3``. Do not include the subminor
+ version (i.e. *not* ``2.5.1``). If you have multiple Python
+ versions installed, the version will usually be the only
+ configuration argument required.
+
+cmd-or-prefix
+ preferably, a command that invokes a Python interpreter.
+ Alternatively, the installation prefix for Python libraries and
+ header files. Only use the alternative formulation if there is
+ no appropriate Python executable available.
+
+includes
+ the ``#include`` paths for Python headers. Normally the correct
+ path(s) will be automatically deduced from ``version`` and/or
+ ``cmd-or-prefix``.
+
+libraries
+ the path to Python library binaries. On MacOS/Darwin,
+ you can also pass the path of the Python framework. Normally the
+ correct path(s) will be automatically deduced from ``version``
+ and/or ``cmd-or-prefix``.
+
+condition
+ if specified, should be a set of Boost.Build
+ properties that are matched against the build configuration when
+ Boost.Build selects a Python configuration to use. See examples
+ below for details.
+
+extension-suffix
+ A string to append to the name of extension
+ modules before the true filename extension. You almost certainly
+ don't need to use this. Usually this suffix is only used when
+ targeting a Windows debug build of Python, and will be set
+ automatically for you based on the value of the
+ |python-debugging|_ feature. However, at least one Linux
+ distribution (Ubuntu Feisty Fawn) has a specially configured
+ `python-dbg`__ package that claims to use such a suffix.
+
+.. |python-debugging| replace:: ``<python-debugging>``
+
+__ https://wiki.ubuntu.com/PyDbgBuilds
+
+
+Examples
+--------
+
+Note that in the examples below, case and *especially whitespace* are
+significant.
+
+- If you have both python 2.5 and python 2.4 installed,
+ ``user-config.jam`` might contain::
+
+ using python : 2.5 ; # Make both versions of Python available
+
+ using python : 2.4 ; # To build with python 2.4, add python=2.4
+ # to your command line.
+
+ The first version configured (2.5) becomes the default. To build
+ against python 2.4, add ``python=2.4`` to the ``bjam`` command line.
+
+- If you have python installed in an unusual location, you might
+ supply the path to the interpreter in the ``cmd-or-prefix``
+ parameter::
+
+ using python : : /usr/local/python-2.6-beta/bin/python ;
+
+- If you have a separate build of Python for use with a particular
+ toolset, you might supply that toolset in the ``condition``
+ parameter::
+
+ using python ; # use for most toolsets
+
+ # Use with Intel C++ toolset
+ using python
+ : # version
+ : c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
+ : # includes
+ : # libraries
+ : <toolset>intel # condition
+ ;
+
+
+- If you have downloaded the Python sources and built both the
+ normal and the “\ `python debugging`_\ †builds from source on
+ Windows, you might see::
+
+ using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
+ using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
+ : # includes
+ : # libs
+ : <python-debugging>on ;
+
+- You can set up your user-config.jam so a bjam built under Windows
+ can build/test both Windows and Cygwin_ python extensions. Just pass
+ ``<target-os>cygwin`` in the ``condition`` parameter
+ for the cygwin python installation::
+
+ # windows installation
+ using python ;
+
+ # cygwin installation
+ using python : : c:\\cygwin\\bin\\python2.5 : : : <target-os>cygwin ;
+
+ when you put target-os=cygwin in your build request, it should build
+ with the cygwin version of python: [#flavor]_
+
+ bjam target-os=cygwin toolset=gcc
+
+ This is supposed to work the other way, too (targeting windows
+ python with a Cygwin_ bjam) but it seems as though the support in
+ Boost.Build's toolsets for building that way is broken at the
+ time of this writing.
+
+- Note that because of `the way Boost.Build currently selects target
+ alternatives`__, you might have be very explicit in your build
+ requests. For example, given::
+
+ using python : 2.5 ; # a regular windows build
+ using python : 2.4 : : : : <target-os>cygwin ;
+
+ building with ::
+
+ bjam target-os=cygwin
+
+ will yield an error. Instead, you'll need to write::
+
+ bjam target-os=cygwin/python=2.4
+
+.. _Cygwin: http://cygwin.com
+
+__ http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection
+
+Choosing a Boost.Python Library Binary
+======================================
+
+If—instead of letting Boost.Build construct and link with the right
+libraries automatically—you choose to use a pre-built Boost.Python
+library, you'll need to think about which one to link with. The
+Boost.Python binary comes in both static and dynamic flavors. Take
+care to choose the right flavor for your application. [#naming]_
+
+The Dynamic Binary
+------------------
+
+The dynamic library is the safest and most-versatile choice:
+
+- A single copy of the library code is used by all extension
+ modules built with a given toolset. [#toolset-specific]_
+
+- The library contains a type conversion registry. Because one
+ registry is shared among all extension modules, instances of a
+ class exposed to Python in one dynamically-loaded extension
+ module can be passed to functions exposed in another such module.
+
+The Static Binary
+-----------------
+
+It might be appropriate to use the static Boost.Python library in
+any of the following cases:
+
+- You are extending_ python and the types exposed in your
+ dynamically-loaded extension module don't need to be used by any
+ other Boost.Python extension modules, and you don't care if the
+ core library code is duplicated among them.
+
+- You are embedding_ python in your application and either:
+
+ - You are targeting a Unix variant OS other than MacOS or AIX,
+ where the dynamically-loaded extension modules can “see†the
+ Boost.Python library symbols that are part of the executable.
+
+ - Or, you have statically linked some Boost.Python extension
+ modules into your application and you don't care if any
+ dynamically-loaded Boost.Python extension modules are able to
+ use the types exposed by your statically-linked extension
+ modules (and vice-versa).
+
+``#include`` Issues
+===================
+
+1. If you should ever have occasion to ``#include "python.h"``
+ directly in a translation unit of a program using Boost.Python,
+ use ``#include "boost/python/detail/wrap_python.hpp"`` instead.
+ It handles several issues necessary for use with Boost.Python,
+ one of which is mentioned in the next section.
+
+2. Be sure not to ``#include`` any system headers before
+ ``wrap_python.hpp``. This restriction is actually imposed by
+ Python, or more properly, by Python's interaction with your
+ operating system. See
+ http://docs.python.org/ext/simpleExample.html for details.
+
+.. _python-debugging:
+.. _python debugging:
+
+Python Debugging Builds
+=======================
+
+Python can be built in a special “python debugging†configuration
+that adds extra checks and instrumentation that can be very useful
+for developers of extension modules. The data structures used by
+the debugging configuration contain additional members, so **a
+Python executable built with python debugging enabled cannot be
+used with an extension module or library compiled without it, and
+vice-versa.**
+
+Since pre-built “python debugging†versions of the Python
+executable and libraries are not supplied with most distributions
+of Python, [#get-debug-build]_ and we didn't want to force our users
+to build them, Boost.Build does not automatically enable python
+debugging in its ``debug`` build variant (which is the default).
+Instead there is a special build property called
+``python-debugging`` that, when used as a build property, will
+define the right preprocessor symbols and select the right
+libraries to link with.
+
+On unix-variant platforms, the debugging versions of Python's data
+structures will only be used if the symbol ``Py_DEBUG`` is defined.
+On many windows compilers, when extension modules are built with
+the preprocessor symbol ``_DEBUG``, Python defaults to force
+linking with a special debugging version of the Python DLL. Since
+that symbol is very commonly used even when Python is not present,
+Boost.Python temporarily undefines _DEBUG when Python.h
+is #included from ``boost/python/detail/wrap_python.hpp`` - unless
+``BOOST_DEBUG_PYTHON`` is defined. The upshot is that if you want
+“python debuggingâ€and you aren't using Boost.Build, you should make
+sure ``BOOST_DEBUG_PYTHON`` is defined, or python debugging will be
+suppressed.
+
+Testing Boost.Python
+====================
+
+To run the full test suite for Boost.Python, invoke ``bjam`` in the
+``libs/python/test`` subdirectory of your Boost distribution.
+
+Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users
+=======================================================
+
+If you are using a version of Python prior to 2.4.1 with a MinGW
+prior to 3.0.0 (with binutils-2.13.90-20030111-1), 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.
+
+__ http://www.python.org/doc/current/inst/index.html
+
+-----------------------------
+
+.. [#2.2] Note that although we tested earlier versions of
+ Boost.Python with Python 2.2, and we don't *think* we've done
+ anything to break compatibility, this release of Boost.Python
+ may not have been tested with versions of Python earlier than
+ 2.4, so we're not 100% sure that python 2.2 and 2.3 are
+ supported.
+
+.. [#naming] Information about how to identify the
+ static and dynamic builds of Boost.Python:
+
+ * `on Windows`__
+ * `on Unix variants`__
+
+ __ ../../../more/getting_started/windows.html#library-naming
+ __ ../../../more/getting_started/unix-variants.html#library-naming
+
+.. [#toolset-specific] Because of the way most \*nix platforms
+ share symbols among dynamically-loaded objects, I'm not certain
+ that extension modules built with different compiler toolsets
+ will always use different copies of the Boost.Python library
+ when loaded into the same Python instance. Not using different
+ libraries could be a good thing if the compilers have compatible
+ ABIs, because extension modules built with the two libraries
+ would be interoperable. Otherwise, it could spell disaster,
+ since an extension module and the Boost.Python library would
+ have different ideas of such things as class layout. I would
+ appreciate someone doing the experiment to find out what
+ happens.
+
+.. [#overwrite] ``configure`` overwrites the existing
+ ``user-config.jam`` in your home directory
+ (if any) after making a backup of the old version.
+
+.. [#flavor] Note that the ``<target-os>cygwin`` feature is
+ different from the ``<flavor>cygwin`` subfeature of the ``gcc``
+ toolset, and you might need handle both explicitly if you also
+ have a MinGW GCC installed.
+
+.. [#home-dir] Windows users, your home directory can be
+ found by typing::
+
+ ECHO %HOMEDRIVE%%HOMEPATH%
+
+ into a `command prompt`_ window.
+
+.. [#get-debug-build] On Unix and similar platforms, a debugging
+ python and associated libraries are 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 Visual Studio project in the
+ PCBuild subdirectory of a full Python source code distribution.
diff --git a/libs/python/doc/index.html b/libs/python/doc/index.html
new file mode 100644
index 000000000..e600366fe
--- /dev/null
+++ b/libs/python/doc/index.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../../../boost.css">
+
+ <title>Boost.Python</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center">Boost.Python</h1>
+
+ <h2 align="center">Index</h2>
+ </td>
+
+
+ <td align="right">
+
+ <form method="get" action="http://www.google.com/custom">
+ <p>
+ <span id= "search-choice">
+ Search
+ <select name="hq" id="hq">
+ <option label="All Documentation" value=
+ "site:www.boost.org inurl:www.boost.org/libs/python/doc">
+ All Documentation
+ </option>
+ <option label="Tutorial" value=
+ "site:www.boost.org inurl:www.boost.org/libs/python/doc/tutorial">
+ Tutorial
+ </option>
+ <option label="Reference" value=
+ "site:www.boost.org inurl:www.boost.org/libs/python/doc/v2">
+ Reference
+ </option>
+ </select>
+ <br>
+ </span>
+
+ <span id="search-text">
+ <input type="text" name="q" id="q" size="31" maxlength="255" alt="Search Text" />
+ </span>
+
+ <br>
+ <span id= "google">
+ <a href= "http://www.google.com/search">
+ <img src="../../../more/google_logo_25wht.gif" alt="Google" border="0" /></a>Powered
+ </span>
+
+ <span id="go">
+ <input type="image" name="search" src="../../../more/space.gif" alt="Search" id="search-button" />
+ </span>
+
+ <br>
+ <input type="hidden" name="cof" value= "LW:277;L:http://www.boost.org/boost.png;LH:86;AH:center;GL:0;S:http://www.boost.org;AWFID:9b83d16ce652ed5a;" />
+ <input type="hidden" name="sa" value= "Google Search" />
+ <input type="hidden" name= "domains" value= "www.boost.org;mail.python.org" /></p>
+ </form>
+
+ </td>
+ </tr>
+<tr>
+
+ </tr>
+ </table>
+ <hr>
+
+
+ <h2>Synopsis</h2>
+ Welcome to version 2 of <b>Boost.Python</b>, a C++ library which enables
+ seamless interoperability between C++ and the <a href=
+ "http://www.python.org">Python</a> 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:
+
+ <ul>
+ <li>References and Pointers</li>
+
+ <li>Globally Registered Type Coercions</li>
+
+ <li>Automatic Cross-Module Type Conversions</li>
+
+ <li>Efficient Function Overloading</li>
+
+ <li>C++ to Python Exception Translation</li>
+
+ <li>Default Arguments</li>
+
+ <li>Keyword Arguments</li>
+
+ <li>Manipulating Python objects in C++</li>
+
+ <li>Exporting C++ Iterators as Python Iterators</li>
+
+ <li>Documentation Strings</li>
+ </ul>
+ The development of these features was funded in part by grants to <a
+ href="http://www.boost-consulting.com">Boost Consulting</a> from the <a
+ href="http://www.llnl.gov/">Lawrence Livermore National Laboratories</a>
+ and by the <a href="http://cci.lbl.gov/">Computational Crystallography
+ Initiative</a> at Lawrence Berkeley National Laboratories.
+
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="index">
+ <dt><a href="tutorial/index.html">Tutorial Introduction</a></dt>
+
+ <dt><a href="building.html">Building and Testing</a></dt>
+
+ <dt><a href="v2/reference.html">Reference Manual</a></dt>
+
+ <dt>Suites:</dt>
+ <dd>
+ <ul>
+ <li><a href="v2/pickle.html">Pickle</a></li>
+ <li><a href="v2/indexing.html">Indexing</a></li>
+ </ul>
+ </dd>
+
+ <dt><a href="v2/configuration.html">Configuration Information</a></dt>
+
+ <dt><a href="v2/platforms.html">Known Working Platforms and
+ Compilers</a></dt>
+
+ <dt><a href="v2/definitions.html">Definitions</a></dt>
+
+ <dt><a href="projects.html">Projects using Boost.Python</a></dt>
+
+ <dt><a href="support.html">Support Resources</a></dt>
+
+ <dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
+
+ <dt><a href="http://www.language-binding.net/pyplusplus/pyplusplus.html">Py++ Boost.Python code generator</a></dt>
+
+ <dt><a href="../pyste/index.html">Pyste Boost.Python code generator (no longer maintained)</a></dt>
+
+ <dt><a href="internals.html">Internals Documentation</a></dt>
+
+ <dt><a href="news.html">News/Change Log</a></dt>
+
+ <dt><a href="../todo.html">TODO list</a></dt>
+
+ <dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
+
+ <dt><a href="v2/acknowledgments.html">Acknowledgments</a></dt>
+ </dl>
+ <hr>
+
+ <h2>Articles</h2>
+
+ &quot;<a href="PyConDC_2003/bpl.html">Building Hybrid
+ Systems With Boost Python</a>&quot;, by Dave Abrahams and Ralf
+ W. Grosse-Kunstleve (<a href="PyConDC_2003/bpl.pdf">PDF</a>)
+
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 26 August, 2003
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002-2003.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/internals.html b/libs/python/doc/internals.html
new file mode 100644
index 000000000..2f7d76070
--- /dev/null
+++ b/libs/python/doc/internals.html
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
+<title>Boost.Python Internals Boost</title>
+<link rel="stylesheet" href="../../../rst.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="boost-python-internals-logo">
+<h1 class="title"><a class="reference" href="index.html">Boost.Python</a> Internals <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../boost.png" /></a></h1>
+<div class="section" id="a-conversation-between-brett-calcott-and-david-abrahams">
+<h1><a name="a-conversation-between-brett-calcott-and-david-abrahams">A conversation between Brett Calcott and David Abrahams</a></h1>
+<table class="field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams and Brett Calcott 2003. See
+accompanying <a class="reference" href="../../../LICENSE_1_0.txt">license</a> for terms of use.</td>
+</tr>
+</tbody>
+</table>
+<p>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).</p>
+<ol class="arabic">
+<li><p class="first">What happens when you do the following:</p>
+<pre class="literal-block">
+struct boring {};
+...etc...
+class_&lt;boring&gt;(&quot;boring&quot;)
+ ;
+</pre>
+</li>
+</ol>
+<p>There seems to be a fair bit going on.</p>
+<blockquote>
+<ul class="simple">
+<li>Python needs a new ClassType to be registered.</li>
+<li>We need to construct a new type that can hold our boring struct.</li>
+<li>Inward and outward converters need to be registered for the type.</li>
+</ul>
+</blockquote>
+<p>Can you gesture in the general direction where these things are done?</p>
+<blockquote>
+<p>I only have time for a &quot;off-the-top-of-my-head&quot; 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.</p>
+<blockquote>
+<p>A new (Python) subclass of Boost.Python.Instance (see
+libs/python/src/object/class.cpp) is created by invoking
+Boost.Python.class, the metatype:</p>
+<pre class="literal-block">
+&gt;&gt;&gt; boring = Boost.Python.class(
+... 'boring'
+... , bases_tuple # in this case, just ()
+... , {
+... '__module__' : module_name
+... , '__doc__' : doc_string # optional
+... }
+... )
+</pre>
+<p>A handle to this object is stuck in the m_class_object field
+of the registration associated with <tt class="literal"><span class="pre">typeid(boring)</span></tt>. 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).</p>
+<p>Because you didn't specify <tt class="literal"><span class="pre">class&lt;boring,</span> <span class="pre">non_copyable,</span>
+<span class="pre">...&gt;</span></tt>, a to-python converter for boring is registered which
+copies its argument into a value_holder held by the the
+Python boring object.</p>
+<p>Because you didn't specify <tt class="literal"><span class="pre">class&lt;boring</span> <span class="pre">...&gt;(no_init)</span></tt>,
+an <tt class="literal"><span class="pre">__init__</span></tt> 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.</p>
+<p><tt class="literal"><span class="pre">register_class_from_python</span></tt> is used to register a
+from-python converter for <tt class="literal"><span class="pre">shared_ptr&lt;boring&gt;</span></tt>.
+<tt class="literal"><span class="pre">boost::shared_ptr</span></tt>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.</p>
+<p>If there were any <tt class="literal"><span class="pre">bases&lt;&gt;</span></tt>, we'd also be registering the
+relationship between these base classes and boring in the
+up/down cast graph (<tt class="literal"><span class="pre">inheritance.[hpp/cpp]</span></tt>).</p>
+<p>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.</p>
+<p>Hmm, that from-python converter probably ought to be handled
+the way class converters are, with no explicit conversions
+registered.</p>
+</blockquote>
+</blockquote>
+<ol class="arabic" start="2">
+<li><p class="first">Can you give a brief overview of the data structures that are
+present in the registry</p>
+<blockquote>
+<p>The registry is simple: it's just a map from typeid -&gt;
+registration (see boost/python/converter/registrations.hpp).
+<tt class="literal"><span class="pre">lvalue_chain</span></tt> and <tt class="literal"><span class="pre">rvalue_chain</span></tt> are simple endogenous
+linked lists.</p>
+<p>If you want to know more, just ask.</p>
+<p>If you want to know about the cast graph, ask me something specific in
+a separate message.</p>
+</blockquote>
+<p>and an overview of the process that happens as a type makes its
+way from c++ to python and back again.</p>
+</li>
+</ol>
+<blockquote>
+<p>Big subject. I suggest some background reading: look for relevant
+info in the LLNL progress reports and the messages they link to.
+Also,</p>
+<blockquote>
+<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a></p>
+<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-December/003115.html">http://mail.python.org/pipermail/c++-sig/2002-December/003115.html</a></p>
+<p><a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1280898">http://aspn.activestate.com/ASPN/Mail/Message/1280898</a></p>
+<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-July/001755.html">http://mail.python.org/pipermail/c++-sig/2002-July/001755.html</a></p>
+</blockquote>
+<p>from c++ to python:</p>
+<blockquote>
+<p>It depends on the type and the call policies in use or, for
+<tt class="literal"><span class="pre">call&lt;&gt;(...)</span></tt>, <tt class="literal"><span class="pre">call_method&lt;&gt;(...)</span></tt>, or <tt class="literal"><span class="pre">object(...)</span></tt>, if
+<tt class="literal"><span class="pre">ref</span></tt> or <tt class="literal"><span class="pre">ptr</span></tt> is used. There are also two basic
+categories to to-python conversion, &quot;return value&quot; conversion
+(for Python-&gt;C++ calls) and &quot;argument&quot; conversion (for
+C++-&gt;Python calls and explicit <tt class="literal"><span class="pre">object()</span></tt> 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.</p>
+<p>The &quot;default&quot; case is by-value (copying) conversion, which uses
+to_python_value as a to-python converter.</p>
+<blockquote>
+<p>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.</p>
+<p>Otherwise, to_python_value uses the <tt class="literal"><span class="pre">m_to_python</span></tt>
+function in the registration for the C++ type.</p>
+</blockquote>
+<p>Other conversions, like by-reference conversions, are only
+available for wrapped classes, and are requested explicitly by
+using <tt class="literal"><span class="pre">ref(...)</span></tt>, <tt class="literal"><span class="pre">ptr(...)</span></tt>, 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.</p>
+</blockquote>
+<p>from python to C++:</p>
+<blockquote>
+<p>Once again I think there is a distinction between &quot;return value&quot;
+and &quot;argument&quot; conversions, and I forget exactly what that is.</p>
+<p>What happens depends on whether an lvalue conversion is needed
+(see <a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a>)
+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.</p>
+<p>An lvalue conversion can be done in one step (just get me the
+pointer to the object - it can be <tt class="literal"><span class="pre">NULL</span></tt> 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.</p>
+</blockquote>
+</blockquote>
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="internals.rst">View document source</a>.
+Generated on: 2003-09-12 14:51 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/internals.rst b/libs/python/doc/internals.rst
new file mode 100644
index 000000000..2438d5ffb
--- /dev/null
+++ b/libs/python/doc/internals.rst
@@ -0,0 +1,182 @@
+===================================
+ Boost.Python_ Internals |(logo)|__
+===================================
+
+.. |(logo)| image:: ../../../boost.png
+ :alt: Boost
+ :class: boost-logo
+
+__ ../../../index.htm
+
+.. _`Boost.Python`: index.html
+
+.. _license: ../../../LICENSE_1_0.txt
+
+
+-------------------------------------------------------
+A conversation between Brett Calcott and David Abrahams
+-------------------------------------------------------
+
+:copyright: Copyright David Abrahams and Brett Calcott 2003. See
+ accompanying license_ for terms of use.
+
+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")
+ ;
+
+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_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/libs/python/doc/news.html b/libs/python/doc/news.html
new file mode 100644
index 000000000..da57caeb3
--- /dev/null
+++ b/libs/python/doc/news.html
@@ -0,0 +1,371 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st September 2004), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="boost.css">
+
+ <title>Boost.Python - News/Change Log</title>
+</head>
+
+<body link="#0000FF" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="index.html">Boost.Python</a></h1>
+
+ <h2 align="center">News/Change Log</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <dl class="page-index">
+
+ <dt>Current SVN</dt>
+ <dd>
+ <ul>
+ <li>Python 3 support:</li>
+ <ul>
+ <li>All the current Boost.Python test cases passed. Extension modules using
+ Boost.Python expected to support Python 3 smoothly.</li>
+ <li>Introduced <code>object.contains</code> where <code>x.contains(y)</code>
+ is equivalent to Python code <code>y in x</code>.
+ Now <code>dict.has_key</code> is just a wrapper of <code>object.contains</code>.
+ </li>
+ <li>When building against Python 3, <code>str.decode</code> will be removed.</li>
+ <li>When building against Python 3, the original signature of <code>list.sort</code>, which is:
+ <pre>void sort(object_cref cmpfunc);</pre>
+ will change to:
+ <pre>void sort(args_proxy const &args, kwds_proxy const &kwds);</pre>
+
+ This is because in Python 3 <code>list.sort</code> requires all its arguments be keyword arguments.
+ So you should call it like this:
+ <pre>x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));</pre>
+
+ </li>
+ <li>According to <a href="http://www.python.org/dev/peps/pep-3123/">PEP 3123</a>,
+ when building Boost.Python against Python older than 2.6, the following macros will
+ be defined in Boost.Python header:
+ <pre>
+# define Py_TYPE(o) (((PyObject*)(o))->ob_type)
+# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt)
+# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size)</pre>
+ So extension writers can use these macro directly, to make code clean and compatible with Python 3.
+ </li>
+ </ul>
+ </ul>
+ </dd>
+
+ <dt>1.39.0 Release</dt>
+
+ <dd>
+ <ul>
+ <li>Pythonic signatures are now automatically appended to the
+ docstrings.
+
+ <li>Use <a href="v2/docstring_options.html"
+ ><code>docstring_options.hpp</code></a> header
+ control the content of docstrings.
+
+ <li>This new feature increases the size of the modules by about 14%.
+ If this is not acceptable it can be turned off by defining the macro
+ BOOST_PYTHON_NO_PY_SIGNATURES. Modules compiled with and without the macro
+ defined are compatible.
+ </li>
+ <li> If BOOST_PYTHON_NO_PY_SIGNATURES is undefined, this version defines the
+ macro BOOST_PYTHON_SUPPORTS_PY_SIGNATURES. This allows writing code that will compile
+ with older version of Boost.Python (see <a href="v2/pytype_function.html#examples">here</a>).
+ </li>
+ <li>By defining BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE, and at a cost
+ of another 14% size increase, proper pythonic type is generated for the "self"
+ parameter of the __init__ methods.
+ </li>
+
+ <li> To support this new feature changes were made to the
+ <a href="v2/to_python_converter.html"><code>to_python_converter.hpp</code></a>,
+ <a href="v2/default_call_policies.html"><code>default_call_policies</code></a>,
+ <a href="v2/ResultConverter.html"><code>ResultConverter</code></a>,
+ <a href="v2/CallPolicies.html"><code>CallPolicies</code></a> and some others.
+ Efforts were made not to have interface breaking changes.
+ </li>
+
+ </ul>
+ </dd>
+
+ <dt>12 May 2007 - 1.34.0 release</dt>
+
+ <dd>
+ <ul>
+ <li>C++ signatures are now automatically appended to the
+ docstrings.
+
+ <li>New <a href="v2/docstring_options.html"
+ ><code>docstring_options.hpp</code></a> header to
+ control the content of docstrings.
+
+ <li>Support for converting <code>void*</code> to/from python,
+ with <code><a
+ href="v2/opaque.html">opaque_pointer_converter</a></code>
+ as the return value policy. Thanks to Niall Douglas for the
+ initial patch.
+ </ul>
+ </dd>
+
+ <dt>19 October 2005 - 1.33.1 release</dt>
+
+ <dd>
+ <ul>
+ <li><code>wrapper&lt;T&gt;</code> can now be used as expected with a
+ held type of <i>some-smart-pointer</i><code>&lt;T&gt;</code></li>
+
+ <li>The build now assumes Python 2.4 by default, rather than 2.2</li>
+
+ <li>Support Python that's built without Unicode support</li>
+
+ <li>Support for wrapping classes with overloaded address-of
+ (<code>&amp;</code>) operators</li>
+ </ul>
+ </dd>
+
+ <dt>14 August 2005 - 1.33 release</dt>
+
+ <dd>
+ <ul>
+ <li>Support for docstrings on nonstatic properties.</li>
+
+ <li>We now export the client-provided docstrings for
+ <code>init&lt;optional&lt;&gt; &gt;</code> and
+ <i>XXX</i><code>_FUNCTION_OVERLOADS()</code> for only the last
+ overload.</li>
+
+ <li>Fixed some support for Embedded VC++ 4</li>
+
+ <li>Better support for rvalue from-python conversions of shared_ptr:
+ always return a pointer that holds the owning python object *unless*
+ the python object contains a NULL shared_ptr holder of the right
+ type.</li>
+
+ <li>Support for exposing <code>vector&lt;T*&gt;</code> with the
+ indexing suite.</li>
+
+ <li>Support for GCC-3.3 on MacOS.</li>
+
+ <li>updated visual studio project build file to include two new files
+ (slice.cpp and wrapper.cpp)</li>
+
+ <li>Added search feature to the index page.</li>
+
+ <li>Numerous fixes to the tutorial</li>
+
+ <li>Numerous workarounds for MSVC 6 and 7, GCC 2.96, and EDG
+ 2.45</li>
+ </ul>
+ </dd>
+
+ <dt>11 March 2005</dt>
+
+ <dd>
+ <ul>
+ <li>Added a hack that will fool PyDoc into working with Boost.Python,
+ thanks to Nick Rasmussen</li>
+ </ul>
+ </dd>
+
+ <dt>19 November 2004 - 1.32 release</dt>
+
+ <dd>
+ <ul>
+ <li>Updated to use the Boost Software License.</li>
+
+ <li>A new, <a href=
+ "tutorial/doc/html/python/exposing.html#python.class_virtual_functions">
+ better method of wrapping classes with virtual functions</a> has been
+ implemented.</li>
+
+ <li>Support for upcoming GCC symbol export control features have been
+ folded in, thanks to Niall Douglas.</li>
+
+ <li>Improved support for <code>std::auto_ptr</code>-like types.</li>
+
+ <li>The Visual C++ bug that makes top-level <i>cv-qualification</i>
+ of function parameter types part of the function type has been worked
+ around.</li>
+
+ <li>Components used by other libraries have been moved out of
+ <code>python/detail</code> and into <code>boost/detail</code> to
+ improve dependency relationships.</li>
+
+ <li>Miscellaneous bug fixes and compiler workarounds.</li>
+ </ul>
+ </dd>
+
+ <dt>8 Sept 2004</dt>
+
+ <dd>Support for Python's Bool type, thanks to <a href=
+ "mailto:dholth-at-fastmail.fm">Daniel Holth</a>.</dd>
+
+ <dt>11 Sept 2003</dt>
+
+ <dd>
+ <ul>
+ <li>Changed the response to multiple to-python converters being
+ registered for the same type from a hard error into warning;
+ Boost.Python now reports the offending type in the message.</li>
+
+ <li>Added builtin <code>std::wstring</code> conversions</li>
+
+ <li>Added <code>std::out_of_range</code> =&gt; Python
+ <code>IndexError</code> exception conversion, thanks to <a href=
+ "mailto:RaoulGough-at-yahoo.co.uk">Raoul Gough</a></li>
+ </ul>
+ </dd>
+
+ <dt>9 Sept 2003</dt>
+
+ <dd>Added new <code><a href="v2/str.html#str-spec">str</a></code></dd>
+
+ <dt>constructors which take a range of characters, allowing strings
+ containing nul (<code>'\0'</code>) characters.</dt>
+
+ <dt>8 Sept 2003</dt>
+
+ <dd>Added the ability to create methods from function objects (with an
+ <code>operator()</code>); see the <a href=
+ "v2/make_function.html#make_function-spec">make_function</a> docs for
+ more info.</dd>
+
+ <dt>10 August 2003</dt>
+
+ <dd>Added the new <code>properties</code> unit tests contributed by
+ <a href="mailto:romany-at-actimize.com">Roman Yakovenko</a> and
+ documented <code>add_static_property</code> at his urging.</dd>
+
+ <dt>1 August 2003</dt>
+
+ <dd>
+ Added the new <code>arg</code> class contributed by <a href=
+ "mailto:nickm-at-sitius.com">Nikolay Mladenov</a> which supplies the
+ ability to wrap functions that can be called with ommitted arguments in
+ the middle:
+ <pre>
+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")));
+}
+
+</pre>And in Python:
+ <pre>
+&gt;&gt;&gt; import test
+&gt;&gt;&gt; f(0, z = "bar")
+&gt;&gt;&gt; f(z = "bar", y = 0.0)
+</pre>Thanks, Nikolay!
+ </dd>
+
+ <dt>22 July 2003</dt>
+
+ <dd>Killed the dreaded "bad argument type for builtin operation" error.
+ Argument errors now show the actual and expected argument types!</dd>
+
+ <dt>19 July 2003</dt>
+
+ <dd>Added the new <code><a href=
+ "v2/return_arg.html">return_arg</a></code> policy from <a href=
+ "mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks, Nikolay!</dd>
+
+ <dt>18 March, 2003</dt>
+
+ <dd><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
+ Gan&szlig;auge</a> has contributed <a href=
+ "v2/opaque.html">opaque pointer support</a>.<br>
+ <a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de
+ Oliveira</a> has contributed the exciting <a href=
+ "../pyste/index.html">Pyste</a> ("Pie-steh") package.</dd>
+
+ <dt>24 February 2003</dt>
+
+ <dd>Finished improved support for <code>boost::shared_ptr</code>. Now any
+ wrapped object of C++ class <code>X</code> can be converted automatically
+ to <code>shared_ptr&lt;X&gt;</code>, regardless of how it was wrapped.
+ The <code>shared_ptr</code> will manage the lifetime of the Python object
+ which supplied the <code>X</code>, rather than just the <code>X</code>
+ object itself, and when such a <code>shared_ptr</code> is converted back
+ to Python, the original Python object will be returned.</dd>
+
+ <dt>19 January 2003</dt>
+
+ <dd>Integrated <code>staticmethod</code> support from <a href=
+ "mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks, Nikolay!</dd>
+
+ <dt>29 December 2002</dt>
+
+ <dd>Added Visual Studio project file and instructions from Brett Calcott.
+ Thanks, Brett!</dd>
+
+ <dt>20 December 2002</dt>
+
+ <dd>Added automatic downcasting for pointers, references, and smart
+ pointers to polymorphic class types upon conversion to python</dd>
+
+ <dt>18 December 2002</dt>
+
+ <dd>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</dd>
+
+ <dt>19 November 2002</dt>
+
+ <dd>Removed the need for users to cast base class member function
+ pointers when used as arguments to <a href=
+ "v2/class.html#class_-spec-modifiers">add_property</a></dd>
+
+ <dt>13 December 2002</dt>
+
+ <dd>Allow exporting of <a href=
+ "v2/enum.html#enum_-spec"><code>enum_</code></a> values into enclosing
+ <a href="v2/scope.html#scope-spec"><code>scope</code></a>.<br>
+ Fixed unsigned integer conversions to deal correctly with numbers that
+ are out-of-range of <code>signed long</code>.</dd>
+
+ <dt>14 November 2002</dt>
+
+ <dd>Auto-detection of class data members wrapped with <a href=
+ "v2/data_members.html#make_getter-spec"><code>make_getter</code></a></dd>
+
+ <dt>13 November 2002</dt>
+
+ <dd>Full Support for <code>std::auto_ptr&lt;&gt;</code> added.</dd>
+
+ <dt>October 2002</dt>
+
+ <dd>Ongoing updates and improvements to tutorial documentation</dd>
+
+ <dt>10 October 2002</dt>
+
+ <dd>Boost.Python V2 is released!</dd>
+ </dl>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 19 November 2004
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002-2003.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/polymorphism.txt b/libs/python/doc/polymorphism.txt
new file mode 100644
index 000000000..38e2f6914
--- /dev/null
+++ b/libs/python/doc/polymorphism.txt
@@ -0,0 +1,222 @@
+.. Copyright David Abrahams 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at
+.. http://www.boost.org/LICENSE_1_0.txt)
+
+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<std::string>(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<T>::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/libs/python/doc/projects.html b/libs/python/doc/projects.html
new file mode 100644
index 000000000..05eb52326
--- /dev/null
+++ b/libs/python/doc/projects.html
@@ -0,0 +1,472 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st September 2004), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html">
+ <link rel="stylesheet" type="text/css" href="boost.css">
+
+ <title>Boost.Python - Projects using Boost.Python</title>
+</head>
+
+<body link="#0000FF" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Projects using Boost.Python</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Introduction</h2>
+
+ <p>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 <a href=
+ "mailto:c++-sig@python.org">post</a> a short description of your project
+ and how Boost.Python helps you get the job done, and we'll add it to this
+ page .</p>
+ <hr>
+
+ <h3>Data Analysis</h3>
+
+ <dl class="page-index">
+ <dt><b><a href="http://www.neuralynx.com">NeuraLab</a></b></dt>
+
+ <dd>Neuralab is a data analysis environment specifically tailored for
+ neural data from <a href="http://www.neuralynx.com">Neuralynx</a>
+ acquisition systems. Neuralab combines presentation quality graphics, a
+ numerical analysis library, and the <a href=
+ "http://www.python.org">Python</a> 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.</dd>
+ </dl>
+
+ <dl class="page-index">
+ <dt><b>TSLib</b> - <a href="http://www.fortressinv.com">Fortress
+ Investment Group LLC</a></dt>
+
+ <dd>
+ Fortress Investment Group has contracted <a href=
+ "http://www.boost-consulting.com">Boost Consulting</a> to develop core
+ internal financial analysis tools in C++ and to prepare Python bindings
+ for them using Boost.Python.
+
+ <p>Tom Barket of Fortress writes:</p>
+
+ <blockquote>
+ 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.
+ </blockquote>
+ </dd>
+ </dl>
+
+ <h3>Educational</h3>
+
+ <dl class="page-index">
+ <dt><a href="http://edu.kde.org/kig"><b>Kig</b></a></dt>
+
+ <dd>
+ <p>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.</p>
+
+ <p>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.</p>
+ </dd>
+ </dl>
+
+ <h3>Enterprise Software</h3>
+
+ <dl class="page-index">
+ <dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
+
+ <dd>
+ The OpenWBEM project is an effort to develop an open-source
+ implementation of Web Based Enterprise Management suitable for
+ commercial and non-commercial application
+
+ <p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
+
+ <blockquote>
+ 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.
+ </blockquote>
+ </dd>
+
+ <dt><b><a href="http://www.transversal.com">Metafaq</a></b></dt>
+
+ <dd>
+ Metafaq, from <a href="http://www.transversal.com">Transversal,
+ Inc.</a>, is an enterprise level online knowledge base management
+ system.
+
+ <p><a href="mailto:ben.young-at-transversal.com">Ben Young</a>
+ writes:</p>
+
+ <blockquote>
+ 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.
+ </blockquote>
+ </dd>
+ </dl>
+
+ <h3>Games</h3>
+
+ <dl>
+ <dt><b><a href="http://www.firaxis.com">Civilization IV</a></b></dt>
+ </dl>
+
+ <blockquote>
+ &ldquo;The fourth game in the PC strategy series that has sold over five
+ million copies, Sid Meier's Civilization IV is a bold step forward for
+ the franchise, with spectacular new 3D graphics and all-new single and
+ multiplayer content. Civilization IV will also set a new standard for
+ user-modification, allowing gamers to create their own add-ons using
+ Python and XML.
+
+ <p>Sid Meier's Civilization IV will be released for PC in late 2005. For
+ more information please visit <a href=
+ "http://www.firaxis.com">http://www.firaxis.com</a> or write <a href=
+ "mailto:kgilmore@firaxis.com">kgilmore@firaxis.com</a>&rdquo;</p>
+ </blockquote>
+
+ <p>Boost.Python is used as the interface layer between the C++ game code
+ and Python. Python is used for many purposes in the game, including map
+ generation, interface screens, game events, tools, tutorials, etc. Most
+ high-level game operations have been exposed to Python in order to give
+ modders the power they need to customize the game.</p>
+
+ <blockquote>
+ -Mustafa Thamer, Civ4 Lead Programmer
+ </blockquote>
+
+ <dl class="page-index">
+ <dt><b><a href="http://vegastrike.sourceforge.net">Vega
+ Strike</a></b></dt>
+
+ <dd>
+ <a href="http://vegastrike.sourceforge.net">Vega Strike</a> is the 3D
+ Space Simulator that allows you to trade and bounty hunt in a vast
+ universe. Players face dangers, decisions, piracy, and aliens.
+
+ <p><a href="http://vegastrike.sourceforge.net">Vega Strike</a> has
+ decided to base its scripting on python, using boost as the layer
+ between the class hierarchy in python and the class hierarchy in C++.
+ The result is a very flexible scripting system that treats units as
+ native python classes when designing missions or writing AI's.</p>
+
+ <p>A large economic and planetary simulation is currently being run in
+ the background in python and the results are returned back into C++ in
+ the form of various factions' spaceships appearing near worlds that
+ they are simulated to be near in python if the player is in the general
+ neighborhood.</p>
+ </dd>
+ </dl>
+
+ <h3>Graphics</h3>
+
+ <dl class="page-index">
+ <dt><b><a href="http://sourceforge.net/projects/pyosg">OpenSceneGraph
+ Bindings</a></b></dt>
+
+ <dd><a href="mailto:gideon@computer.org">Gideon May</a> has created a set
+ of bindings for <a href=
+ "http://www.openscenegraph.org">OpenSceneGraph</a>, a cross-platform
+ C++/OpenGL library for the real-time visualization.<br>
+ &nbsp;</dd>
+
+ <dt><b><a href=
+ "http://www.slac.stanford.edu/grp/ek/hippodraw/index.html">HippoDraw</a></b></dt>
+
+ <dd>
+ 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.
+
+ <p>Before the web page came online, <a href=
+ "mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a> wrote:</p>
+
+ <blockquote>
+ Don't have a web page for the project, but the organization's is
+ <a href=
+ "http://www.slac.stanford.edu">http://www.slac.stanford.edu</a> (the
+ first web server site in America, I installed it).
+ </blockquote>Which was just too cool a piece of trivia to omit.<br>
+ &nbsp;
+ </dd>
+
+ <dt><a href="http://www.iplt.org"><b>IPLT</b></a></dt>
+
+ <dd>
+ <a href="mailto:ansgar.philippsen-at-unibas.ch">Ansgar Philippsen</a>
+ writes:
+
+ <blockquote>
+ IPLT is an image processing library and toolbox for the structural
+ biology electron microscopy community. I would call it a
+ budding/evolving project, since it is currently not in production
+ stage, but rather under heavy development. Python is used as the main
+ scripting/interaction level, but also for rapid prototyping, since
+ the underlying C++ class library is pretty much fully exposed via
+ boost.python (at least the high-level interface). The combined power
+ of C++ and Python for this project turned out to be just awesome.
+ </blockquote><br>
+ &nbsp;
+ </dd>
+
+ <dt><a href=
+ "http://www.procoders.net/pythonmagick"><b>PythonMagick</b></a></dt>
+
+ <dd>PythonMagick binds the <a href=
+ "http://www.graphicsmagick.org">GraphicsMagick</a> image manipulation
+ library to Python.<br>
+ &nbsp;</dd>
+
+ <dt><a href="http://www.vpython.org"><b>VPython</b></a></dt>
+
+ <dd>
+ <a href="mailto:Bruce_Sherwood-at-ncsu.edu">Bruce Sherwood</a> writes:
+
+ <blockquote>
+ VPython is an extension for Python that makes it easy to create
+ navigable 3D animations, which are generated as a side effect of
+ computational code. VPython is used in education for various
+ purposes, including teaching physics and programming, but it has also
+ been used by research scientists to visualize systems or data in 3D.
+ </blockquote><br>
+ &nbsp;
+ </dd>
+ </dl>
+
+ <h3>Scientific Computing</h3>
+
+ <dl class="page index">
+ <dt><a href="http://camfr.sourceforge.net"><b>CAMFR</b></a></dt>
+
+ <dd>
+ CAMFR is a photonics and electromagnetics modelling tool. Python is
+ used for computational steering.
+
+ <p><a href="mailto:Peter.Bienstman@rug.ac.be">Peter Bienstman</a>
+ writes:</p>
+
+ <blockquote>
+ Thanks for providing such a great tool!
+ </blockquote>
+ </dd>
+
+ <dt><a href="http://cctbx.sourceforge.net"><b>cctbx - Computational
+ Crystallography Toolbox</b></a></dt>
+
+ <dd>
+ 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.
+
+ <p>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.</p>
+
+ <p>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 L-BFGS quasi-Newton minimizer.</p>
+ </dd>
+
+ <dt><a href="http://www.llnl.gov/CASC/emsolve"><b>EMSolve</b></a></dt>
+
+ <dd>EMSolve is a provably stable, charge conserving, and energy
+ conserving solver for Maxwell's equations.<br>
+ &nbsp;</dd>
+
+ <dt><b><a href="http://cern.ch/gaudi">Gaudi</a></b> and <b><a href=
+ "http://cern.ch/Gaudi/RootPython/">RootPython</a></b></dt>
+
+ <dd>
+ Gaudi is a framework for particle physics collision data processing
+ applications developed in the context of the LHCb and ATLAS experiments
+ at CERN.
+
+ <p><a href="mailto:Pere.Mato@cern.ch">Pere Mato Vila</a> writes:</p>
+
+ <blockquote>
+ 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 <a href=
+ "http://root.cern.ch">ROOT</a> framework and python
+
+ <p>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.</p>
+ </blockquote>
+ </dd>
+
+ <dt><b><a href="http://www.esss.com.br">ESSS</a></b></dt>
+
+ <dd>
+ 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.
+
+ <p><a href="mailto:bruno@esss.com.br">Bruno da Silva de Oliveira</a>
+ writes:</p>
+
+ <blockquote>
+ 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!
+ </blockquote>
+
+ <p>Two projects have been developed so far with this technology:</p>
+
+ <p><b><a href=
+ "http://www.esss.com.br/index.php?pg=dev_projetos">Simba</a></b>
+ 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.</p>
+
+ <p><b><a href=
+ "http://www.esss.com.br/index.php?pg=dev_projetos">Aero</a></b> 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.</p>
+ </dd>
+
+ <dt><b><a href="http://polybori.sourceforge.net/">PolyBoRi</a></b></dt>
+
+ <dd>
+ <p><a href="mailto:brickenstein@mfo.de"
+ >Michael Brickenstein</a> writes:</p>
+
+ <blockquote>
+ <p>The core of PolyBoRi is a C++ library, which provides
+ high-level data types for Boolean polynomials and monomials,
+ exponent vectors, as well as for the underlying polynomial
+ rings and subsets of the powerset of the Boolean variables. As
+ a unique approach, binary decision diagrams are used as
+ internal storage type for polynomial structures. On top of
+ this C++-library we provide a Python interface. This allows
+ parsing of complex polynomial systems, as well as sophisticated
+ and extendable strategies for Gr&ouml;bner basis computation.
+ Boost.Python has helped us to create this interface in a
+ very clean way.</p>
+ </blockquote>
+ </dd>
+
+ <dt><b><a href="http://pyrap.googlecode.com/">Pyrap</a></b></dt>
+ <dd>
+ <p><a href="diepen@astron.nl"
+ >Ger van Diepen</a> writes:</p>
+
+ <blockquote>
+ <p>Pyrap is the python interface to the Radio-Astronomical Package
+ casacore (<a href="http://casacore.googlecode.com/"
+ >casacore.googlecode.com</a>). Astronomers love pyrap because
+ it makes it easily possible to get their data (observed with
+ radio-astronomical telescopes like LOFAR, ASKAP, and eVLA) in numpy
+ arrays and do basic data inspection and manipulation using the many
+ python packages that are available.</p>
+
+ <p>Boost.Python made it quite easily possible to create converters for
+ the various data types, also for numpy arrays and individual elements
+ of a numpy array. It's nice they work fully recursively. Mapping C++
+ functions to Python was straightforward.</p>
+ </blockquote>
+ </dd>
+
+ <dt><b><a href="http://www.rdkit.org/"
+ >RDKit: Cheminformatics and Machine Learning Software</a></b></dt>
+
+ <dd>
+ A collection of cheminformatics and machine-learning software
+ written in C++ and Python.
+ </dd>
+ </dl>
+
+ <h3>Systems Libraries</h3>
+
+ <dl>
+ <dt><a href="http://itamarst.org/software"><b>Fusion</b></a></dt>
+
+ <dd>
+ <p>Fusion is a library that supports implementing protocols in C++ for
+ use with Twisted, allowing control over memory allocation strategies,
+ fast method calls internally, etc.. Fusion supports TCP, UDP and
+ multicast, and is implemented using the Boost.Python python
+ bindings.</p>
+
+ <p>Fusion is licensed under the MIT license, and available for download
+ from <a href=
+ "http://itamarst.org/software">http://itamarst.org/software</a>.</p>
+ </dd>
+ </dl>
+
+ <h3>Tools</h3>
+
+ <dl>
+ <dt><a href="http://www.jayacard.org"><b>Jayacard</b></a></dt>
+
+ <dd>
+ 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.
+
+ <p>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.</p>
+ </dd>
+ </dl>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 29 May, 2008</p>
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002-2008.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/support.html b/libs/python/doc/support.html
new file mode 100644
index 000000000..319856341
--- /dev/null
+++ b/libs/python/doc/support.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="boost.css">
+
+ <title>Boost.Python - Support Resources</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Support Resources</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Synopsis</h2>
+
+ <p>This is a list of available resources for support with Boost.Python
+ problems and feature requests. <b>Please try to resist emailing the
+ Boost.Python developers directly for support.</b> Use the following
+ resources instead; the developers are listening!</p>
+ <hr>
+
+ <dl class="page-index">
+ <dt><b><a href="http://www.boost-consulting.com">Boost
+ Consulting</a></b> - Commercial support, development, training, and
+ distribution for all the Boost libraries, from the people who brought
+ you Boost.Python.<br>
+ &nbsp;</dt>
+
+ <dt><b><a href=
+ "http://www.boost.org/more/mailing_lists.htm#cplussig">The Python
+ C++-sig</a></b> mailing list is a forum for discussing Python/C++
+ interoperability, and Boost.Python in particular. Post your
+ Boost.Python questions here.<br>
+ &nbsp;</dt>
+
+ <dt>The <b>Boost.Python <a href=
+ "http://www.python.org/cgi-bin/moinmoin/boost_2epython">Wiki
+ Pages</a></b> established by Mike Rovner as part of the <a href=
+ "http://www.python.org/cgi-bin/moinmoin">PythonInfo Wiki</a> serves as
+ a forum to gather peoples' experience and as a cookbook.<br>
+ &nbsp;</dt>
+ </dl>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 12 Sept, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2003.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/tutorial/doc/Jamfile.v2 b/libs/python/doc/tutorial/doc/Jamfile.v2
new file mode 100644
index 000000000..ba8882636
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/Jamfile.v2
@@ -0,0 +1,18 @@
+# Copyright Joel de Guzman 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+project boost/libs/python/doc/tutorial/doc ;
+
+import boostbook : boostbook ;
+using quickbook ;
+
+path-constant images : html ;
+
+boostbook tutorial
+ :
+ tutorial.qbk
+ :
+ <xsl:param>boost.root=../../../../../..
+ <format>pdf:<xsl:param>img.src.path=$(images)/
+ <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/python/doc/tutorial/doc/html
+ ;
diff --git a/libs/python/doc/tutorial/doc/html/images/alert.png b/libs/python/doc/tutorial/doc/html/images/alert.png
new file mode 100644
index 000000000..b4645bc7e
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/alert.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/home.png b/libs/python/doc/tutorial/doc/html/images/home.png
new file mode 100644
index 000000000..5584aacb0
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/home.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/jam.png b/libs/python/doc/tutorial/doc/html/images/jam.png
new file mode 100644
index 000000000..224ed7914
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/jam.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/next.png b/libs/python/doc/tutorial/doc/html/images/next.png
new file mode 100644
index 000000000..59800b4e8
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/next.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/note.png b/libs/python/doc/tutorial/doc/html/images/note.png
new file mode 100644
index 000000000..3ed047cac
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/note.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/prev.png b/libs/python/doc/tutorial/doc/html/images/prev.png
new file mode 100644
index 000000000..d88a40f92
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/prev.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/python.png b/libs/python/doc/tutorial/doc/html/images/python.png
new file mode 100644
index 000000000..cc2ff1d54
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/python.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/smiley.png b/libs/python/doc/tutorial/doc/html/images/smiley.png
new file mode 100644
index 000000000..30a77f71c
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/smiley.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/tip.png b/libs/python/doc/tutorial/doc/html/images/tip.png
new file mode 100644
index 000000000..9f596b0b8
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/tip.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/images/up.png b/libs/python/doc/tutorial/doc/html/images/up.png
new file mode 100644
index 000000000..17d9c3ec4
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/images/up.png
Binary files differ
diff --git a/libs/python/doc/tutorial/doc/html/index.html b/libs/python/doc/tutorial/doc/html/index.html
new file mode 100644
index 000000000..c324f065c
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/index.html
@@ -0,0 +1,142 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Chapter&#160;1.&#160;python 2.0</title>
+<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="next" href="python/hello.html" title="Building Hello World">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a></div>
+<div class="chapter">
+<div class="titlepage"><div>
+<div><h2 class="title">
+<a name="python"></a>Chapter&#160;1.&#160;python 2.0</h2></div>
+<div><div class="author"><h3 class="author">
+<span class="firstname">Joel</span> <span class="surname">de Guzman</span>
+</h3></div></div>
+<div><div class="author"><h3 class="author">
+<span class="firstname">David</span> <span class="surname">Abrahams</span>
+</h3></div></div>
+<div><p class="copyright">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams</p></div>
+<div><div class="legalnotice">
+<a name="python.legal"></a><p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></div>
+</div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="section"><a href="index.html#python.quickstart">QuickStart</a></span></dt>
+<dt><span class="section"><a href="python/hello.html">Building Hello World</a></span></dt>
+<dt><span class="section"><a href="python/exposing.html">Exposing Classes</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="python/exposing.html#python.constructors">Constructors</a></span></dt>
+<dt><span class="section"><a href="python/exposing.html#python.class_data_members">Class Data Members</a></span></dt>
+<dt><span class="section"><a href="python/exposing.html#python.class_properties">Class Properties</a></span></dt>
+<dt><span class="section"><a href="python/exposing.html#python.inheritance">Inheritance</a></span></dt>
+<dt><span class="section"><a href="python/exposing.html#python.class_virtual_functions">Class Virtual Functions</a></span></dt>
+<dt><span class="section"><a href="python/exposing.html#python.virtual_functions_with_default_implementations">Virtual Functions with Default Implementations</a></span></dt>
+<dt><span class="section"><a href="python/exposing.html#python.class_operators_special_functions">Class Operators/Special Functions</a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="python/functions.html">Functions</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="python/functions.html#python.call_policies">Call Policies</a></span></dt>
+<dt><span class="section"><a href="python/functions.html#python.overloading">Overloading</a></span></dt>
+<dt><span class="section"><a href="python/functions.html#python.default_arguments">Default Arguments</a></span></dt>
+<dt><span class="section"><a href="python/functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="python/object.html">Object Interface</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="python/object.html#python.basic_interface">Basic Interface</a></span></dt>
+<dt><span class="section"><a href="python/object.html#python.derived_object_types">Derived Object types</a></span></dt>
+<dt><span class="section"><a href="python/object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
+<dt><span class="section"><a href="python/object.html#python.enums">Enums</a></span></dt>
+<dt><span class="section"><a href="python/object.html#python.creating_python_object">Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code></a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="python/embedding.html">Embedding</a></span></dt>
+<dd><dl><dt><span class="section"><a href="python/embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></dd>
+<dt><span class="section"><a href="python/iterators.html">Iterators</a></span></dt>
+<dt><span class="section"><a href="python/exception.html">Exception Translation</a></span></dt>
+<dt><span class="section"><a href="python/techniques.html">General Techniques</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="python/techniques.html#python.creating_packages">Creating Packages</a></span></dt>
+<dt><span class="section"><a href="python/techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
+<dt><span class="section"><a href="python/techniques.html#python.reducing_compiling_time">Reducing Compiling Time</a></span></dt>
+</dl></dd>
+</dl>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.quickstart"></a>QuickStart</h2></div></div></div>
+<p>
+ 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).
+ </p>
+<h3>
+<a name="quickstart.hello_world"></a>
+ Hello World
+ </h3>
+<p>
+ Following C/C++ tradition, let's start with the "hello, world". A
+ C++ Function:
+ </p>
+<pre class="programlisting"><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">greet</span><span class="special">()</span>
+<span class="special">{</span>
+ <span class="keyword">return</span> <span class="string">"hello, world"</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ can be exposed to Python by writing a Boost.Python wrapper:
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello_ext</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
+ <span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="identifier">greet</span><span class="special">);</span>
+<span class="special">}</span>
+</pre>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">hello_ext</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
+<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
+</pre>
+<div class="blockquote"><blockquote class="blockquote"><p>
+ <span class="emphasis"><em><span class="bold"><strong>Next stop... Building your Hello World module
+ from start to finish...</strong></span></em></span>
+ </p></blockquote></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"><p><small>Last revised: December 26, 2011 at 21:58:39 GMT</small></p></td>
+<td align="right"><div class="copyright-footer"></div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a></div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/embedding.html b/libs/python/doc/tutorial/doc/html/python/embedding.html
new file mode 100644
index 000000000..4e1c21857
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/embedding.html
@@ -0,0 +1,269 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Embedding</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="object.html" title="Object Interface">
+<link rel="next" href="iterators.html" title="Iterators">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="object.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.embedding"></a>Embedding</h2></div></div></div>
+<div class="toc"><dl><dt><span class="section"><a href="embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></div>
+<p>
+ 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 <span class="emphasis"><em>embed</em></span> the Python interpreter
+ into your C++ program.
+ </p>
+<p>
+ Currently, Boost.Python does not directly support everything you'll need when
+ embedding. Therefore you'll need to use the <a href="http://www.python.org/doc/current/api/api.html" target="_top">Python/C
+ API</a> 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... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
+ </p>
+<h3>
+<a name="embedding.building_embedded_programs"></a>
+ Building embedded programs
+ </h3>
+<p>
+ To be able to embed python into your programs, you have to link to both Boost.Python's
+ as well as Python's own runtime library.
+ </p>
+<p>
+ Boost.Python's library comes in two variants. Both are located in Boost's
+ <code class="literal">/libs/python/build/bin-stage</code> subdirectory. On Windows, the
+ variants are called <code class="literal">boost_python.lib</code> (for release builds)
+ and <code class="literal">boost_python_debug.lib</code> (for debugging). If you can't
+ find the libraries, you probably haven't built Boost.Python yet. See <a href="../../../../building.html" target="_top">Building and Testing</a> on how to do this.
+ </p>
+<p>
+ Python's library can be found in the <code class="literal">/libs</code> subdirectory
+ of your Python directory. On Windows it is called pythonXY.lib where X.Y is
+ your major Python version number.
+ </p>
+<p>
+ Additionally, Python's <code class="literal">/include</code> subdirectory has to be added
+ to your include path.
+ </p>
+<p>
+ In a Jamfile, all the above boils down to:
+ </p>
+<pre class="programlisting">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
+ &lt;find-library&gt;boost_python &lt;library-path&gt;c:\boost\libs\python
+ $(PYTHON_PROPERTIES)
+ &lt;library-path&gt;$(PYTHON_LIB_PATH)
+ &lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
+</pre>
+<h3>
+<a name="embedding.getting_started"></a>
+ Getting started
+ </h3>
+<p>
+ 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:
+ </p>
+<div class="orderedlist"><ol class="orderedlist" type="1">
+<li class="listitem">
+ #include <code class="literal">&lt;boost/python.hpp&gt;</code>
+ </li>
+<li class="listitem">
+ Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
+ to start the interpreter and create the <code class="literal">__main__</code> module.
+ </li>
+<li class="listitem">
+ Call other Python C API routines to use the interpreter.
+ </li>
+</ol></div>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ <span class="bold"><strong>Note that at this time you must not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
+ to stop the interpreter. This may be fixed in a future version of boost.python.</strong></span>
+ </p></td></tr>
+</table></div>
+<p>
+ (Of course, there can be other C++ code between all of these steps.)
+ </p>
+<div class="blockquote"><blockquote class="blockquote"><p>
+ <span class="emphasis"><em><span class="bold"><strong>Now that we can embed the interpreter in
+ our programs, lets see how to put it to use...</strong></span></em></span>
+ </p></blockquote></div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
+<p>
+ As you probably already know, objects in Python are reference-counted. Naturally,
+ the <code class="literal">PyObject</code>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 <a href="http://www.python.org/doc/current/c-api/refcounting.html" target="_top">by
+ hand</a>. This is messy and especially hard to get right in the presence
+ of C++ exceptions. Fortunately Boost.Python provides the <a href="../../../../v2/handle.html" target="_top">handle</a>
+ and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
+ automate the process.
+ </p>
+<h3>
+<a name="using_the_interpreter.running_python_code"></a>
+ Running Python code
+ </h3>
+<p>
+ Boost.python provides three related functions to run Python code from C++.
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
+<span class="identifier">object</span> <span class="identifier">exec</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">code</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
+<span class="identifier">object</span> <span class="identifier">exec_file</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">filename</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
+</pre>
+<p>
+ eval evaluates the given expression and returns the resulting value. exec
+ executes the given code (typically a set of statements) returning the result,
+ and exec_file executes the code contained in the given file.
+ </p>
+<p>
+ The <code class="literal">globals</code> and <code class="literal">locals</code> 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 <code class="literal">__main__</code> module for both parameters.
+ </p>
+<p>
+ Boost.python provides a function to import a module:
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
+</pre>
+<p>
+ import imports a python module (potentially loading it into the running process
+ first), and returns it.
+ </p>
+<p>
+ Let's import the <code class="literal">__main__</code> module and run some Python code
+ in its namespace:
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
+<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
+
+<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"hello = file('hello.txt', 'w')\n"</span>
+ <span class="string">"hello.write('Hello world!')\n"</span>
+ <span class="string">"hello.close()"</span><span class="special">,</span>
+ <span class="identifier">main_namespace</span><span class="special">);</span>
+</pre>
+<p>
+ This should create a file called 'hello.txt' in the current directory containing
+ a phrase that is well-known in programming circles.
+ </p>
+<h3>
+<a name="using_the_interpreter.manipulating_python_objects"></a>
+ Manipulating Python objects
+ </h3>
+<p>
+ Often we'd like to have a class to manipulate Python objects. But we have
+ already seen such a class above, and in the <a href="object.html" target="_top">previous
+ section</a>: the aptly named <code class="literal">object</code> class and its
+ derivatives. We've already seen that they can be constructed from a <code class="literal">handle</code>.
+ The following examples should further illustrate this fact:
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
+<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
+<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"result = 5 ** 2"</span><span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">);</span>
+<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">main_namespace</span><span class="special">[</span><span class="string">"result"</span><span class="special">]);</span>
+</pre>
+<p>
+ Here we create a dictionary object for the <code class="literal">__main__</code> 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
+ use eval instead, which returns the result directly:
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</span><span class="special">);</span>
+<span class="keyword">int</span> <span class="identifier">five_squared</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
+</pre>
+<h3>
+<a name="using_the_interpreter.exception_handling"></a>
+ Exception handling
+ </h3>
+<p>
+ If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
+ is thrown:
+ </p>
+<pre class="programlisting"><span class="keyword">try</span>
+<span class="special">{</span>
+ <span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
+ <span class="comment">// execution will never get here:</span>
+ <span class="keyword">int</span> <span class="identifier">five_divided_by_zero</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">result</span><span class="special">);</span>
+<span class="special">}</span>
+<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
+<span class="special">{</span>
+ <span class="comment">// handle the exception in some way</span>
+<span class="special">}</span>
+</pre>
+<p>
+ The <code class="literal">error_already_set</code> exception class doesn't carry any
+ information in itself. To find out more about the Python exception that occurred,
+ you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">exception
+ handling functions</a> of the Python C API in your catch-statement. This
+ can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70" target="_top">PyErr_Print()</a>
+ to print the exception's traceback to the console, or comparing the type
+ of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html" target="_top">standard
+ exceptions</a>:
+ </p>
+<pre class="programlisting"><span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&amp;)</span>
+<span class="special">{</span>
+ <span class="keyword">if</span> <span class="special">(</span><span class="identifier">PyErr_ExceptionMatches</span><span class="special">(</span><span class="identifier">PyExc_ZeroDivisionError</span><span class="special">))</span>
+ <span class="special">{</span>
+ <span class="comment">// handle ZeroDivisionError specially</span>
+ <span class="special">}</span>
+ <span class="keyword">else</span>
+ <span class="special">{</span>
+ <span class="comment">// print all other errors to stderr</span>
+ <span class="identifier">PyErr_Print</span><span class="special">();</span>
+ <span class="special">}</span>
+<span class="special">}</span>
+</pre>
+<p>
+ (To retrieve even more information from the exception you can use some of
+ the other exception handling functions listed <a href="http://www.python.org/doc/api/exceptionHandling.html" target="_top">here</a>.)
+ </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="object.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/exception.html b/libs/python/doc/tutorial/doc/html/python/exception.html
new file mode 100644
index 000000000..7c053a7e8
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/exception.html
@@ -0,0 +1,63 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Exception Translation</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="iterators.html" title="Iterators">
+<link rel="next" href="techniques.html" title="General Techniques">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.exception"></a>Exception Translation</h2></div></div></div>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
+</pre>
+<p>
+ Users may provide custom translation. Here's an example:
+ </p>
+<pre class="programlisting"><span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
+<span class="identifier">void</span> <span class="identifier">translator</span><span class="special">(</span><span class="identifier">PodBayDoorException</span> <span class="identifier">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
+ <span class="identifier">PyErr_SetString</span><span class="special">(</span><span class="identifier">PyExc_UserWarning</span><span class="special">,</span> <span class="string">"I'm sorry Dave..."</span><span class="special">);</span>
+<span class="special">}</span>
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">kubrick</span><span class="special">)</span> <span class="special">{</span>
+ <span class="identifier">register_exception_translator</span><span class="special">&lt;</span>
+ <span class="identifier">PodBayDoorException</span><span class="special">&gt;(</span><span class="identifier">translator</span><span class="special">);</span>
+ <span class="special">...</span>
+</pre>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/exposing.html b/libs/python/doc/tutorial/doc/html/python/exposing.html
new file mode 100644
index 000000000..5547b2f20
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/exposing.html
@@ -0,0 +1,591 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Exposing Classes</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="hello.html" title="Building Hello World">
+<link rel="next" href="functions.html" title="Functions">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.exposing"></a>Exposing Classes</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section"><a href="exposing.html#python.constructors">Constructors</a></span></dt>
+<dt><span class="section"><a href="exposing.html#python.class_data_members">Class Data Members</a></span></dt>
+<dt><span class="section"><a href="exposing.html#python.class_properties">Class Properties</a></span></dt>
+<dt><span class="section"><a href="exposing.html#python.inheritance">Inheritance</a></span></dt>
+<dt><span class="section"><a href="exposing.html#python.class_virtual_functions">Class Virtual Functions</a></span></dt>
+<dt><span class="section"><a href="exposing.html#python.virtual_functions_with_default_implementations">Virtual Functions with Default Implementations</a></span></dt>
+<dt><span class="section"><a href="exposing.html#python.class_operators_special_functions">Class Operators/Special Functions</a></span></dt>
+</dl></div>
+<p>
+ Now let's expose a C++ class to Python.
+ </p>
+<p>
+ Consider a C++ class/struct that we want to expose to Python:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
+<span class="special">{</span>
+ <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">greet</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<p>
+ We can expose this to Python by writing a corresponding Boost.Python C++ Wrapper:
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
+
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
+ <span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Here, we wrote a C++ class wrapper that exposes the member functions <code class="literal">greet</code>
+ and <code class="literal">set</code>. Now, after building our module as a shared library,
+ we may use our class <code class="literal">World</code> in Python. Here's a sample Python
+ session:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">'howdy'</span><span class="special">)</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
+<span class="string">'howdy'</span>
+</pre>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.constructors"></a>Constructors</h3></div></div></div>
+<p>
+ Our previous example didn't have any explicit constructors. Since <code class="literal">World</code>
+ 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
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">planet</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">World</span><span class="special">()</span>
+</pre>
+<p>
+ We may wish to wrap a class with a non-default constructor. Let us build
+ on our previous example:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">World</span>
+<span class="special">{</span>
+ <span class="identifier">World</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">):</span> <span class="identifier">msg</span><span class="special">(</span><span class="identifier">msg</span><span class="special">)</span> <span class="special">{}</span> <span class="comment">// added constructor</span>
+ <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">msg</span> <span class="special">=</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">greet</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">msg</span><span class="special">;</span> <span class="special">}</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<p>
+ This time <code class="literal">World</code> has no default constructor; our previous
+ wrapping code would fail to compile when the library tried to expose it.
+ We have to tell <code class="literal">class_&lt;World&gt;</code> about the constructor
+ we want to expose instead.
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
+
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
+ <span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ <code class="literal">init&lt;std::string&gt;()</code> exposes the constructor taking
+ in a <code class="literal">std::string</code> (in Python, constructors are spelled
+ "<code class="literal">"__init__"</code>").
+ </p>
+<p>
+ We can expose additional constructors by passing more <code class="literal">init&lt;...&gt;</code>s
+ to the <code class="literal">def()</code> member function. Say for example we have
+ another World constructor taking in two doubles:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">World</span><span class="special">&gt;(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;())</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">greet</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"set"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
+<span class="special">;</span>
+</pre>
+<p>
+ On the other hand, if we do not wish to expose any constructors at all, we
+ may use <code class="literal">no_init</code> instead:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Abstract</span><span class="special">&gt;(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
+</pre>
+<p>
+ This actually adds an <code class="literal">__init__</code> method which always raises
+ a Python RuntimeError exception.
+ </p>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.class_data_members"></a>Class Data Members</h3></div></div></div>
+<p>
+ 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 <span class="bold"><strong>read-only</strong></span>
+ or <span class="bold"><strong>read-write</strong></span>. Consider this class <code class="literal">Var</code>:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Var</span>
+<span class="special">{</span>
+ <span class="identifier">Var</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">name</span><span class="special">(</span><span class="identifier">name</span><span class="special">),</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">{}</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="identifier">name</span><span class="special">;</span>
+ <span class="keyword">float</span> <span class="identifier">value</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<p>
+ Our C++ <code class="literal">Var</code> class and its data members can be exposed
+ to Python:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Var</span><span class="special">&gt;(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;())</span>
+ <span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">name</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def_readwrite</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span>
+</pre>
+<p>
+ Then, in Python, assuming we have placed our Var class inside the namespace
+ hello as we did before:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">Var</span><span class="special">(</span><span class="string">'pi'</span><span class="special">)</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span><span class="special">,</span> <span class="string">'is around'</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span>
+<span class="identifier">pi</span> <span class="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
+</pre>
+<p>
+ Note that <code class="literal">name</code> is exposed as <span class="bold"><strong>read-only</strong></span>
+ while <code class="literal">value</code> is exposed as <span class="bold"><strong>read-write</strong></span>.
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name</span>
+<span class="identifier">Traceback</span> <span class="special">(</span><span class="identifier">most</span> <span class="identifier">recent</span> <span class="identifier">call</span> <span class="identifier">last</span><span class="special">):</span>
+ <span class="identifier">File</span> <span class="string">"&lt;stdin&gt;"</span><span class="special">,</span> <span class="identifier">line</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">in</span> <span class="error">?</span>
+<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span><span class="error">'</span><span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.class_properties"></a>Class Properties</h3></div></div></div>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Num</span>
+<span class="special">{</span>
+ <span class="identifier">Num</span><span class="special">();</span>
+ <span class="keyword">float</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
+ <span class="keyword">void</span> <span class="identifier">set</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">value</span><span class="special">);</span>
+ <span class="special">...</span>
+<span class="special">};</span>
+</pre>
+<p>
+ 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 <code class="literal">Num</code>
+ class using Boost.Python:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Num</span><span class="special">&gt;(</span><span class="string">"Num"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"value"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">set</span><span class="special">);</span>
+</pre>
+<p>
+ And at last, in Python:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="number">3.14</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span>
+<span class="special">(</span><span class="number">3.14</span><span class="special">,</span> <span class="number">3.14</span><span class="special">)</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">rovalue</span> <span class="special">=</span> <span class="number">2.17</span> <span class="comment"># error!</span>
+</pre>
+<p>
+ Take note that the class property <code class="literal">rovalue</code> is exposed as
+ <span class="bold"><strong>read-only</strong></span> since the <code class="literal">rovalue</code>
+ setter member function is not passed in:
+ </p>
+<pre class="programlisting"><span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.inheritance"></a>Inheritance</h3></div></div></div>
+<p>
+ 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.
+ </p>
+<p>
+ Consider this trivial inheritance structure:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span> <span class="special">{</span> <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">();</span> <span class="special">};</span>
+<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
+</pre>
+<p>
+ And a set of C++ functions operating on <code class="literal">Base</code> and <code class="literal">Derived</code>
+ object instances:
+ </p>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">Base</span><span class="special">*);</span>
+<span class="keyword">void</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">Derived</span><span class="special">*);</span>
+<span class="identifier">Base</span><span class="special">*</span> <span class="identifier">factory</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">Derived</span><span class="special">;</span> <span class="special">}</span>
+</pre>
+<p>
+ We've seen how we can wrap the base class <code class="literal">Base</code>:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
+ <span class="comment">/*...*/</span>
+ <span class="special">;</span>
+</pre>
+<p>
+ Now we can inform Boost.Python of the inheritance relationship between <code class="literal">Derived</code>
+ and its base class <code class="literal">Base</code>. Thus:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"Derived"</span><span class="special">)</span>
+ <span class="comment">/*...*/</span>
+ <span class="special">;</span>
+</pre>
+<p>
+ Doing so, we get some things for free:
+ </p>
+<div class="orderedlist"><ol class="orderedlist" type="1">
+<li class="listitem">
+ Derived automatically inherits all of Base's Python methods (wrapped
+ C++ member functions)
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>If</strong></span> Base is polymorphic, <code class="literal">Derived</code>
+ objects which have been passed to Python via a pointer or reference to
+ <code class="literal">Base</code> can be passed where a pointer or reference to
+ <code class="literal">Derived</code> is expected.
+ </li>
+</ol></div>
+<p>
+ Now, we will expose the C++ free functions <code class="literal">b</code> and <code class="literal">d</code>
+ and <code class="literal">factory</code>:
+ </p>
+<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
+<span class="identifier">def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>
+<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
+</pre>
+<p>
+ Note that free function <code class="literal">factory</code> is being used to generate
+ new instances of class <code class="literal">Derived</code>. In such cases, we use
+ <code class="literal">return_value_policy&lt;manage_new_object&gt;</code> to instruct
+ Python to adopt the pointer to <code class="literal">Base</code> and hold the instance
+ in a new Python <code class="literal">Base</code> object until the the Python object
+ is destroyed. We will see more of Boost.Python <a class="link" href="functions.html#python.call_policies" title="Call Policies">call
+ policies</a> later.
+ </p>
+<pre class="programlisting"><span class="comment">// Tell Python to take ownership of factory's result</span>
+<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">,</span>
+ <span class="identifier">return_value_policy</span><span class="special">&lt;</span><span class="identifier">manage_new_object</span><span class="special">&gt;());</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.class_virtual_functions"></a>Class Virtual Functions</h3></div></div></div>
+<p>
+ In this section, we will learn how to make functions behave polymorphically
+ through virtual functions. Continuing our example, let us add a virtual function
+ to our <code class="literal">Base</code> class:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
+<span class="special">{</span>
+ <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
+ <span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<p>
+ 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. It is not ideal to add anything
+ to our class <code class="computeroutput"><span class="identifier">Base</span></code>. Yet, when
+ you have a virtual function that's going to be overridden in Python and called
+ polymorphically <span class="bold"><strong>from C++</strong></span>, we'll need to
+ add some scaffoldings to make things work properly. What we'll do is write
+ a class wrapper that derives from <code class="computeroutput"><span class="identifier">Base</span></code>
+ that will unintrusively hook into the virtual functions so that a Python
+ override may be called:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
+<span class="special">{</span>
+ <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">)();</span>
+ <span class="special">}</span>
+<span class="special">};</span>
+</pre>
+<p>
+ Notice too that in addition to inheriting from <code class="computeroutput"><span class="identifier">Base</span></code>,
+ we also multiply- inherited <code class="computeroutput"><span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span></code> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
+ The <code class="computeroutput"><span class="identifier">wrapper</span></code> template makes
+ the job of wrapping classes that are meant to overridden in Python, easier.
+ </p>
+<div class="sidebar">
+<div class="titlepage"></div>
+<p>
+ <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span>
+ </p>
+<p>
+ If you are using Microsoft Visual C++ 6 or 7, you have to write <code class="computeroutput"><span class="identifier">f</span></code> as:
+ </p>
+<p>
+ <code class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></code>.
+ </p>
+</div>
+<p>
+ BaseWrap's overridden virtual member function <code class="computeroutput"><span class="identifier">f</span></code>
+ in effect calls the corresponding method of the Python object through <code class="computeroutput"><span class="identifier">get_override</span></code>.
+ </p>
+<p>
+ Finally, exposing <code class="computeroutput"><span class="identifier">Base</span></code>:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
+ <span class="special">;</span>
+</pre>
+<p>
+ <code class="computeroutput"><span class="identifier">pure_virtual</span></code> signals Boost.Python
+ that the function <code class="computeroutput"><span class="identifier">f</span></code> is a
+ pure virtual function.
+ </p>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top">
+<p>
+ <span class="bold"><strong>member function and methods</strong></span>
+ </p>
+<p>
+ Python, like many object oriented languages uses the term <span class="bold"><strong>methods</strong></span>.
+ Methods correspond roughly to C++'s <span class="bold"><strong>member functions</strong></span>
+ </p>
+</td></tr>
+</table></div>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.virtual_functions_with_default_implementations"></a>Virtual Functions with Default Implementations</h3></div></div></div>
+<p>
+ We've seen in the previous section how classes with pure virtual functions
+ are wrapped using Boost.Python's <a href="../../../../v2/wrapper.html" target="_top">class
+ wrapper</a> facilities. If we wish to wrap <span class="bold"><strong>non</strong></span>-pure-virtual
+ functions instead, the mechanism is a bit different.
+ </p>
+<p>
+ Recall that in the <a class="link" href="exposing.html#python.class_virtual_functions" title="Class Virtual Functions">previous
+ section</a>, we wrapped a class with a pure virtual function that we then
+ implemented in C++, or Python classes derived from it. Our base class:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
+<span class="special">{</span>
+ <span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
+<span class="special">};</span>
+</pre>
+<p>
+ had a pure virtual function <code class="literal">f</code>. If, however, its member
+ function <code class="literal">f</code> was not declared as pure virtual:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Base</span>
+<span class="special">{</span>
+ <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">Base</span><span class="special">()</span> <span class="special">{}</span>
+ <span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span>
+<span class="special">};</span>
+</pre>
+<p>
+ We wrap it this way:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">BaseWrap</span> <span class="special">:</span> <span class="identifier">Base</span><span class="special">,</span> <span class="identifier">wrapper</span><span class="special">&lt;</span><span class="identifier">Base</span><span class="special">&gt;</span>
+<span class="special">{</span>
+ <span class="keyword">int</span> <span class="identifier">f</span><span class="special">()</span>
+ <span class="special">{</span>
+ <span class="keyword">if</span> <span class="special">(</span><span class="identifier">override</span> <span class="identifier">f</span> <span class="special">=</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">))</span>
+ <span class="keyword">return</span> <span class="identifier">f</span><span class="special">();</span> <span class="comment">// *note*</span>
+ <span class="keyword">return</span> <span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span>
+ <span class="special">}</span>
+
+ <span class="keyword">int</span> <span class="identifier">default_f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">();</span> <span class="special">}</span>
+<span class="special">};</span>
+</pre>
+<p>
+ Notice how we implemented <code class="computeroutput"><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">f</span></code>. Now,
+ we have to check if there is an override for <code class="computeroutput"><span class="identifier">f</span></code>.
+ If none, then we call <code class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></code>.
+ </p>
+<div class="sidebar">
+<div class="titlepage"></div>
+<p>
+ <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>MSVC6/7 Workaround</strong></span>
+ </p>
+<p>
+ If you are using Microsoft Visual C++ 6 or 7, you have to rewrite the line
+ with the <code class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></code> as:
+ </p>
+<p>
+ <code class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">f</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">());</span></code>.
+ </p>
+</div>
+<p>
+ Finally, exposing:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">BaseWrap</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span><span class="special">&gt;(</span><span class="string">"Base"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span><span class="special">)</span>
+ <span class="special">;</span>
+</pre>
+<p>
+ Take note that we expose both <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></code> and <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span></code>. Boost.Python needs to keep track
+ of 1) the dispatch function <code class="literal">f</code> and 2) the forwarding function
+ to its default implementation <code class="literal">default_f</code>. There's a special
+ <code class="literal">def</code> function for this purpose.
+ </p>
+<p>
+ In Python, the results would be as expected:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="keyword">class</span> <span class="identifier">Derived</span><span class="special">(</span><span class="identifier">Base</span><span class="special">):</span>
+<span class="special">...</span> <span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
+<span class="special">...</span> <span class="keyword">return</span> <span class="number">42</span>
+<span class="special">...</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span> <span class="special">=</span> <span class="identifier">Derived</span><span class="special">()</span>
+</pre>
+<p>
+ Calling <code class="literal">base.f()</code>:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">base</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
+<span class="number">0</span>
+</pre>
+<p>
+ Calling <code class="literal">derived.f()</code>:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">derived</span><span class="special">.</span><span class="identifier">f</span><span class="special">()</span>
+<span class="number">42</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
+<h3>
+<a name="class_operators_special_functions.python_operators"></a>
+ Python Operators
+ </h3>
+<p>
+ 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.
+ </p>
+<p>
+ Consider a file position class <code class="literal">FilePos</code> and a set of operators
+ that take on FilePos instances:
+ </p>
+<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span>
+
+<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
+<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
+<span class="keyword">int</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
+<span class="identifier">FilePos</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="keyword">int</span><span class="special">);</span>
+<span class="identifier">FilePos</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="identifier">FilePos</span><span class="special">&amp;,</span> <span class="keyword">int</span><span class="special">);</span>
+<span class="identifier">FilePos</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">-=(</span><span class="identifier">FilePos</span><span class="special">&amp;,</span> <span class="keyword">int</span><span class="special">);</span>
+<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
+</pre>
+<p>
+ The class and the various operators can be mapped to Python rather easily
+ and intuitively:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">FilePos</span><span class="special">&gt;(</span><span class="string">"FilePos"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __add__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="keyword">int</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __radd__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="identifier">self</span><span class="special">)</span> <span class="comment">// __sub__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __sub__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">+=</span> <span class="keyword">int</span><span class="special">())</span> <span class="comment">// __iadd__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">-=</span> <span class="identifier">other</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;())</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">self</span> <span class="special">&lt;</span> <span class="identifier">self</span><span class="special">);</span> <span class="comment">// __lt__</span>
+</pre>
+<p>
+ 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
+ <code class="literal">self</code> refers to FilePos object. Also, not every class
+ <code class="literal">T</code> that you might need to interact with in an operator
+ expression is (cheaply) default-constructible. You can use <code class="literal">other&lt;T&gt;()</code>
+ in place of an actual <code class="literal">T</code> instance when writing "self
+ expressions".
+ </p>
+<h3>
+<a name="class_operators_special_functions.special_methods"></a>
+ Special Methods
+ </h3>
+<p>
+ Python has a few more <span class="emphasis"><em>Special Methods</em></span>. 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 <span class="emphasis"><em>special functions</em></span>.
+ Example:
+ </p>
+<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">Rational</span>
+<span class="special">{</span> <span class="keyword">public</span><span class="special">:</span> <span class="keyword">operator</span> <span class="keyword">double</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> <span class="special">};</span>
+
+<span class="identifier">Rational</span> <span class="identifier">pow</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">,</span> <span class="identifier">Rational</span><span class="special">);</span>
+<span class="identifier">Rational</span> <span class="identifier">abs</span><span class="special">(</span><span class="identifier">Rational</span><span class="special">);</span>
+<span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">ostream</span><span class="special">&amp;,</span><span class="identifier">Rational</span><span class="special">);</span>
+
+<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;(</span><span class="string">"Rational"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">float_</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __float__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">other</span><span class="special">&lt;</span><span class="identifier">Rational</span><span class="special">&gt;))</span> <span class="comment">// __pow__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">abs</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __abs__</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span> <span class="comment">// __str__</span>
+ <span class="special">;</span>
+</pre>
+<p>
+ Need we say more?
+ </p>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ What is the business of <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>? Well, the method <code class="computeroutput"><span class="identifier">str</span></code> requires the <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code> to do its work (i.e. <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;</span></code>
+ is used by the method defined by <code class="computeroutput"><span class="identifier">def</span><span class="special">(</span><span class="identifier">str</span><span class="special">(</span><span class="identifier">self</span><span class="special">))</span></code>.
+ </p></td></tr>
+</table></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/functions.html b/libs/python/doc/tutorial/doc/html/python/functions.html
new file mode 100644
index 000000000..ddd5bc7b7
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/functions.html
@@ -0,0 +1,586 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Functions</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="exposing.html" title="Exposing Classes">
+<link rel="next" href="object.html" title="Object Interface">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.functions"></a>Functions</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section"><a href="functions.html#python.call_policies">Call Policies</a></span></dt>
+<dt><span class="section"><a href="functions.html#python.overloading">Overloading</a></span></dt>
+<dt><span class="section"><a href="functions.html#python.default_arguments">Default Arguments</a></span></dt>
+<dt><span class="section"><a href="functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
+</dl></div>
+<p>
+ In this chapter, we'll look at Boost.Python powered functions in closer detail.
+ We will see some facilities to make exposing C++ functions to Python safe from
+ potential pifalls such as dangling pointers and references. We will 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.
+ </p>
+<div class="blockquote"><blockquote class="blockquote"><p>
+ <span class="emphasis"><em>Read on...</em></span>
+ </p></blockquote></div>
+<p>
+ But before you do, you might want to fire up Python 2.2 or later and type
+ <code class="literal">&gt;&gt;&gt; import this</code>.
+ </p>
+<pre class="programlisting">&gt;&gt;&gt; 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 <span class="bold"><strong>right</strong></span> 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!
+</pre>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.call_policies"></a>Call Policies</h3></div></div></div>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
+</pre>
+<p>
+ 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
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">y</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
+</pre>
+<p>
+ What's the problem?
+ </p>
+<p>
+ Well, what if f() was implemented as shown below:
+ </p>
+<pre class="programlisting"><span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
+ <span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ The problem is that the lifetime of result X&amp; 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.
+ </p>
+<p>
+ Here's what's happening:
+ </p>
+<div class="orderedlist"><ol class="orderedlist" type="1">
+<li class="listitem">
+ <code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
+ and a pointer to <code class="literal">z</code>
+ </li>
+<li class="listitem">
+ A reference to <code class="literal">y.x</code> is returned
+ </li>
+<li class="listitem">
+ <code class="literal">y</code> is deleted. <code class="literal">x</code> is a dangling reference
+ </li>
+<li class="listitem">
+ <code class="literal">x.some_method()</code> is called
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>BOOM!</strong></span>
+ </li>
+</ol></div>
+<p>
+ We could copy result into a new object:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">).</span><span class="identifier">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="comment"># No crash, but still bad</span>
+<span class="number">3.14</span>
+</pre>
+<p>
+ 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.
+ </p>
+<p>
+ Our problems do not end there. Suppose Y is implemented as follows:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Y</span>
+<span class="special">{</span>
+ <span class="identifier">X</span> <span class="identifier">x</span><span class="special">;</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">;</span>
+ <span class="keyword">int</span> <span class="identifier">z_value</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">z</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span> <span class="special">}</span>
+<span class="special">};</span>
+</pre>
+<p>
+ Notice that the data member <code class="literal">z</code> is held by class Y using
+ a raw pointer. Now we have a potential dangling pointer problem inside Y:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">y</span><span class="special">,</span> <span class="identifier">z</span><span class="special">)</span> <span class="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">del</span> <span class="identifier">z</span> <span class="preprocessor"># Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
+</pre>
+<p>
+ For reference, here's the implementation of <code class="literal">f</code> again:
+ </p>
+<pre class="programlisting"><span class="identifier">X</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Y</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">y</span><span class="special">.</span><span class="identifier">z</span> <span class="special">=</span> <span class="identifier">z</span><span class="special">;</span>
+ <span class="keyword">return</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Here's what's happening:
+ </p>
+<div class="orderedlist"><ol class="orderedlist" type="1">
+<li class="listitem">
+ <code class="literal">f</code> is called passing in a reference to <code class="literal">y</code>
+ and a pointer to <code class="literal">z</code>
+ </li>
+<li class="listitem">
+ A pointer to <code class="literal">z</code> is held by <code class="literal">y</code>
+ </li>
+<li class="listitem">
+ A reference to <code class="literal">y.x</code> is returned
+ </li>
+<li class="listitem">
+ <code class="literal">z</code> is deleted. <code class="literal">y.z</code> is a dangling
+ pointer
+ </li>
+<li class="listitem">
+ <code class="literal">y.z_value()</code> is called
+ </li>
+<li class="listitem">
+ <code class="literal">z-&gt;value()</code> is called
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>BOOM!</strong></span>
+ </li>
+</ol></div>
+<h3>
+<a name="call_policies.call_policies"></a>
+ Call Policies
+ </h3>
+<p>
+ Call Policies may be used in situations such as the example detailed above.
+ In our example, <code class="literal">return_internal_reference</code> and <code class="literal">with_custodian_and_ward</code>
+ are our friends:
+ </p>
+<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
+ <span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span>
+ <span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span> <span class="special">&gt;());</span>
+</pre>
+<p>
+ What are the <code class="literal">1</code> and <code class="literal">2</code> parameters, you
+ ask?
+ </p>
+<pre class="programlisting"><span class="identifier">return_internal_reference</span><span class="special">&lt;</span><span class="number">1</span>
+</pre>
+<p>
+ Informs Boost.Python that the first argument, in our case <code class="literal">Y&amp;
+ y</code>, is the owner of the returned reference: <code class="literal">X&amp;</code>.
+ The "<code class="literal">1</code>" simply specifies the first argument.
+ In short: "return an internal reference <code class="literal">X&amp;</code> owned
+ by the 1st argument <code class="literal">Y&amp; y</code>".
+ </p>
+<pre class="programlisting"><span class="identifier">with_custodian_and_ward</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">&gt;</span>
+</pre>
+<p>
+ Informs Boost.Python that the lifetime of the argument indicated by ward
+ (i.e. the 2nd argument: <code class="literal">Z* z</code>) is dependent on the lifetime
+ of the argument indicated by custodian (i.e. the 1st argument: <code class="literal">Y&amp;
+ y</code>).
+ </p>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="identifier">policy1</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span>
+ <span class="identifier">policy2</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...,</span>
+ <span class="identifier">policy3</span><span class="special">&lt;</span><span class="identifier">args</span><span class="special">...&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;</span>
+</pre>
+<p>
+ Here is the list of predefined call policies. A complete reference detailing
+ these can be found <a href="../../../../v2/reference.html#models_of_call_policies" target="_top">here</a>.
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ <span class="bold"><strong>with_custodian_and_ward</strong></span>: Ties lifetimes
+ of the arguments
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>with_custodian_and_ward_postcall</strong></span>: Ties
+ lifetimes of the arguments and results
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>return_internal_reference</strong></span>: Ties lifetime
+ of one argument to that of result
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>return_value_policy&lt;T&gt; with T one of:</strong></span>
+ <div class="itemizedlist"><ul class="itemizedlist" type="circle">
+<li class="listitem">
+ <span class="bold"><strong>reference_existing_object</strong></span>: naive
+ (dangerous) approach
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>copy_const_reference</strong></span>: Boost.Python
+ v1 approach
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>copy_non_const_reference</strong></span>:
+ </li>
+<li class="listitem">
+ <span class="bold"><strong>manage_new_object</strong></span>: Adopt a pointer
+ and hold the instance
+ </li>
+</ul></div>
+ </li>
+</ul></div>
+<div class="sidebar">
+<div class="titlepage"></div>
+<p>
+ <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><strong>Remember the Zen, Luke:</strong></span>
+ </p>
+<p>
+ "Explicit is better than implicit"
+ </p>
+<p>
+ "In the face of ambiguity, refuse the temptation to guess"
+ </p>
+</div>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.overloading"></a>Overloading</h3></div></div></div>
+<p>
+ 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.
+ </p>
+<p>
+ We have here our C++ class:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
+<span class="special">{</span>
+ <span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">)</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
+ <span class="special">}</span>
+
+ <span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">b</span><span class="special">)</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
+ <span class="special">}</span>
+
+ <span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
+ <span class="special">}</span>
+
+ <span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">c</span><span class="special">)</span>
+ <span class="special">{</span>
+ <span class="keyword">return</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span> <span class="special">+</span> <span class="identifier">c</span><span class="special">;</span>
+ <span class="special">};</span>
+<span class="special">};</span>
+</pre>
+<p>
+ Class X has 4 overloaded functions. We will start by introducing some member
+ function pointer variables:
+ </p>
+<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
+<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
+<span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx3</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
+<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx4</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
+</pre>
+<p>
+ With these in hand, we can proceed to define and wrap this for Python:
+ </p>
+<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
+<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
+<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx3</span><span class="special">)</span>
+<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx4</span><span class="special">)</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.default_arguments"></a>Default Arguments</h3></div></div></div>
+<p>
+ Boost.Python wraps (member) function pointers. Unfortunately, C++ function
+ pointers carry no default argument info. Take a function <code class="literal">f</code>
+ with default arguments:
+ </p>
+<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">=</span> <span class="number">3.14</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">*</span> <span class="special">=</span> <span class="string">"hello"</span><span class="special">);</span>
+</pre>
+<p>
+ But the type of a pointer to the function <code class="literal">f</code> has no information
+ about its default arguments:
+ </p>
+<pre class="programlisting"><span class="keyword">int</span><span class="special">(*</span><span class="identifier">g</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">double</span><span class="special">,</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*)</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">;</span> <span class="comment">// defaults lost!</span>
+</pre>
+<p>
+ When we pass this function pointer to the <code class="literal">def</code> function,
+ there is no way to retrieve the default arguments:
+ </p>
+<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!</span>
+</pre>
+<p>
+ Because of this, when wrapping C++ code, we had to resort to manual wrapping
+ as outlined in the <a class="link" href="functions.html#python.overloading" title="Overloading">previous section</a>,
+ or writing thin wrappers:
+ </p>
+<pre class="programlisting"><span class="comment">// write "thin wrappers"</span>
+<span class="keyword">int</span> <span class="identifier">f1</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
+<span class="keyword">int</span> <span class="identifier">f2</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">);</span> <span class="special">}</span>
+
+<span class="comment">/*...*/</span>
+
+ <span class="comment">// in module init</span>
+ <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// all arguments</span>
+ <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f2</span><span class="special">);</span> <span class="comment">// two arguments</span>
+ <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span> <span class="comment">// one argument</span>
+</pre>
+<p>
+ When you want to wrap functions (or member functions) that either:
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ have default arguments, or
+ </li>
+<li class="listitem">
+ are overloaded with a common sequence of initial arguments
+ </li>
+</ul></div>
+<h3>
+<a name="default_arguments.boost_python_function_overloads"></a>
+ BOOST_PYTHON_FUNCTION_OVERLOADS
+ </h3>
+<p>
+ Boost.Python now has a way to make it easier. For instance, given a function:
+ </p>
+<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">c</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">3</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="comment">/*...*/</span>
+<span class="special">}</span>
+</pre>
+<p>
+ The macro invocation:
+ </p>
+<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
+</pre>
+<p>
+ will automatically create the thin wrappers for us. This macro will create
+ a class <code class="literal">foo_overloads</code> that can be passed on to <code class="literal">def(...)</code>.
+ The third and fourth macro argument are the minimum arguments and maximum
+ arguments, respectively. In our <code class="literal">foo</code> function the minimum
+ number of arguments is 1 and the maximum number of arguments is 4. The <code class="literal">def(...)</code>
+ function will automatically add all the foo variants for us:
+ </p>
+<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
+</pre>
+<h3>
+<a name="default_arguments.boost_python_member_function_overloads"></a>
+ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
+ </h3>
+<p>
+ 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.
+ </p>
+<p>
+ Like <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>, <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
+ may be used to automatically create the thin wrappers for wrapping member
+ functions. Let's have an example:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">george</span>
+<span class="special">{</span>
+ <span class="keyword">void</span>
+ <span class="identifier">wack_em</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span> <span class="special">=</span> <span class="char">'x'</span><span class="special">)</span>
+ <span class="special">{</span>
+ <span class="comment">/*...*/</span>
+ <span class="special">}</span>
+<span class="special">};</span>
+</pre>
+<p>
+ The macro invocation:
+ </p>
+<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">george_overloads</span><span class="special">,</span> <span class="identifier">wack_em</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
+</pre>
+<p>
+ will generate a set of thin wrappers for george's <code class="literal">wack_em</code>
+ 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 <code class="literal">george_overloads</code> that can then be used
+ as an argument to <code class="literal">def(...)</code>:
+ </p>
+<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">george</span><span class="special">::</span><span class="identifier">wack_em</span><span class="special">,</span> <span class="identifier">george_overloads</span><span class="special">());</span>
+</pre>
+<p>
+ See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
+ reference</a> for details.
+ </p>
+<h3>
+<a name="default_arguments.init_and_optional"></a>
+ init and optional
+ </h3>
+<p>
+ A similar facility is provided for class constructors, again, with default
+ arguments or a sequence of overloads. Remember <code class="literal">init&lt;...&gt;</code>?
+ For example, given a class X with a constructor:
+ </p>
+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
+<span class="special">{</span>
+ <span class="identifier">X</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">b</span> <span class="special">=</span> <span class="char">'D'</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">c</span> <span class="special">=</span> <span class="string">"constructor"</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">);</span>
+ <span class="comment">/*...*/</span>
+<span class="special">}</span>
+</pre>
+<p>
+ You can easily add this constructor to Boost.Python in one shot:
+ </p>
+<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
+</pre>
+<p>
+ Notice the use of <code class="literal">init&lt;...&gt;</code> and <code class="literal">optional&lt;...&gt;</code>
+ to signify the default (optional arguments).
+ </p>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.auto_overloading"></a>Auto-Overloading</h3></div></div></div>
+<p>
+ It was mentioned in passing in the previous section that <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>
+ and <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code> can also be
+ used for overloaded functions and member functions with a common sequence
+ of initial arguments. Here is an example:
+ </p>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
+<span class="special">{</span>
+ <span class="comment">/*...*/</span>
+<span class="special">}</span>
+
+<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">a</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="comment">/*...*/</span>
+<span class="special">}</span>
+
+<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="comment">/*...*/</span>
+<span class="special">}</span>
+
+<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="comment">/*...*/</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Like in the previous section, we can generate thin wrappers for these overloaded
+ functions in one-shot:
+ </p>
+<pre class="programlisting"><span class="identifier">BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">foo_overloads</span><span class="special">,</span> <span class="identifier">foo</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
+</pre>
+<p>
+ Then...
+ </p>
+<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
+</pre>
+<p>
+ Notice though that we have a situation now where we have a minimum of zero
+ (0) arguments and a maximum of 3 arguments.
+ </p>
+<h3>
+<a name="auto_overloading.manual_wrapping"></a>
+ Manual Wrapping
+ </h3>
+<p>
+ It is important to emphasize however that <span class="bold"><strong>the overloaded
+ functions must have a common sequence of initial arguments</strong></span>. Otherwise,
+ our scheme above will not work. If this is not the case, we have to wrap
+ our functions <a class="link" href="functions.html#python.overloading" title="Overloading">manually</a>.
+ </p>
+<p>
+ Actually, we can mix and match manual wrapping of overloaded functions and
+ automatic wrapping through <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
+ and its sister, <code class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</code>. Following
+ up on our example presented in the section <a class="link" href="functions.html#python.overloading" title="Overloading">on
+ overloading</a>, since the first 4 overload functins have a common sequence
+ of initial arguments, we can use <code class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</code>
+ to automatically wrap the first three of the <code class="literal">def</code>s and
+ manually wrap just the last. Here's how we'll do this:
+ </p>
+<pre class="programlisting"><span class="identifier">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class="special">(</span><span class="identifier">xf_overloads</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">4</span><span class="special">)</span>
+</pre>
+<p>
+ Create a member function pointers as above for both X::f overloads:
+ </p>
+<pre class="programlisting"><span class="keyword">bool</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx1</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">char</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
+<span class="keyword">int</span> <span class="special">(</span><span class="identifier">X</span><span class="special">::*</span><span class="identifier">fx2</span><span class="special">)(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
+</pre>
+<p>
+ Then...
+ </p>
+<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">,</span> <span class="identifier">xf_overloads</span><span class="special">());</span>
+<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
+</pre>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/hello.html b/libs/python/doc/tutorial/doc/html/python/hello.html
new file mode 100644
index 000000000..b78573826
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/hello.html
@@ -0,0 +1,195 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Building Hello World</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="next" href="exposing.html" title="Exposing Classes">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.hello"></a>Building Hello World</h2></div></div></div>
+<h3>
+<a name="hello.from_start_to_finish"></a>
+ From Start To Finish
+ </h3>
+<p>
+ 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 will outline the steps necessary
+ to achieve that. We will use the build tool that comes bundled with every boost
+ distribution: <span class="bold"><strong>bjam</strong></span>.
+ </p>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top">
+<p>
+ <span class="bold"><strong>Building without bjam</strong></span>
+ </p>
+<p>
+ 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 <code class="literal">bjam</code>.
+ </p>
+<p>
+ Take note however that the preferred build tool for Boost.Python is bjam.
+ There are so many ways to set up the build incorrectly. Experience shows
+ that 90% of the "I can't build Boost.Python" problems come from
+ people who had to use a different tool.
+ </p>
+</td></tr>
+</table></div>
+<p>
+ We will 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: <a href="../../../../building.html" target="_top">building.html</a>. After
+ this brief <span class="emphasis"><em>bjam</em></span> tutorial, we should have built the DLLs
+ and run a python program using the extension.
+ </p>
+<p>
+ The tutorial example can be found in the directory: <code class="literal">libs/python/example/tutorial</code>.
+ There, you can find:
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ hello.cpp
+ </li>
+<li class="listitem">
+ hello.py
+ </li>
+<li class="listitem">
+ Jamroot
+ </li>
+</ul></div>
+<p>
+ The <code class="literal">hello.cpp</code> file is our C++ hello world example. The
+ <code class="literal">Jamroot</code> is a minimalist <span class="emphasis"><em>bjam</em></span> script
+ that builds the DLLs for us. Finally, <code class="literal">hello.py</code> is our Python
+ program that uses the extension in <code class="literal">hello.cpp</code>.
+ </p>
+<p>
+ Before anything else, you should have the bjam executable in your boost directory
+ or somewhere in your path such that <code class="literal">bjam</code> can be executed
+ in the command line. Pre-built Boost.Jam executables are available for most
+ platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
+ </p>
+<h3>
+<a name="hello.let_s_jam_"></a>
+ Let's Jam!
+ </h3>
+<p>
+ <span class="inlinemediaobject"><img src="../images/jam.png" alt="jam"></span>
+ </p>
+<p>
+ <a href="../../../../../example/tutorial/Jamroot" target="_top">Here</a> is our minimalist
+ Jamroot file. Simply copy the file and tweak <code class="literal">use-project boost</code>
+ to where your boost root directory is and your OK.
+ </p>
+<p>
+ The comments contained in the Jamrules file above should be sufficient to get
+ you going.
+ </p>
+<h3>
+<a name="hello.running_bjam"></a>
+ Running bjam
+ </h3>
+<p>
+ <span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
+ interpreter.
+ </p>
+<div class="blockquote"><blockquote class="blockquote"><p>
+ Start it up.
+ </p></blockquote></div>
+<p>
+ A file called user-config.jam in your home directory is used to configure your
+ tools. In Windows, your home directory can be found by typing:
+ </p>
+<pre class="programlisting">ECHO %HOMEDRIVE%%HOMEPATH%
+</pre>
+<p>
+ into a command prompt window. Your file should at least have the rules for
+ your compiler and your python installation. A specific example of this on Windows
+ would be:
+ </p>
+<pre class="programlisting"># MSVC configuration
+using msvc : 8.0 ;
+
+# Python configuration
+using python : 2.4 : C:<span class="emphasis"><em>dev/tools/Python</em></span> ;
+</pre>
+<p>
+ The first rule tells Bjam to use the MSVC 8.0 compiler and associated tools.
+ The second rule provides information on Python, its version and where it is
+ located. The above assumes that the Python installation is in <code class="literal">C:<span class="emphasis"><em>dev/tools\/Python</em></span></code>.
+ If you have one fairly "standard" python installation for your platform,
+ you might not need to do this.
+ </p>
+<p>
+ Now we are ready... Be sure to <code class="literal">cd</code> to <code class="literal">libs/python/example/tutorial</code>
+ where the tutorial <code class="literal">"hello.cpp"</code> and the <code class="literal">"Jamroot"</code>
+ is situated.
+ </p>
+<p>
+ Finally:
+ </p>
+<pre class="programlisting"><span class="identifier">bjam</span>
+</pre>
+<p>
+ It should be building now:
+ </p>
+<pre class="programlisting">cd C:\dev\boost\libs\python\example\tutorial
+bjam
+...patience...
+...found 1101 targets...
+...updating 35 targets...
+</pre>
+<p>
+ And so on... Finally:
+ </p>
+<pre class="programlisting">Creating library <span class="emphasis"><em>path-to-boost_python.dll</em></span>
+ Creating library /path-to-hello_ext.exp/
+**passed** ... hello.test
+...updated 35 targets...
+</pre>
+<p>
+ Or something similar. If all is well, you should now have built the DLLs and
+ run the Python program.
+ </p>
+<div class="blockquote"><blockquote class="blockquote"><p>
+ <span class="bold"><strong>There you go... Have fun!</strong></span>
+ </p></blockquote></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/iterators.html b/libs/python/doc/tutorial/doc/html/python/iterators.html
new file mode 100644
index 000000000..9fb402b6b
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/iterators.html
@@ -0,0 +1,187 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Iterators</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="embedding.html" title="Embedding">
+<link rel="next" href="exception.html" title="Exception Translation">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.iterators"></a>Iterators</h2></div></div></div>
+<p>
+ In C++, and STL in particular, we see iterators everywhere. Python also has
+ iterators, but these are two very different beasts.
+ </p>
+<p>
+ <span class="bold"><strong>C++ iterators:</strong></span>
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ C++ has 5 type categories (random-access, bidirectional, forward, input,
+ output)
+ </li>
+<li class="listitem">
+ There are 2 Operation categories: reposition, access
+ </li>
+<li class="listitem">
+ A pair of iterators is needed to represent a (first/last) range.
+ </li>
+</ul></div>
+<p>
+ <span class="bold"><strong>Python Iterators:</strong></span>
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ 1 category (forward)
+ </li>
+<li class="listitem">
+ 1 operation category (next())
+ </li>
+<li class="listitem">
+ Raises StopIteration exception at end
+ </li>
+</ul></div>
+<p>
+ The typical Python iteration protocol: <code class="literal"><span class="bold"><strong>for y
+ in x...</strong></span></code> is as follows:
+ </p>
+<pre class="programlisting"><span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">__iter__</span><span class="special">()</span> <span class="comment"># get iterator</span>
+<span class="keyword">try</span><span class="special">:</span>
+ <span class="keyword">while</span> <span class="number">1</span><span class="special">:</span>
+ <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">()</span> <span class="comment"># get each item</span>
+ <span class="special">...</span> <span class="comment"># process y</span>
+<span class="keyword">except</span> <span class="identifier">StopIteration</span><span class="special">:</span> <span class="keyword">pass</span> <span class="comment"># iterator exhausted</span>
+</pre>
+<p>
+ Boost.Python provides some mechanisms to make C++ iterators play along nicely
+ as Python iterators. What we need to do is to produce appropriate <code class="computeroutput"><span class="identifier">__iter__</span></code> function from C++ iterators that
+ is compatible with the Python iteration protocol. For example:
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;();</span>
+<span class="identifier">object</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">get_iterator</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
+<span class="identifier">object</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">iter</span><span class="special">.</span><span class="identifier">next</span><span class="special">();</span>
+</pre>
+<p>
+ Or for use in class_&lt;&gt;:
+ </p>
+<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;())</span>
+</pre>
+<p>
+ <span class="bold"><strong>range</strong></span>
+ </p>
+<p>
+ We can create a Python savvy iterator using the range function:
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ range(start, finish)
+ </li>
+<li class="listitem">
+ range&lt;Policies,Target&gt;(start, finish)
+ </li>
+</ul></div>
+<p>
+ Here, start/finish may be one of:
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ member data pointers
+ </li>
+<li class="listitem">
+ member function pointers
+ </li>
+<li class="listitem">
+ adaptable function object (use Target parameter)
+ </li>
+</ul></div>
+<p>
+ <span class="bold"><strong>iterator</strong></span>
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ iterator&lt;T, Policies&gt;()
+ </li></ul></div>
+<p>
+ Given a container <code class="literal">T</code>, iterator is a shortcut that simply
+ calls <code class="literal">range</code> with &amp;T::begin, &amp;T::end.
+ </p>
+<p>
+ Let's put this into action... Here's an example from some hypothetical bogon
+ Particle accelerator code:
+ </p>
+<pre class="programlisting"><span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
+<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
+ <span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
+<span class="keyword">for</span> <span class="identifier">y</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span>
+ <span class="identifier">count</span><span class="special">(</span><span class="identifier">y</span><span class="special">)</span>
+</pre>
+<p>
+ Now, our C++ Wrapper:
+ </p>
+<pre class="programlisting"><span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="string">"Field"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_end</span><span class="special">))</span>
+ <span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
+</pre>
+<p>
+ <span class="bold"><strong>stl_input_iterator</strong></span>
+ </p>
+<p>
+ So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes
+ we wish to go the other way, though: we'd like to pass a Python sequence to
+ an STL algorithm or use it to initialize an STL container. We need to make
+ a Python iterator look like an STL iterator. For that, we use <code class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special">&lt;&gt;</span></code>.
+ Consider how we might implement a function that exposes <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">assign</span><span class="special">()</span></code> to Python:
+ </p>
+<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
+<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
+ <span class="comment">// Turn a Python sequence into an STL input range</span>
+ <span class="identifier">stl_input_iterator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
+ <span class="identifier">l</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span>
+<span class="special">}</span>
+
+<span class="comment">// Part of the wrapper for list&lt;int&gt;</span>
+<span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;(</span><span class="string">"list_int"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"assign"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">list_assign</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;)</span>
+ <span class="comment">// ...</span>
+ <span class="special">;</span>
+</pre>
+<p>
+ Now in Python, we can assign any integer sequence to <code class="computeroutput"><span class="identifier">list_int</span></code>
+ objects:
+ </p>
+<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
+<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
+</pre>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/object.html b/libs/python/doc/tutorial/doc/html/python/object.html
new file mode 100644
index 000000000..7bc2aa255
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/object.html
@@ -0,0 +1,360 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>Object Interface</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="functions.html" title="Functions">
+<link rel="next" href="embedding.html" title="Embedding">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.object"></a>Object Interface</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section"><a href="object.html#python.basic_interface">Basic Interface</a></span></dt>
+<dt><span class="section"><a href="object.html#python.derived_object_types">Derived Object types</a></span></dt>
+<dt><span class="section"><a href="object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
+<dt><span class="section"><a href="object.html#python.enums">Enums</a></span></dt>
+<dt><span class="section"><a href="object.html#python.creating_python_object">Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code></a></span></dt>
+</dl></div>
+<p>
+ 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 <code class="literal">object</code>. We will see in this
+ chapter how to deal with Python objects.
+ </p>
+<p>
+ 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++ <code class="literal">object</code>s are as close as possible to Python. This should
+ minimize the learning curve significantly.
+ </p>
+<p>
+ <span class="inlinemediaobject"><img src="../images/python.png" alt="python"></span>
+ </p>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.basic_interface"></a>Basic Interface</h3></div></div></div>
+<p>
+ Class <code class="literal">object</code> wraps <code class="literal">PyObject*</code>. All the
+ intricacies of dealing with <code class="literal">PyObject</code>s such as managing
+ reference counting are handled by the <code class="literal">object</code> class. C++
+ object interoperability is seamless. Boost.Python C++ <code class="literal">object</code>s
+ can in fact be explicitly constructed from any C++ object.
+ </p>
+<p>
+ To illustrate, this Python code snippet:
+ </p>
+<pre class="programlisting"><span class="keyword">def</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">):</span>
+ <span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">'foo'</span><span class="special">):</span>
+ <span class="identifier">x</span><span class="special">[</span><span class="number">3</span><span class="special">:</span><span class="number">7</span><span class="special">]</span> <span class="special">=</span> <span class="string">'bar'</span>
+ <span class="keyword">else</span><span class="special">:</span>
+ <span class="identifier">x</span><span class="special">.</span><span class="identifier">items</span> <span class="special">+=</span> <span class="identifier">y</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="identifier">x</span><span class="special">)</span>
+ <span class="keyword">return</span> <span class="identifier">x</span>
+
+<span class="keyword">def</span> <span class="identifier">getfunc</span><span class="special">():</span>
+ <span class="keyword">return</span> <span class="identifier">f</span><span class="special">;</span>
+</pre>
+<p>
+ Can be rewritten in C++ using Boost.Python facilities this way:
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">object</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span>
+ <span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</span><span class="special">)</span>
+ <span class="identifier">x</span><span class="special">.</span><span class="identifier">slice</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">7</span><span class="special">)</span> <span class="special">=</span> <span class="string">"bar"</span><span class="special">;</span>
+ <span class="keyword">else</span>
+ <span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"items"</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">y</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="identifier">x</span><span class="special">);</span>
+ <span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span>
+<span class="special">}</span>
+<span class="identifier">object</span> <span class="identifier">getfunc</span><span class="special">()</span> <span class="special">{</span>
+ <span class="keyword">return</span> <span class="identifier">object</span><span class="special">(</span><span class="identifier">f</span><span class="special">);</span>
+<span class="special">}</span>
+</pre>
+<p>
+ 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.
+ </p>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.derived_object_types"></a>Derived Object types</h3></div></div></div>
+<p>
+ Boost.Python comes with a set of derived <code class="literal">object</code> types
+ corresponding to that of Python's:
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ list
+ </li>
+<li class="listitem">
+ dict
+ </li>
+<li class="listitem">
+ tuple
+ </li>
+<li class="listitem">
+ str
+ </li>
+<li class="listitem">
+ long_
+ </li>
+<li class="listitem">
+ enum
+ </li>
+</ul></div>
+<p>
+ These derived <code class="literal">object</code> types act like real Python types.
+ For instance:
+ </p>
+<pre class="programlisting"><span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==&gt;</span> <span class="string">"1"</span>
+</pre>
+<p>
+ Wherever appropriate, a particular derived <code class="literal">object</code> has
+ corresponding Python type's methods. For instance, <code class="literal">dict</code>
+ has a <code class="literal">keys()</code> method:
+ </p>
+<pre class="programlisting"><span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
+</pre>
+<p>
+ <code class="literal">make_tuple</code> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
+ Example:
+ </p>
+<pre class="programlisting"><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
+</pre>
+<p>
+ In C++, when Boost.Python <code class="literal">object</code>s are used as arguments
+ to functions, subtype matching is required. For example, when a function
+ <code class="literal">f</code>, as declared below, is wrapped, it will only accept
+ instances of Python's <code class="literal">str</code> type and subtypes.
+ </p>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">object</span> <span class="identifier">n2</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"upper"</span><span class="special">)();</span> <span class="comment">// NAME = name.upper()</span>
+ <span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span> <span class="comment">// better</span>
+ <span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
+<span class="special">}</span>
+</pre>
+<p>
+ In finer detail:
+ </p>
+<pre class="programlisting"><span class="identifier">str</span> <span class="identifier">NAME</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">.</span><span class="identifier">upper</span><span class="special">();</span>
+</pre>
+<p>
+ Illustrates that we provide versions of the str type's methods as C++ member
+ functions.
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</span> <span class="special">%</span> <span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">NAME</span><span class="special">,</span><span class="identifier">name</span><span class="special">);</span>
+</pre>
+<p>
+ Demonstrates that you can write the C++ equivalent of <code class="literal">"format"
+ % x,y,z</code> in Python, which is useful since there's no easy way to
+ do that in std C++.
+ </p>
+<div class="sidebar">
+<div class="titlepage"></div>
+<p>
+ <span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><strong>Beware</strong></span> the common pitfall
+ of forgetting that the constructors of most of Python's mutable types make
+ copies, just as in Python.
+ </p>
+</div>
+<p>
+ Python:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">dict</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">__dict__</span><span class="special">)</span> <span class="comment"># copies x.__dict__</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">d</span><span class="special">[</span><span class="string">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span> <span class="comment"># modifies the copy</span>
+</pre>
+<p>
+ C++:
+ </p>
+<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__</span>
+<span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy</span>
+</pre>
+<h3>
+<a name="derived_object_types.class__lt_t_gt__as_objects"></a>
+ class_&lt;T&gt; as objects
+ </h3>
+<p>
+ Due to the dynamic nature of Boost.Python objects, any <code class="literal">class_&lt;T&gt;</code>
+ may also be one of these types! The following code snippet wraps the class
+ (type) object.
+ </p>
+<p>
+ We can use this to create wrapped instances. Example:
+ </p>
+<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&gt;(</span><span class="string">"Vec2"</span><span class="special">,</span> <span class="identifier">init</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;())</span>
+ <span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"length"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">length</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"angle"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">Point</span><span class="special">::</span><span class="identifier">angle</span><span class="special">)</span>
+ <span class="special">)(</span><span class="number">3.0</span><span class="special">,</span> <span class="number">4.0</span><span class="special">);</span>
+
+<span class="identifier">assert</span><span class="special">(</span><span class="identifier">vec345</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">)</span> <span class="special">==</span> <span class="number">5.0</span><span class="special">);</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.extracting_c___objects"></a>Extracting C++ objects</h3></div></div></div>
+<p>
+ At some point, we will need to get C++ values out of object instances. This
+ can be achieved with the <code class="literal">extract&lt;T&gt;</code> function. Consider
+ the following:
+ </p>
+<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">);</span> <span class="comment">// compile error</span>
+</pre>
+<p>
+ In the code above, we got a compiler error because Boost.Python <code class="literal">object</code>
+ can't be implicitly converted to <code class="literal">double</code>s. Instead, what
+ we wanted to do above can be achieved by writing:
+ </p>
+<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="identifier">o</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"length"</span><span class="special">));</span>
+<span class="identifier">Vec2</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;(</span><span class="identifier">o</span><span class="special">);</span>
+<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span> <span class="special">==</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">length</span><span class="special">());</span>
+</pre>
+<p>
+ The first line attempts to extract the "length" attribute of the
+ Boost.Python <code class="literal">object</code>. The second line attempts to <span class="emphasis"><em>extract</em></span>
+ the <code class="literal">Vec2</code> object from held by the Boost.Python <code class="literal">object</code>.
+ </p>
+<p>
+ Take note that we said "attempt to" above. What if the Boost.Python
+ <code class="literal">object</code> does not really hold a <code class="literal">Vec2</code>
+ type? This is certainly a possibility considering the dynamic nature of Python
+ <code class="literal">object</code>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:
+ </p>
+<pre class="programlisting"><span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">Vec2</span><span class="special">&amp;&gt;</span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span>
+<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">check</span><span class="special">())</span> <span class="special">{</span>
+ <span class="identifier">Vec2</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">();</span> <span class="special">...</span>
+</pre>
+<p>
+ <span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <code class="literal">extract&lt;T&gt;</code>
+ facility in fact solves the mutable copying problem:
+ </p>
+<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special">&lt;</span><span class="identifier">dict</span><span class="special">&gt;(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span>
+<span class="identifier">d</span><span class="special">[</span><span class="string">"whatever"</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies x.__dict__ !</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.enums"></a>Enums</h3></div></div></div>
+<p>
+ Boost.Python has a nifty facility to capture and wrap C++ enums. While Python
+ has no <code class="literal">enum</code> type, we'll often want to expose our C++ enums
+ to Python as an <code class="literal">int</code>. 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:
+ </p>
+<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
+</pre>
+<p>
+ the construct:
+ </p>
+<pre class="programlisting"><span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">choice</span><span class="special">&gt;(</span><span class="string">"choice"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
+ <span class="special">;</span>
+</pre>
+<p>
+ can be used to expose to Python. The new enum type is created in the current
+ <code class="literal">scope()</code>, which is usually the current module. The snippet
+ above creates a Python class derived from Python's <code class="literal">int</code>
+ type which is associated with the C++ type passed as its first parameter.
+ </p>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top">
+<p>
+ <span class="bold"><strong>what is a scope?</strong></span>
+ </p>
+<p>
+ 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 <a href="../../../../v2/scope.html" target="_top">here</a>.
+ </p>
+</td></tr>
+</table></div>
+<p>
+ You can access those values in Python as
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
+<span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
+</pre>
+<p>
+ where my_module is the module where the enum is declared. You can also create
+ a new scope around a class:
+ </p>
+<pre class="programlisting"><span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">&gt;(</span><span class="string">"X"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
+ <span class="special">.</span><span class="identifier">def</span><span class="special">(</span> <span class="special">...</span> <span class="special">)</span>
+ <span class="special">;</span>
+
+<span class="comment">// Expose X::nested as X.nested</span>
+<span class="identifier">enum_</span><span class="special">&lt;</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">&gt;(</span><span class="string">"nested"</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</span><span class="special">,</span> <span class="identifier">red</span><span class="special">)</span>
+ <span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
+ <span class="special">;</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.creating_python_object"></a>Creating <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> from <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code>
+</h3></div></div></div>
+<p>
+ When you want a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span></code> to manage a pointer to <code class="computeroutput"><span class="identifier">PyObject</span><span class="special">*</span></code>
+ pyobj one does:
+ </p>
+<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span> <span class="identifier">o</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span><span class="identifier">pyobj</span><span class="special">));</span>
+</pre>
+<p>
+ In this case, the <code class="computeroutput"><span class="identifier">o</span></code> object,
+ manages the <code class="computeroutput"><span class="identifier">pyobj</span></code>, it won&#8217;t
+ increase the reference count on construction.
+ </p>
+<p>
+ Otherwise, to use a borrowed reference:
+ </p>
+<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">object</span> <span class="identifier">o</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">handle</span><span class="special">&lt;&gt;(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">borrowed</span><span class="special">(</span><span class="identifier">pyobj</span><span class="special">)));</span>
+</pre>
+<p>
+ In this case, <code class="computeroutput"><span class="identifier">Py_INCREF</span></code> is
+ called, so <code class="computeroutput"><span class="identifier">pyobj</span></code> is not destructed
+ when object o goes out of scope.
+ </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/html/python/techniques.html b/libs/python/doc/tutorial/doc/html/python/techniques.html
new file mode 100644
index 000000000..34cfc4442
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/html/python/techniques.html
@@ -0,0 +1,440 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
+<title>General Techniques</title>
+<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
+<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;python 2.0">
+<link rel="prev" href="exception.html" title="Exception Translation">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../../../index.html">Home</a></td>
+<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
+<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
+<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
+<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="python.techniques"></a>General Techniques</h2></div></div></div>
+<div class="toc"><dl>
+<dt><span class="section"><a href="techniques.html#python.creating_packages">Creating Packages</a></span></dt>
+<dt><span class="section"><a href="techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
+<dt><span class="section"><a href="techniques.html#python.reducing_compiling_time">Reducing Compiling Time</a></span></dt>
+</dl></div>
+<p>
+ Here are presented some useful techniques that you can use while wrapping code
+ with Boost.Python.
+ </p>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.creating_packages"></a>Creating Packages</h3></div></div></div>
+<p>
+ 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 <a href="http://www.python.org/doc/current/tut/node8.html" target="_top">Python
+ Tutorial</a>.
+ </p>
+<p>
+ 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.
+ </p>
+<p>
+ 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)
+ <code class="literal">sounds</code>. Our library already has a neat C++ namespace hierarchy,
+ like so:
+ </p>
+<pre class="programlisting"><span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span>
+<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span>
+<span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span>
+</pre>
+<p>
+ We would like to present this same hierarchy to the Python user, allowing
+ him to write code like this:
+ </p>
+<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
+<span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span> <span class="comment"># echo is a C++ function</span>
+</pre>
+<p>
+ The first step is to write the wrapping code. We have to export each module
+ separately with Boost.Python, like this:
+ </p>
+<pre class="programlisting"><span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">core</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span> <span class="identifier">namespace</span> <span class="special">*/</span>
+ <span class="special">...</span>
+<span class="special">}</span>
+
+<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">io</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">io</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span> <span class="identifier">namespace</span> <span class="special">*/</span>
+ <span class="special">...</span>
+<span class="special">}</span>
+
+<span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">filters</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">*/</span>
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">filters</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span> <span class="identifier">namespace</span> <span class="special">*/</span>
+ <span class="special">...</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Compiling these files will generate the following Python extensions: <code class="literal">core.pyd</code>,
+ <code class="literal">io.pyd</code> and <code class="literal">filters.pyd</code>.
+ </p>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ The extension <code class="literal">.pyd</code> is used for python extension modules,
+ which are just shared libraries. Using the default for your system, like
+ <code class="literal">.so</code> for Unix and <code class="literal">.dll</code> for Windows,
+ works just as well.
+ </p></td></tr>
+</table></div>
+<p>
+ Now, we create this directory structure for our Python package:
+ </p>
+<pre class="programlisting">sounds/
+ __init__.py
+ core.pyd
+ filters.pyd
+ io.pyd
+</pre>
+<p>
+ The file <code class="literal">__init__.py</code> is what tells Python that the directory
+ <code class="literal">sounds/</code> is actually a Python package. It can be a empty
+ file, but can also perform some magic, that will be shown later.
+ </p>
+<p>
+ Now our package is ready. All the user has to do is put <code class="literal">sounds</code>
+ into his <a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000" target="_top">PYTHONPATH</a>
+ and fire up the interpreter:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="string">'file.mp3'</span><span class="special">)</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">new_sound</span> <span class="special">=</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">,</span> <span class="number">1.0</span><span class="special">)</span>
+</pre>
+<p>
+ Nice heh?
+ </p>
+<p>
+ This is the simplest way to create hierarchies of packages, but it is not
+ very flexible. What if we want to add a <span class="emphasis"><em>pure</em></span> 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.
+ </p>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="comment">/* file core.cpp */</span>
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_core</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="special">...</span>
+ <span class="comment">/* export everything in the sounds::core namespace */</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Note that we added an underscore to the module name. The filename will have
+ to be changed to <code class="literal">_core.pyd</code> as well, and we do the same
+ to the other extension modules. Now, we change our package hierarchy like
+ so:
+ </p>
+<pre class="programlisting">sounds/
+ __init__.py
+ core/
+ __init__.py
+ <span class="underline">core.pyd
+ filters/
+ \</span>_init__.py
+ <span class="underline">filters.pyd
+ io/
+ \</span>_init__.py
+ _io.pyd
+</pre>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">_core</span><span class="special">.</span><span class="identifier">foo</span><span class="special">(...)</span>
+</pre>
+<p>
+ which is not what we want. But here enters the <code class="literal">__init__.py</code>
+ magic: everything that is brought to the <code class="literal">__init__.py</code> namespace
+ can be accessed directly by the user. So, all we have to do is bring the
+ entire namespace from <code class="literal">_core.pyd</code> to <code class="literal">core/__init__.py</code>.
+ So add this line of code to <code class="literal">sounds/core/__init__.py</code>:
+ </p>
+<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
+</pre>
+<p>
+ We do the same for the other packages. Now the user accesses the functions
+ and classes in the extension modules like before:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(...)</span>
+</pre>
+<p>
+ 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 <span class="emphasis"><em>pure</em></span>
+ Python function, <code class="literal">echo_noise</code>, to the <code class="literal">filters</code>
+ package. This function applies both the <code class="literal">echo</code> and <code class="literal">noise</code>
+ filters in sequence in the given <code class="literal">sound</code> object. We create
+ a file named <code class="literal">sounds/filters/echo_noise.py</code> and code our
+ function:
+ </p>
+<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">_filters</span>
+<span class="keyword">def</span> <span class="identifier">echo_noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">):</span>
+ <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">echo</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
+ <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">_filters</span><span class="special">.</span><span class="identifier">noise</span><span class="special">(</span><span class="identifier">sound</span><span class="special">)</span>
+ <span class="keyword">return</span> <span class="identifier">s</span>
+</pre>
+<p>
+ Next, we add this line to <code class="literal">sounds/filters/__init__.py</code>:
+ </p>
+<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
+</pre>
+<p>
+ And that's it. The user now accesses this function like any other function
+ from the <code class="literal">filters</code> package:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span><span class="special">.</span><span class="identifier">echo_noise</span><span class="special">(...)</span>
+</pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.extending_wrapped_objects_in_python"></a>Extending Wrapped Objects in Python</h3></div></div></div>
+<p>
+ Thanks to Python's flexibility, you can easily add new methods to a class,
+ even after it was already created:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">class</span> <span class="identifier">C</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span> <span class="keyword">pass</span>
+<span class="special">&gt;&gt;&gt;</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="comment"># a regular function</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="keyword">def</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span> <span class="keyword">return</span> <span class="string">'A C instance!'</span>
+<span class="special">&gt;&gt;&gt;</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="comment"># now we turn it in a member function</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">C</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">C_str</span>
+<span class="special">&gt;&gt;&gt;</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">C</span><span class="special">()</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">c</span>
+<span class="identifier">A</span> <span class="identifier">C</span> <span class="identifier">instance</span><span class="special">!</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">C_str</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span>
+<span class="identifier">A</span> <span class="identifier">C</span> <span class="identifier">instance</span><span class="special">!</span>
+</pre>
+<p>
+ Yes, Python rox. <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
+ </p>
+<p>
+ We can do the same with classes that were wrapped with Boost.Python. Suppose
+ we have a class <code class="literal">point</code> in C++:
+ </p>
+<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">point</span> <span class="special">{...};</span>
+
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ If we are using the technique from the previous session, <a class="link" href="techniques.html#python.creating_packages" title="Creating Packages">Creating
+ Packages</a>, we can code directly into <code class="literal">geom/__init__.py</code>:
+ </p>
+<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
+
+<span class="comment"># a regular function</span>
+<span class="keyword">def</span> <span class="identifier">point_str</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
+ <span class="keyword">return</span> <span class="identifier">str</span><span class="special">((</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">))</span>
+
+<span class="comment"># now we turn it into a member function</span>
+<span class="identifier">point</span><span class="special">.</span><span class="identifier">__str__</span> <span class="special">=</span> <span class="identifier">point_str</span>
+</pre>
+<p>
+ <span class="bold"><strong>All</strong></span> point instances created from C++ will
+ also have this member function! This technique has several advantages:
+ </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+ Cut down compile times to zero for these additional functions
+ </li>
+<li class="listitem">
+ Reduce the memory footprint to virtually zero
+ </li>
+<li class="listitem">
+ Minimize the need to recompile
+ </li>
+<li class="listitem">
+ Rapid prototyping (you can move the code to C++ if required without changing
+ the interface)
+ </li>
+</ul></div>
+<p>
+ 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.
+ </p>
+<pre class="programlisting"><span class="comment"># The one Boost.Python uses for all wrapped classes.</span>
+<span class="comment"># You can use here any class exported by Boost instead of "point"</span>
+<span class="identifier">BoostPythonMetaclass</span> <span class="special">=</span> <span class="identifier">point</span><span class="special">.</span><span class="identifier">__class__</span>
+
+<span class="keyword">class</span> <span class="identifier">injector</span><span class="special">(</span><span class="identifier">object</span><span class="special">):</span>
+ <span class="keyword">class</span> <span class="identifier">__metaclass__</span><span class="special">(</span><span class="identifier">BoostPythonMetaclass</span><span class="special">):</span>
+ <span class="keyword">def</span> <span class="identifier">__init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">,</span> <span class="identifier">dict</span><span class="special">):</span>
+ <span class="keyword">for</span> <span class="identifier">b</span> <span class="keyword">in</span> <span class="identifier">bases</span><span class="special">:</span>
+ <span class="keyword">if</span> <span class="identifier">type</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span> <span class="keyword">not</span> <span class="keyword">in</span> <span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">type</span><span class="special">):</span>
+ <span class="keyword">for</span> <span class="identifier">k</span><span class="special">,</span><span class="identifier">v</span> <span class="keyword">in</span> <span class="identifier">dict</span><span class="special">.</span><span class="identifier">items</span><span class="special">():</span>
+ <span class="identifier">setattr</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">k</span><span class="special">,</span><span class="identifier">v</span><span class="special">)</span>
+ <span class="keyword">return</span> <span class="identifier">type</span><span class="special">.</span><span class="identifier">__init__</span><span class="special">(</span><span class="identifier">self</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">bases</span><span class="special">,</span> <span class="identifier">dict</span><span class="special">)</span>
+
+<span class="comment"># inject some methods in the point foo</span>
+<span class="keyword">class</span> <span class="identifier">more_point</span><span class="special">(</span><span class="identifier">injector</span><span class="special">,</span> <span class="identifier">point</span><span class="special">):</span>
+ <span class="keyword">def</span> <span class="identifier">__repr__</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
+ <span class="keyword">return</span> <span class="string">'Point(x=%s, y=%s)'</span> <span class="special">%</span> <span class="special">(</span><span class="identifier">self</span><span class="special">.</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">y</span><span class="special">)</span>
+ <span class="keyword">def</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
+ <span class="keyword">print</span> <span class="string">'foo!'</span>
+</pre>
+<p>
+ Now let's see how it got:
+ </p>
+<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">point</span><span class="special">()</span>
+<span class="identifier">Point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">10</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">10</span><span class="special">)</span>
+<span class="special">&gt;&gt;&gt;</span> <span class="identifier">point</span><span class="special">().</span><span class="identifier">foo</span><span class="special">()</span>
+<span class="identifier">foo</span><span class="special">!</span>
+</pre>
+<p>
+ Another useful idea is to replace constructors with factory functions:
+ </p>
+<pre class="programlisting"><span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
+
+<span class="keyword">def</span> <span class="identifier">point</span><span class="special">(</span><span class="identifier">x</span><span class="special">=</span><span class="number">0</span><span class="special">,</span> <span class="identifier">y</span><span class="special">=</span><span class="number">0</span><span class="special">):</span>
+ <span class="keyword">return</span> <span class="identifier">_point</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">y</span><span class="special">)</span>
+</pre>
+<p>
+ 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.
+ </p>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="python.reducing_compiling_time"></a>Reducing Compiling Time</h3></div></div></div>
+<p>
+ 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:
+ </p>
+<pre class="programlisting"><span class="comment">/* file point.cpp */</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+
+<span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">()</span>
+<span class="special">{</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span>
+<span class="special">}</span>
+
+<span class="comment">/* file triangle.cpp */</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+
+<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">()</span>
+<span class="special">{</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">&gt;(</span><span class="string">"triangle"</span><span class="special">)...;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Now you create a file <code class="literal">main.cpp</code>, which contains the <code class="literal">BOOST_PYTHON_MODULE</code>
+ macro, and call the various export functions inside it.
+ </p>
+<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">();</span>
+<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">();</span>
+
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">export_point</span><span class="special">();</span>
+ <span class="identifier">export_triangle</span><span class="special">();</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Compiling and linking together all this files produces the same result as
+ the usual approach:
+ </p>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>
+
+<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">_geom</span><span class="special">)</span>
+<span class="special">{</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">&gt;(</span><span class="string">"point"</span><span class="special">)...;</span>
+ <span class="identifier">class_</span><span class="special">&lt;</span><span class="identifier">triangle</span><span class="special">&gt;(</span><span class="string">"triangle"</span><span class="special">)...;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ but the memory is kept under control.
+ </p>
+<p>
+ 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.
+ </p>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
+ take a look at the <code class="literal">--multiple</code> option, that generates
+ the wrappers in various files as demonstrated here.
+ </p></td></tr>
+</table></div>
+<div class="note"><table border="0" summary="Note">
+<tr>
+<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
+<th align="left">Note</th>
+</tr>
+<tr><td align="left" valign="top"><p>
+ This method is useful too if you are getting the error message <span class="emphasis"><em>"fatal
+ error C1204:Compiler limit:internal structure overflow"</em></span>
+ when compiling a large source file, as explained in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.
+ </p></td></tr>
+</table></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005 Joel
+ de Guzman, David Abrahams<p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
+ http://www.boost.org/LICENSE_1_0.txt </a>)
+ </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a>
+</div>
+</body>
+</html>
diff --git a/libs/python/doc/tutorial/doc/tutorial.qbk b/libs/python/doc/tutorial/doc/tutorial.qbk
new file mode 100644
index 000000000..10a452200
--- /dev/null
+++ b/libs/python/doc/tutorial/doc/tutorial.qbk
@@ -0,0 +1,1985 @@
+[library python
+ [version 2.0]
+ [authors [de Guzman, Joel], [Abrahams, David]]
+ [copyright 2002 2003 2004 2005 Joel de Guzman, David Abrahams]
+ [category inter-language support]
+ [purpose
+ Reflects C++ classes and functions into Python
+ ]
+ [license
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ <ulink url="http://www.boost.org/LICENSE_1_0.txt">
+ http://www.boost.org/LICENSE_1_0.txt
+ </ulink>)
+ ]
+]
+
+[/ QuickBook Document version 0.9 ]
+
+[def __note__ [$images/note.png]]
+[def __alert__ [$images/alert.png]]
+[def __tip__ [$images/tip.png]]
+[def :-) [$images/smiley.png]]
+[def __jam__ [$images/jam.png]]
+
+[section 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 <boost/python.hpp>
+
+ BOOST_PYTHON_MODULE(hello_ext)
+ {
+ using namespace boost::python;
+ 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:
+
+[python]
+
+ >>> import hello_ext
+ >>> print hello_ext.greet()
+ hello, world
+
+[c++]
+
+[:['[*Next stop... Building your Hello World module from start to finish...]]]
+
+[endsect]
+[section:hello 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 will outline the steps
+necessary to achieve that. We will use the build tool that comes bundled
+with every boost distribution: [*bjam].
+
+[note [*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].
+
+Take note however that the preferred build tool for Boost.Python is bjam.
+There are so many ways to set up the build incorrectly. Experience shows
+that 90% of the "I can't build Boost.Python" problems come from people
+who had to use a different tool.
+]
+
+We will 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
+the DLLs and run a python program using the extension.
+
+The tutorial example can be found in the directory:
+[^libs/python/example/tutorial]. There, you can find:
+
+* hello.cpp
+* hello.py
+* Jamroot
+
+The [^hello.cpp] file is our C++ hello world example. The [^Jamroot] is
+a minimalist ['bjam] script that builds the DLLs for us. Finally,
+[^hello.py] is our Python program that uses the extension in
+[^hello.cpp].
+
+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. The complete list of Bjam executables can be found
+[@http://sourceforge.net/project/showfiles.php?group_id=7586 here].
+
+[h2 Let's Jam!]
+__jam__
+
+[@../../../../example/tutorial/Jamroot Here] is our minimalist Jamroot
+file. Simply copy the file and tweak [^use-project boost] to where your
+boost root directory is and your OK.
+
+The comments contained in the Jamrules file above should be sufficient
+to get you going.
+
+[h2 Running bjam]
+
+['bjam] is run using your operating system's command line interpreter.
+
+[:Start it up.]
+
+A file called user-config.jam in your home directory is used to
+configure your tools. In Windows, your home directory can be found by
+typing:
+
+[pre
+ECHO %HOMEDRIVE%%HOMEPATH%
+]
+
+into a command prompt window. Your file should at least have the rules
+for your compiler and your python installation. A specific example of
+this on Windows would be:
+
+[pre
+# MSVC configuration
+using msvc : 8.0 ;
+
+# Python configuration
+using python : 2.4 : C:/dev/tools/Python/ ;
+]
+
+The first rule tells Bjam to use the MSVC 8.0 compiler and associated
+tools. The second rule provides information on Python, its version and
+where it is located. The above assumes that the Python installation is
+in [^C:/dev/tools\/Python/]. If you have one fairly "standard" python
+installation for your platform, you might not need to do this.
+
+Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial]
+where the tutorial [^"hello.cpp"] and the [^"Jamroot"] is situated.
+
+Finally:
+
+ bjam
+
+It should be building now:
+
+[pre
+cd C:\dev\boost\libs\python\example\tutorial
+bjam
+...patience...
+...found 1101 targets...
+...updating 35 targets...
+]
+
+And so on... Finally:
+
+[pre
+ Creating library /path-to-boost_python.dll/
+ Creating library /path-to-'''hello_ext'''.exp/
+'''**passed**''' ... hello.test
+...updated 35 targets...
+]
+
+Or something similar. If all is well, you should now have built the DLLs and
+run the Python program.
+
+[:[*There you go... Have fun!]]
+
+[endsect]
+[section:exposing 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:
+
+[python]
+
+ >>> import hello
+ >>> planet = hello.World()
+ >>> planet.set('howdy')
+ >>> planet.greet()
+ 'howdy'
+
+[section 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:
+
+[c++]
+
+ 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.
+
+[endsect]
+[section 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:
+
+[python]
+
+ >>> 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
+
+[endsect]
+[section 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:
+
+[c++]
+
+ 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:
+
+[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:
+
+[c++]
+
+ .add_property("rovalue", &Num::get)
+
+[endsect]
+[section 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:
+
+# 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 will 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 will see more of
+Boost.Python [link python.call_policies call policies] later.
+
+ // Tell Python to take ownership of factory's result
+ def("factory", factory,
+ return_value_policy<manage_new_object>());
+
+[endsect]
+
+[section Class Virtual Functions]
+
+In this section, we will 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 ~Base() {}
+ virtual int f() = 0;
+ };
+
+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. It is not ideal to add anything to our class
+`Base`. Yet, when you have a virtual function that's going to be overridden in
+Python and called polymorphically *from C++*, we'll need to add some
+scaffoldings to make things work properly. What we'll do is write a class
+wrapper that derives from `Base` that will unintrusively hook into the virtual
+functions so that a Python override may be called:
+
+ struct BaseWrap : Base, wrapper<Base>
+ {
+ int f()
+ {
+ return this->get_override("f")();
+ }
+ };
+
+Notice too that in addition to inheriting from `Base`, we also multiply-
+inherited `wrapper<Base>` (See [@../../../v2/wrapper.html Wrapper]). The
+`wrapper` template makes the job of wrapping classes that are meant to
+overridden in Python, easier.
+
+[blurb __alert__ [*MSVC6/7 Workaround]
+
+If you are using Microsoft Visual C++ 6 or 7, you have to write `f` as:
+
+`return call<int>(this->get_override("f").ptr());`.]
+
+BaseWrap's overridden virtual member function `f` in effect calls the
+corresponding method of the Python object through `get_override`.
+
+Finally, exposing `Base`:
+
+ class_<BaseWrap, boost::noncopyable>("Base")
+ .def("f", pure_virtual(&Base::f))
+ ;
+
+`pure_virtual` signals Boost.Python that the function `f` is a pure virtual
+function.
+
+[note [*member function and methods]
+
+Python, like many object oriented languages uses the term [*methods].
+Methods correspond roughly to C++'s [*member functions]]
+
+[endsect]
+
+[section Virtual Functions with Default Implementations]
+
+We've seen in the previous section how classes with pure virtual functions are
+wrapped using Boost.Python's [@../../../v2/wrapper.html class wrapper]
+facilities. If we wish to wrap [*non]-pure-virtual functions instead, the
+mechanism is a bit different.
+
+Recall that in the [link python.class_virtual_functions 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 ~Base() {}
+ virtual int f() { return 0; }
+ };
+
+We wrap it this way:
+
+ struct BaseWrap : Base, wrapper<Base>
+ {
+ int f()
+ {
+ if (override f = this->get_override("f"))
+ return f(); // *note*
+ return Base::f();
+ }
+
+ int default_f() { return this->Base::f(); }
+ };
+
+Notice how we implemented `BaseWrap::f`. Now, we have to check if there is an
+override for `f`. If none, then we call `Base::f()`.
+
+[blurb __alert__ [*MSVC6/7 Workaround]
+
+If you are using Microsoft Visual C++ 6 or 7, you have to rewrite the line
+with the `*note*` as:
+
+`return call<char const*>(f.ptr());`.]
+
+Finally, exposing:
+
+ class_<BaseWrap, boost::noncopyable>("Base")
+ .def("f", &Base::f, &BaseWrap::default_f)
+ ;
+
+Take note that we expose both `&Base::f` and `&BaseWrap::default_f`.
+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.
+
+In Python, the results would be as expected:
+
+[python]
+
+ >>> base = Base()
+ >>> class Derived(Base):
+ ... def f(self):
+ ... return 42
+ ...
+ >>> derived = Derived()
+
+Calling [^base.f()]:
+
+ >>> base.f()
+ 0
+
+Calling [^derived.f()]:
+
+ >>> derived.f()
+ 42
+
+[endsect]
+[section 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:
+
+[c++]
+
+ 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".
+
+[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
+ { public: operator double() const; };
+
+ Rational pow(Rational, Rational);
+ Rational abs(Rational);
+ ostream& operator<<(ostream&,Rational);
+
+ class_<Rational>("Rational")
+ .def(float_(self)) // __float__
+ .def(pow(self, other<Rational>)) // __pow__
+ .def(abs(self)) // __abs__
+ .def(str(self)) // __str__
+ ;
+
+Need we say more?
+
+[note What is the business of `operator<<`?
+Well, the method `str` requires the `operator<<` to do its work (i.e.
+`operator<<` is used by the method defined by `def(str(self))`.]
+
+[endsect]
+[endsect] [/ Exposing Classes ]
+
+[section Functions]
+
+In this chapter, we'll look at Boost.Python powered functions in closer
+detail. We will see some facilities to make exposing C++ functions to
+Python safe from potential pifalls such as dangling pointers and
+references. We will 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!
+]
+
+[section 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:
+
+[python]
+
+ >>> 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:
+
+[c++]
+
+ 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<args...,
+ policy2<args...,
+ policy3<args...> > >
+
+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]: 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]: naive (dangerous) approach
+ * [*copy_const_reference]: Boost.Python v1 approach
+ * [*copy_non_const_reference]:
+ * [*manage_new_object]: Adopt a pointer and hold the instance
+
+[blurb :-) [*Remember the Zen, Luke:]
+
+"Explicit is better than implicit"
+
+"In the face of ambiguity, refuse the temptation to guess"
+]
+
+[endsect]
+[section 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 will 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)
+
+[endsect]
+[section 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 [link python.overloading previous section], or
+writing thin wrappers:
+
+ // write "thin wrappers"
+ int f1(int x) { return f(x); }
+ int f2(int x, double y) { return 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_MEMBER_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<int, optional<char, std::string, double> >())
+
+Notice the use of [^init<...>] and [^optional<...>] to signify the default
+(optional arguments).
+
+[endsect]
+[section Auto-Overloading]
+
+It was mentioned in passing in the previous section that
+[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_MEMBER_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", (void(*)(bool, int, char))0, 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
+[link python.overloading 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 [link python.overloading 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)
+
+[endsect]
+[endsect] [/ Functions ]
+
+[section:object 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 will 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.
+
+[$images/python.png]
+
+[section 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:
+
+[python]
+
+ 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:
+
+[c++]
+
+ 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.
+
+[endsect]
+[section 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++.
+
+[blurb
+ __alert__ [*Beware] the common pitfall of forgetting that the constructors
+ of most of Python's mutable types make copies, just as in Python.
+]
+
+Python:
+[python]
+
+ >>> d = dict(x.__dict__) # copies x.__dict__
+ >>> d['whatever'] = 3 # modifies the copy
+
+C++:
+[c++]
+
+ dict d(x.attr("__dict__")); // copies x.__dict__
+ d['whatever'] = 3; // modifies the copy
+
+[h2 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);
+
+[endsect]
+[section 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 [^double]s. 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]. The second line attempts to ['extract] the [^Vec2] object from held
+by the Boost.Python [^object].
+
+Take note that we said "attempt to" above. What if the Boost.Python [^object]
+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<Vec2&> x(o);
+ if (x.check()) {
+ Vec2& v = x(); ...
+
+__tip__ 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__ !
+
+
+[endsect]
+[section 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.
+
+[note [*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
+[@../../../v2/scope.html here].]
+
+You can access those values in Python as
+
+[python]
+
+ >>> 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:
+
+[c++]
+
+ scope in_X = class_<X>("X")
+ .def( ... )
+ .def( ... )
+ ;
+
+ // Expose X::nested as X.nested
+ enum_<X::nested>("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 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]]
+
+[endsect]
+
+[section:creating_python_object Creating `boost::python::object` from `PyObject*`]
+
+When you want a `boost::python::object` to manage a pointer to `PyObject*` pyobj one does:
+
+ boost::python::object o(boost::python::handle<>(pyobj));
+
+In this case, the `o` object, manages the `pyobj`, it won’t increase the reference count on construction.
+
+Otherwise, to use a borrowed reference:
+
+ boost::python::object o(boost::python::handle<>(boost::python::borrowed(pyobj)));
+
+In this case, `Py_INCREF` is called, so `pyobj` is not destructed when object o goes out of scope.
+
+[endsect] [/ creating_python_object ]
+
+[endsect] [/ Object Interface]
+
+[section 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 embed python into your programs, you have to link to
+both Boost.Python's as well as Python's own runtime library.
+
+Boost.Python's 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 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
+ <find-library>boost_python <library-path>c:\boost\libs\python
+ $(PYTHON_PROPERTIES)
+ <library-path>$(PYTHON_LIB_PATH)
+ <find-library>$(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''' [^<boost/python.hpp>]
+
+# Call Py_Initialize() to start the interpreter and create the [^__main__] module.
+
+# Call other Python C API routines to use the interpreter.
+
+[/ # Call Py_Finalize() to stop the interpreter and release its resources.]
+
+[note [*Note that at this time you must not call Py_Finalize() to stop the
+interpreter. This may be fixed in a future version of boost.python.]
+]
+
+(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...]]]
+
+[section 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/c-api/refcounting.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] and
+[@../../../v2/object.html object] class templates to automate the process.
+
+[h2 Running Python code]
+
+Boost.python provides three related functions to run Python code from C++.
+
+ object eval(str expression, object globals = object(), object locals = object())
+ object exec(str code, object globals = object(), object locals = object())
+ object exec_file(str filename, object globals = object(), object locals = object())
+
+eval evaluates the given expression and returns the resulting value.
+exec executes the given code (typically a set of statements) returning the result,
+and exec_file executes the code contained in the given file.
+
+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.
+
+Boost.python provides a function to import a module:
+
+ object import(str name)
+
+import imports a python module (potentially loading it into the running process
+first), and returns it.
+
+Let's import the [^__main__] module and run some Python code in its namespace:
+
+ object main_module = import("__main__");
+ object main_namespace = main_module.attr("__dict__");
+
+ object ignored = exec("hello = file('hello.txt', 'w')\n"
+ "hello.write('Hello world!')\n"
+ "hello.close()",
+ main_namespace);
+
+This should create a file called 'hello.txt' in the current directory
+containing a phrase that is well-known in programming circles.
+
+[h2 Manipulating Python objects]
+
+Often we'd like to have a class to manipulate Python objects.
+But we have already seen such a class above, and in the
+[@python/object.html previous section]: the aptly named [^object] class
+and its derivatives. We've already seen that they can be constructed from
+a [^handle]. The following examples should further illustrate this fact:
+
+ object main_module = import("__main__");
+ object main_namespace = main_module.attr("__dict__");
+ object ignored = exec("result = 5 ** 2", main_namespace);
+ 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 use eval instead,
+which returns the result directly:
+
+ object result = eval("5 ** 2");
+ int five_squared = extract<int>(result);
+
+[h2 Exception handling]
+
+If an exception occurs in the evaluation of the python expression,
+[@../../../v2/errors.html#error_already_set-spec error_already_set] is thrown:
+
+ try
+ {
+ object result = eval("5/0");
+ // execution will never get here:
+ int five_divided_by_zero = extract<int>(result);
+ }
+ catch(error_already_set const &)
+ {
+ // 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 const &)
+ {
+ 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].)
+
+[endsect]
+[endsect] [/ Embedding]
+
+[section 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:
+
+[python]
+
+ 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:
+
+[c++]
+
+ 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:
+
+[python]
+
+ f = Field()
+ for x in f.pions:
+ smash(x)
+ for y in f.bogons:
+ count(y)
+
+Now, our C++ Wrapper:
+
+[c++]
+
+ class_<F>("Field")
+ .property("pions", range(&F::p_begin, &F::p_end))
+ .property("bogons", range(&F::b_begin, &F::b_end));
+
+[*stl_input_iterator]
+
+So far, we have seen how to expose C++ iterators and ranges to Python.
+Sometimes we wish to go the other way, though: we'd like to pass a
+Python sequence to an STL algorithm or use it to initialize an STL
+container. We need to make a Python iterator look like an STL iterator.
+For that, we use `stl_input_iterator<>`. Consider how we might
+implement a function that exposes `std::list<int>::assign()` to
+Python:
+
+[c++]
+
+ template<typename T>
+ void list_assign(std::list<T>& l, object o) {
+ // Turn a Python sequence into an STL input range
+ stl_input_iterator<T> begin(o), end;
+ l.assign(begin, end);
+ }
+
+ // Part of the wrapper for list<int>
+ class_<std::list<int> >("list_int")
+ .def("assign", &list_assign<int>)
+ // ...
+ ;
+
+Now in Python, we can assign any integer sequence to `list_int` objects:
+
+[python]
+
+ x = list_int();
+ x.assign([1,2,3,4,5])
+
+[endsect]
+[section:exception 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);
+ ...
+
+[endsect]
+[section:techniques General Techniques]
+
+Here are presented some useful techniques that you can use while wrapping code with Boost.Python.
+
+[section 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].
+
+[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:
+
+[python]
+
+ >>> 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:
+
+[c++]
+
+ /* 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:
+
+[python]
+
+ >>> 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(...)
+
+[endsect]
+[section 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++:
+
+[c++]
+
+ class point {...};
+
+ BOOST_PYTHON_MODULE(_geom)
+ {
+ class_<point>("point")...;
+ }
+
+If we are using the technique from the previous session,
+[link python.creating_packages Creating Packages], we can code directly
+into [^geom/\_\_init\_\_.py]:
+
+[python]
+
+ 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.
+
+[endsect]
+[section 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:
+
+[c++]
+
+ /* file point.cpp */
+ #include <point.h>
+ #include <boost/python.hpp>
+
+ void export_point()
+ {
+ class_<point>("point")...;
+ }
+
+ /* file triangle.cpp */
+ #include <triangle.h>
+ #include <boost/python.hpp>
+
+ void export_triangle()
+ {
+ class_<triangle>("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 <boost/python.hpp>
+ #include <point.h>
+ #include <triangle.h>
+
+ BOOST_PYTHON_MODULE(_geom)
+ {
+ class_<point>("point")...;
+ class_<triangle>("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.
+
+[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.]
+
+[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].]
+
+[endsect]
+[endsect] [/ General Techniques]
+
+
diff --git a/libs/python/doc/tutorial/index.html b/libs/python/doc/tutorial/index.html
new file mode 100644
index 000000000..792427772
--- /dev/null
+++ b/libs/python/doc/tutorial/index.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+ </head>
+ <body>
+ Automatic redirection failed, click this
+ <a href="doc/html/index.html">link</a> &nbsp;<hr>
+ <p>© Copyright Beman Dawes, 2001</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../../../LICENSE_1_0.txt">
+ LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+ </body>
+</html>
diff --git a/libs/python/doc/v2/Apr2002.html b/libs/python/doc/v2/Apr2002.html
new file mode 100644
index 000000000..62350defa
--- /dev/null
+++ b/libs/python/doc/v2/Apr2002.html
@@ -0,0 +1,166 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../boost.css">
+<title>Boost.Python - April 2002 Progress Report</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">April 2002 Progress Report</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<h2>Contents</h2>
+<dl class="index">
+ <dt><a href="#accomplishments">Accomplishments</a></dt>
+ <dl class="index">
+ <dt><a href="#arity">Arbitrary Arity Support</a></dt>
+ <dt><a href="#callbacks">New Callback Interface</a></dt>
+ <dt><a href="#policies">Call Policies for Construtors</a></dt>
+ <dt><a href="#bugs">Real Users, Real Bugs</a></dt>
+ <dt><a href="#insights">New Insights</a></dt>
+ <dt><a href="#v1">Boost.Python V1 Maintenance</a></dt>
+ </dl>
+
+ <dt><a href="#missing">What's Missing</a></dt>
+
+</dl>
+
+<h2><a name="accomplishments">Accomplishments</a></h2>
+
+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...
+
+<h3><a name="arity">Arbitrary Arity Support</a></h3>
+
+I began using the <a
+href="../../../preprocessor/doc/index.html">Boost.Preprocessor</a>
+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.
+
+<p>
+
+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 &quot;manually&quot; expand the metaprograms for
+arities from zero to fifteen arguments, and EDG-based compilers with
+<code>__EDG_VERSION__&nbsp;&lt;=&nbsp;245</code> 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 <code>BOOST_PYTHON_MAX_ARITY</code> preprocessor symbol.
+
+<h3><a name="callbacks">New Callback Interface</a></h3>
+
+I mentioned in <a href="Mar2002.html">last month's report</a> 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 <a
+href="http://mail.python.org/pipermail/c++-sig/2002-April/000953.html">this
+message</a> (though the GCC 2.95.3 bugs have been fixed).
+
+<h3><a name="policies">Call Policies for Constructors</a></h3>
+
+On April 2nd, I <a
+href="http://mail.python.org/pipermail/c++-sig/2002-April/000916.html">announced</a>
+support for the use of call policies with constructors.
+
+<h3><a name="bugs">Real Users, Real Bugs</a></h3>
+
+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.
+
+<h3><a name="insights">New Insights</a></h3>
+
+<a
+href="http://mail.python.org/pipermail/c++-sig/2002-May/001010.html"
+>Answering some of Pearu's questions</a> 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 <code>to_python()</code> and
+<code>from_python()</code>. 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 &quot;callback&quot;, as in &quot;calling
+back into Python&quot;, and I named the converters used in callbacks
+accordingly: <code>to_python_callback</code> and
+<code>from_python_callback</code>. However, as it turns out, the
+behavior of the &quot;callback&quot; 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 <code>to_python</code> and
+<code>from_python</code> so those names are available for the
+user-friendly explicit converters.
+
+<p>
+<a
+href="http://mail.python.org/pipermail/c++-sig/2002-May/001013.html">Another
+of Pearu's questions</a> pushes momentum further in the direction of a
+more-sophisticated overloading mechanism than the current
+simple-minded &quot;first match&quot; approach, as I suggested <a
+href="Mar2002.html#implicit_conversions">last month</a>.
+
+<h3><a name="v1">Boost.Python V1 Maintenance</a></h3>
+
+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:
+<ol>
+<li>Update the build/test documentation with detailed instructions for
+configuring various toolsets.
+<li>Provide some links to Boost.Python v2 to let people know what's
+coming.
+</ol>
+
+
+<h2><a name="missing">What's Missing</a></h2>
+
+Last month I announced that I would implement the following which are
+not yet complete:
+<ol>
+<li>Document all implemented features
+<li>Implement conversions for <code>char</code> types. This is
+implemented but not tested, so we have to assume it doesn't work.
+</ol>
+
+These are my first priority for this month (especially the
+documentation).
+
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
+ 2002. </i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/CallPolicies.html b/libs/python/doc/v2/CallPolicies.html
new file mode 100644
index 000000000..06384a23d
--- /dev/null
+++ b/libs/python/doc/v2/CallPolicies.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../../../../boost.css">
+
+ <title>Boost.Python - CallPolicies Concept</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">CallPolicies Concept</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#composition">CallPolicies Composition</a></dt>
+
+ <dt><a href="#concept-requirements">Concept Requirements</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#CallPolicies-concept">CallPolicies Concept</a></dt>
+ </dl>
+ </dd>
+ </dl>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>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:</p>
+
+ <ol>
+ <li><code>precall</code> - Python argument tuple management before the
+ wrapped object is invoked</li>
+
+ <li><code>result_converter</code> - C++ return value handling</li>
+
+ <li><code>postcall</code> - Python argument tuple and result management
+ after the wrapped object is invoked</li>
+ <li><code>extract_return_type</code> - metafunction for extracting the return type from a given signature type sequence</li>
+ </ol>
+
+ <h2><a name="composition"></a>CallPolicies Composition</h2>
+ 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,
+ <code>Base</code> which defaults to <a href=
+ "default_call_policies.html#default_call_policies-spec"><code>default_call_policies</code></a>.
+ By convention, the <code>precall</code> function of the <code>Base</code>
+ is invoked <i>after</i> the <code>precall</code> function supplied by the
+ outer template, and the <code>postcall</code> function of the
+ <code>Base</code> is invoked <i>before</i> the <code>postcall</code>
+ function of the outer template. If a <code>result_converter</code> is
+ supplied by the outer template, it <i>replaces</i> any
+ <code>result_converter</code> supplied by the <code>Base</code>. For an
+ example, see <a href=
+ "return_internal_reference.html#return_internal_reference-spec"><code>return_internal_reference</code></a>.
+
+
+ <h2><a name="concept-requirements"></a>Concept Requirements</h2>
+
+ <h3><a name="CallPolicies-concept"></a>CallPolicies Concept</h3>
+
+ <p>In the table below, <code><b>x</b></code> denotes an object whose type
+ <code><b>P</b></code> is a model of CallPolicies, <code><b>a</b></code>
+ denotes a <code>PyObject*</code> pointing to a Python argument tuple
+ object, and <code><b>r</b></code> denotes a <code>PyObject*</code>
+ referring to a "preliminary" result object.</p>
+
+ <table summary="CallPolicies expressions" border="1" cellpadding="5">
+ <tr>
+ <td><b>Expression</b></td>
+
+ <td><b>Type</b></td>
+
+ <td><b>Result/Semantics</b></td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>x.precall(a)</code></td>
+
+ <td>convertible to <code>bool</code></td>
+
+ <td>returns <code>false</code> and <code><a href=
+ "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>
+ upon failure, <code>true</code> otherwise.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>P::result_converter</code></td>
+
+ <td>A model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>.</td>
+
+ <td>An MPL unary <a href=
+ "../../../mpl/doc/refmanual/metafunction-class.html">Metafunction
+ Class</a> used produce the "preliminary" result object.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>x.postcall(a, r)</code></td>
+
+ <td>convertible to <code>PyObject*</code></td>
+
+ <td>0 <code>0</code> and <code><a href=
+ "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>
+ upon failure. Must "conserve references" even in the event of an
+ exception. In other words, if <code>r</code> is not returned, its
+ reference count must be decremented; if another existing object is
+ returned, its reference count must be incremented.</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>P::extract_return_type</code></td>
+
+ <td>A model of <a href=
+ "../../../mpl/doc/refmanual/metafunction.html">Metafunction</a>.</td>
+
+ <td>An MPL unary <a href=
+ "../../../mpl/doc/refmanual/metafunction.html">Metafunction</a> used extract the return type from a given signature. By default it is derived from mpl::front.</td>
+ </tr>
+ </table>
+ Models of CallPolicies are required to be <a href=
+ "../../../utility/CopyConstructible.html">CopyConstructible</a>.
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+
+ <p>Permission to copy, use, modify, sell and distribute this software is
+ granted provided this copyright notice appears in all copies. This
+ software is provided "as is" without express or implied warranty, and
+ with no claim as to its suitability for any purpose.</p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/Dereferenceable.html b/libs/python/doc/v2/Dereferenceable.html
new file mode 100644
index 000000000..f7c53fd23
--- /dev/null
+++ b/libs/python/doc/v2/Dereferenceable.html
@@ -0,0 +1,74 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../../../../boost.css">
+<title>Boost.Python - Dereferenceable Concept</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">Dereferenceable Concept</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ <dt><a href="#concept-requirements">Concept Requirements</a></dt>
+ <dl class="page-index">
+ <dt><a href="#Dereferenceable-concept">Dereferenceable Concept</a></dt>
+ </dl>
+</dl>
+
+<h2><a name="introduction"></a>Introduction</h2>
+
+<p>Instances of a Dereferenceable type can be used like a pointer to access an lvalue.
+
+<h2><a name="concept-requirements"></a>Concept Requirements</h2>
+<h3><a name="Dereferenceable-concept"></a>Dereferenceable Concept</h3>
+
+<p>In the table below, <code><b>T</b></code> is a model of
+Dereferenceable, and <code><b>x</b></code> denotes an object of
+type <code>T</code>. In addition, all pointers are Dereferenceable.
+
+<table summary="Dereferenceable expressions" border="1" cellpadding="5">
+
+ <tr>
+ <td><b>Expression</b></td>
+ <td><b>Result</b></td>
+ <td><b>Operational Semantics</b></td>
+ </tr>
+
+ <tr>
+ <td><code>get_pointer(x)</code></td>
+ <td>convertible to <code><a href="pointee.html#pointee-spec">pointee</a>&lt;T&gt;::type*</code>
+ <td><code>&amp;*x</code>, or a null pointer
+ </tr>
+<tr>
+
+</table>
+
+<hr>
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 18 December, 2003
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002-2003. </i>
+
+<p>Permission to copy, use, modify, sell
+ and distribute this software is granted provided this copyright notice appears
+ in all copies. This software is provided "as is" without express or implied
+ warranty, and with no claim as to its suitability for any purpose.
+</body>
+</html>
diff --git a/libs/python/doc/v2/Extractor.html b/libs/python/doc/v2/Extractor.html
new file mode 100644
index 000000000..441ca38b3
--- /dev/null
+++ b/libs/python/doc/v2/Extractor.html
@@ -0,0 +1,96 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../../../../boost.css">
+<title>Boost.Python - Extractor Concept</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">Extractor Concept</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ <dt><a href="#concept-requirements">Concept Requirements</a></dt>
+ <dl class="page-index">
+ <dt><a href="#Extractor-concept">Extractor Concept</a></dt>
+ </dl>
+ <dt><a href="#notes">Notes</a></dt>
+</dl>
+
+<h2><a name="introduction"></a>Introduction</h2>
+
+<p>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 <code>from_python</code> conversions for
+&quot;traditional&quot; Python extension types.
+
+<h2><a name="concept-requirements"></a>Concept Requirements</h2>
+<h3><a name="Extractor-concept"></a>Extractor Concept</h3>
+
+<p>In the table below, <code><b>X</b></code> denotes a model of
+Extractor and <code><b>a</b></code> denotes an instance of a Python
+object type.
+
+<table summary="Extractor expressions" border="1" cellpadding="5">
+
+ <tr>
+ <td><b>Expression</b></td>
+ <td><b>Type</b></td>
+ <td><b>Semantics</b></td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>X::execute(a)</code></td>
+ <td>non-void
+ <td>Returns the C++ object being extracted. The
+ <code>execute</code> function must not be overloaded.
+ </tr>
+
+ <tr>
+ <td valign="top"><code>&amp;a.ob_type</code>
+ <td><code><a
+ href="http://www.python.org/doc/2.2/ext/dnt-type-methods.html">PyTypeObject</a>**</code>
+ <td>Points to the <code>ob_type</code> field of an object which is
+ layout-compatible with <code>PyObject</code>
+ </tr>
+
+ </tr>
+
+</table>
+
+<h2><a name="notes"></a>Notes</h2>
+
+Informally, an Extractor's <code>execute</code> 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 <code>PyObject</code>, and POD types which
+are layout-compatible with PyObject.
+
+<hr>
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i>
+
+<p>Permission to copy, use, modify, sell
+ and distribute this software is granted provided this copyright notice appears
+ in all copies. This software is provided "as is" without express or implied
+ warranty, and with no claim as to its suitability for any purpose.
+</body>
+</html>
diff --git a/libs/python/doc/v2/HolderGenerator.html b/libs/python/doc/v2/HolderGenerator.html
new file mode 100644
index 000000000..58b4265af
--- /dev/null
+++ b/libs/python/doc/v2/HolderGenerator.html
@@ -0,0 +1,74 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../../../../boost.css">
+<title>Boost.Python - Holder Concept</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">HolderGenerator Concept</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ <dt><a href="#concept-requirements">Concept Requirements</a></dt>
+ <dl class="page-index">
+ <dt><a href="#HolderGenerator-concept">HolderGenerator Concept</a></dt>
+ </dl>
+</dl>
+
+<h2><a name="introduction"></a>Introduction</h2>
+
+<p>A HolderGenerator is a unary metafunction class which returns types
+suitable for holding instances of its argument in a wrapped C++ class
+instance.
+
+<h2><a name="concept-requirements"></a>Concept Requirements</h2>
+<h3><a name="HolderGenerator-concept"></a>HolderGenerator Concept</h3>
+
+<p>In the table below, <code><b>G</b></code> denotes an type which
+models HolderGenerator, and <code><b>X</b></code> denotes a class
+type.
+
+<table summary="Holder expressions" border="1" cellpadding="5">
+
+ <tr>
+ <td><b>Expression</b></td>
+ <td><b>Requirements</b></td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>G::apply&lt;X&gt;::type</code></td>
+ <td>A concrete subclass of <a
+ href="instance_holder.html#instance_holder-spec">instance_holder</a>
+ which can hold objects of type <code>X</code>.
+ </tr>
+</table>
+
+<hr>
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i>
+
+<p>Permission to copy, use, modify, sell
+ and distribute this software is granted provided this copyright notice appears
+ in all copies. This software is provided "as is" without express or implied
+ warranty, and with no claim as to its suitability for any purpose.
+</body>
+</html>
diff --git a/libs/python/doc/v2/Jun2002.html b/libs/python/doc/v2/Jun2002.html
new file mode 100644
index 000000000..db1fc25c6
--- /dev/null
+++ b/libs/python/doc/v2/Jun2002.html
@@ -0,0 +1,229 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../boost.css">
+<title>Boost.Python - June 2002 Progress Report</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">June 2002 Progress Report</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<h2>Contents</h2>
+<dl class="index">
+ <dt><a href="#intro">Introduction</a></dt>
+ <dt><a href="#handle"><code>handle&lt;T&gt;</code></a></dt>
+ <dt><a href="#object"><code>object</code></a></dt>
+ <dl class="index">
+ <dt><a href="#operators"><code>object</code> operators</a></dt>
+ <dt><a href="#conversions"><code>object</code> conversions</a></dt>
+ </dl>
+ <dt><a href="#list"><code>list</code></a></dt>
+ <dt><a href="#numerics"><code>Numerics</code></a></dt>
+ <dt><a href="#community">Community</a></dt>
+ <dt><a href="#next">What's Next</a></dt>
+</dl>
+
+<h2><a name="intro">Introduction</a></h2>
+
+July was mostly focused on allowing expressive manipulation of
+individual Python objects, or what Ralf Grosse-Kunstleve calls
+&quot;Writing Python in C++&quot;. The work began with this <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001311.html">posting</a>,
+which outlines the issues and intention.
+
+<h2><a name="handle"><code>handle&lt;T&gt;</code></a></h2>
+
+The most basic element needed was a replacement for the
+<code>reference&lt;&gt;</code> class template and the
+<code>ref</code> typedef from Boost.Python v1, a simple smart
+pointer to a Python object. The old v1 typedef
+&quot;<code>ref</code>&quot; (for
+<code>reference&lt;PyObject&gt;</code>) had to be retired because I
+thought it would be too confusing given the importance of <code><a
+href="../../../bind/ref.html">boost::ref</a>()</code> to this
+library. I began a <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001311.html">discussion</a>of
+possible names, and it was eventually <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001337.html">decided</a>
+to rename <code>reference</code> to <code>handle</code> and supply a
+default argument so that <code>ref</code> could be spelled
+<code>handle&lt;&gt;</code> without an additional typedef. There
+were also some interface changes to make it safer and more-efficient
+to interface with the raw
+<code>PyObject*</code>s forced on us by Python's 'C' API. A
+discussion of those protocols can be found <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001401.html">here</a>.
+
+<h2><a name="handle"><code>object</code></a></h2>
+
+It is intended that users will seldom need or want to work with
+<code>handle&lt;&gt;</code>; its major distinguishing features are
+that it gives direct access to the underlying object representation
+through <code>operator*</code> and <code>operator-&gt;</code>, and
+that can be <code>NULL</code>, both sources of danger. Instead the
+library provides a class called <code>object</code>, which
+encapsulates a valid Python object and provides a similar interface to
+Python's.
+
+<h3><a name="operators"><code>object</code> operators</a></h3>
+
+The first challenge was to provide support for object manipulations
+using a Python-like syntax, mostly in the form of operator overloads:
+
+<table border="1">
+<tr><th>Python <th>C++
+
+<tr>
+ <td><code>y = x.foo</code> <td><code>y = x.attr(&quot;foo&quot;);
+<tr>
+ <td><code>x.foo = 1</code> <td><code>x.attr(&quot;foo&quot;) = 1;
+
+<tr>
+ <td><code>y = x[z]</code> <td><code>y = x[z];
+<tr>
+ <td><code>x[z] = 1</code> <td><code>x[z] = 1;
+
+<tr>
+ <td><code>y = x[3:-1]</code> <td><code>y = x.slice(3,-1);
+
+<tr>
+ <td><code>y = x[3:]</code> <td><code>y = x.slice(3,_);
+
+<tr>
+ <td><code>y = x[:-2]</code> <td><code>y = x.slice(_,-2);
+
+<tr>
+ <td><code>z = x(1, y)</code> <td><code>z = x(1, y);
+<tr>
+ <td><code>z = x.f(1, y)</code> <td><code>z = x.attr(&quot;f&quot;)(1, y);
+
+<tr>
+ <td><code>not x</code> <td><code>!x
+
+<tr>
+ <td><code>x and y</code> <td><code>x and y
+</table>
+
+I'm still a unsatisfied with the interface for attribute access. There
+original proposal used a syntax like this one:
+<pre>
+y = x._(&quot;foo&quot;);
+x._(&quot;foo&quot;) = 1;
+</pre>
+
+which was only marginally better than what we've got. Niki Spahiev
+then <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001447.html">pointed
+out</a> a potential conflict with the macro which GNU Gettext <a
+href="http://www.gnu.org/manual/gettext/html_mono/gettext.html#SEC6">suggests</a>
+people define. This unfortunate state of affairs forced us into using
+<code>attr</code> 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:
+<pre>
+y = x,&quot;foo&quot; // error
+x,&quot;foo&quot; = 1; // error
+
+y = (x,&quot;foo&quot;); // ok
+(x,&quot;foo&quot;) = 1; // ok
+</pre>
+
+Well, I guess we could consider adding that to the interface without
+removing <code>attr()</code>, to see how it plays out...
+
+<h3><a name="operators"><code>object</code> conversions</a></h3>
+
+The <code>object</code> class also provided an opportunity to replace
+Boost.Python v1's <code>to_python()</code> as a user-level
+interface. Instead, <code>object</code> 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 <code><a
+href="call.html">call</a>&lt;&gt;</code>.
+
+<p>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 &quot;interesting&quot; than it
+should have been.
+
+<h2><a name="list"><code>list</code></a></h2>
+
+With <code>object</code> implemented, it was time to begin replacing
+the ad-hoc implementations of <code>list</code>, <code>string</code>,
+and <code>dictionary</code> supplied by Boost.Python v1 with something
+more robust. I started with <code>list</code> as an example. Because
+<code>object</code> already provides all of the requisite operators,
+publicly deriving <code>list</code> 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 <code>list</code> arguments
+to wrapped functions. Some of the issues are laid out in <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001551.html">this
+thread</a>. Ultimately, it was decided that <code>list(x)</code>
+should do the same thing in C++ as in Python (conversion), while
+<code>list</code> arguments should only match Python
+<code>list</code>s (and <code>list</code> subclasses). The
+implementation worked well, and provided a <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001586.html">roadmap</a>
+for the protocol to be used for implementation of the other built-in
+types.
+
+<h2><a name="numerics">Numerics</a></h2>
+
+Support for C++ <code>long long</code> and <code>unsigned long
+long</code>
+(and <code>__int64</code> 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.
+
+<h2><a name="community">Community</a></h2>
+
+<ul>
+<li>Ralf W. Grosse-Kunstleve and Nick Sauter have implemented
+<a href="http://cci.lbl.gov/boost/">multiplatform nightly
+build-and-test</a> runs for Boost.Python V2 at LBL.
+
+<li>Dave Hawkes has made significant progress on generating the
+Python <a
+href="http://mail.python.org/pipermail/c++-sig/2002-June/001503.html">built-in
+function and API wrappers</a>
+
+<li>Achim Domma has agreed to take up the job of implementing the
+<code>str</code>, <code>dict</code>, and <code>tuple</code> classes.
+</ul>
+
+Deep thanks to all the Boost.Python contributors! This project
+wouldn't be possible without your participation.
+
+ <h2><a name="next">What's Next</a></h2>
+
+As I write this we are already well into the month of July, so I
+suggest you consult the <a
+href="http://mail.python.org/pipermail/c++-sig/2002-July/">Mailing
+List Archive</a> if you want to know what's been happening. Otherwise
+you'll just have to wait till next month (hopefully the beginning).
+
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
+ 2002. </i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/Mar2002.html b/libs/python/doc/v2/Mar2002.html
new file mode 100644
index 000000000..97444d229
--- /dev/null
+++ b/libs/python/doc/v2/Mar2002.html
@@ -0,0 +1,237 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../boost.css">
+<title>Boost.Python - March 2002 Progress Report</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">March 2002 Progress Report</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<h2>Contents</h2>
+<dl class="index">
+ <dt><a href="#accomplishments">Accomplishments</a></dt>
+ <dl class="index">
+ <dt><a href="#calling_python">Calling Python from C++</a></dt>
+ <dt><a href="#virtual_functions">Virtual Functions</a></dt>
+ <dt><a href="#abstract_classes">Abstract Classes</a></dt>
+ <dt><a href="#implicit_conversions">C++ Implicit Conversions</a></dt>
+ <dt><a href="#data_members">C++ Data Members</a></dt>
+ <dt><a href="#miscellaneous">Miscellaneous</a></dt>
+ </dl>
+
+ <dt><a href="#future">The Near future</a></dt>
+
+ <dt><a href="#notes">Notes</a></dt>
+
+</dl>
+
+<h2><a name="accomplishments">Accomplishments</a></h2>
+
+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.
+
+<h3><a name="calling_python">Calling Python from C++</a></h3>
+
+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
+<a href="callbacks.txt">here</a>.
+
+<p>
+One point which <i>isn't</i> emphasized in that document is that there
+are subtle differences in the way <code>from_python</code> conversions
+work when used for C++ function arguments and Python function return
+values. In particular, while <code>T const&amp;</code> 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.
+
+<p>I'm not particularly pleased with the current callback interface,
+since it usually results in constructs like:
+<pre>
+<u>return returning</u>&lt;X&amp;&gt;::call(f, obj);
+</pre>
+However, I think the following may be possible and I plan to investigate:
+<pre>
+return apply&lt;X&amp;&gt;(f, obj);
+</pre>
+I'm open to suggestion for better names (and syntaxes)!
+
+<h3><a name="virtual_functions">Virtual Functions</a></h3>
+
+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 <i>derived</i> from the one exposed to
+Python. Needing some way for users to specify that class, I added an
+optional template argument to <code>value_holder_generator</code> and
+<code>pointer_holder_generator&lt;&gt;</code> to specify the class
+actually held. This move began to put pressure on the
+<code>class_&lt;&gt;</code> interface, since the need for the user to
+produce complicated instantations of
+<code>class_&lt;&gt;</code> was increased:
+
+<pre>
+class&lt;Foo, bases&lt;&gt;, value_holder_generator&lt;Foo_callback&gt; &gt;(&quot;Foo&quot;)
+.def(&quot;hello&quot;, &amp;Foo::hello)
+...
+</pre>
+
+<h3><a name="abstract_classes">Abstract Classes</a></h3>
+
+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 &quot;holder&quot;) which is managed
+by the corresponding Python object.
+
+<p>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 <code>class_&lt;&gt;</code> 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.
+
+<p>
+
+This was the straw that broke the
+<code>class_&lt;&gt;</code> interface's back and caused the redesign
+whose outcome is detailed <a
+href="http://mail.python.org/pipermail/c++-sig/2002-March/000892.html">here</a>.
+The approach allows the user to supply the optional parameters in an
+arbitrary order. It was inspired by the use of <a
+href="../../../utility/iterator_adaptors.htm#named_tempalte_parameters">named
+template parameters</a> in the <a
+href="../../../utility/iterator_adaptors.htm">Boost Iterator Adaptor
+Library</a>, 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.
+
+<p>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.
+
+<h3><a name="implicit_conversions">C++ Implicit Conversions</a></h3>
+
+Support for C++ implicit conversion involves creating
+<code>from_python</code> converters for a type <code>U</code> which in
+turn use <code>from_python</code> converters registered for a type
+<code>T</code> where there exists a implicit conversion from
+<code>T</code> to <code>U</code>. The current implementation is
+subject to two inefficiencies:
+<ol>
+
+<li>Because an rvalue <code>from_python</code> converter produces two
+pieces of data (a function and a <code>void*</code>) from its
+<code>convertible()</code> function, we end up calling the function
+for <code>T</code> twice: once when the converter is looked up in the
+registry, and again when the conversion is actually performed.
+
+<li>A vector is used to mark the "visited" converters, preventing
+infinite recursion as <code>T</code> to
+<code>U</code> and <code>U</code> to <code>T</code> converters
+continually search through one-another.
+
+</ol>
+
+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.
+
+<h3><a name="data_members">C++ Data Members</a></h3>
+
+To supply the ability to directly access data members, I was able to
+hijack the new Python <a
+href="http://www.python.org/2.2/descrintro.html#property">property</a>
+type. I had hoped that I would also be able to re-use the work of <a
+href="make_function.html">make_function</a> 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 <i>object</i>, 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.
+
+<h3><a name="miscellaneous">Miscellaneous</a></h3>
+<ul>
+<li>Moved <code>args&lt;&gt;</code> and <code>bases&lt;&gt;</code> from unnamed namespace to <code>boost::python</code> in their own header files.
+<li>Convert <code>NULL</code> pointers returned from wrapped C++ functions to <code>None</code>.
+<li>Improved some compile-time error checks.
+<li>Eliminated <code>boost/python/detail/eval.hpp</code> in favor of
+more-general <code>boost/mpl/apply.hpp</code>.
+<li>General code cleanup and refactoring.
+<li>Works with Microsoft Visual C++ 7.0
+<li>Warning suppression for many compilers
+<li>Elegant interface design for exporting <code>enum</code> types.
+</ul>
+<hr>
+
+<h2><a name="future">The Near Future</a></h2>
+
+Before April 15th I plan to
+<ol>
+<li>Document all implemented features
+<li>Implement a <code>CallPolicy</code> interface for constructors of wrapped
+classes
+<li>Implement conversions for <code>char</code> types.
+<li>Implement automated code generation for all headers containing
+families of overloaded functions to handle arbitrary arity.
+</ol>
+
+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)!
+
+<h2><a name="notes">Notes</a></h2>
+
+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.
+
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
+ 2002. </i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/May2002.html b/libs/python/doc/v2/May2002.html
new file mode 100644
index 000000000..5e5b6aaa4
--- /dev/null
+++ b/libs/python/doc/v2/May2002.html
@@ -0,0 +1,311 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../boost.css">
+<title>Boost.Python - May 2002 Progress Report</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">May 2002 Progress Report</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<h2>Contents</h2>
+<dl class="index">
+ <dt><a href="#intro">Introduction</a></dt>
+ <dt><a href="#features">New Features</a></dt>
+ <dl>
+ <dt><a href="#aix_shared">Shared Library Support for AIX</a><dd>
+ <dt><a href="#class_enhancements">Class Enhancements</a><dd>
+ <dl>
+ <dt><a href="#operators">Operators</a><dd>
+ <dt><a href="#iterators">Iterators</a><dd>
+ <dt><a href="#properties">Properties</a><dd>
+ <dt><a href="#setattr">setattr</a><dd>
+ <dt><a href="#module">__module__ Attribute</a><dd>
+ </dl>
+ <dt><a href="#back_reference">back_reference</a><dd>
+ </dl>
+
+ <dt><a href="#documentation">Documentation</a></dt>
+ <dt><a href="#misc">Miscellaneous</a></dt>
+ <dl class="index">
+ <dt><a href="#converters">Converters</a></dt>
+ <dt><a href="#checkins">Checkins Mailing List</a></dt>
+ <dt><a href="#shared">Shared Libraries</a></dt>
+ </dl>
+
+ <dt><a href="#next">What's Next</a></dt>
+</dl>
+
+<h2><a name="intro">Introduction</a></h2>
+
+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 <a
+href="../../../../tools/build/v1/build_system.htm">Boost.Build</a> and specific
+<a href="../building.html">instructions</a> for building Boost.Python
+v1. The documentation for Boost.Python v2 was also updated as
+described <a href="#documentation">here</a>.
+
+<h2><a name="features">New Features</a></h2>
+
+ <h3><a name="aix_shared">Shared Library Support for AIX</a></h3>
+
+ The Kull group required the ability to build and test Boost.Python
+ extensions on AIX, a platform with &quot;creatively designed&quot;
+ 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 <a
+ href="../../../../tools/build/v1/gen_aix_import_file.py">Python
+ Script</a> 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.
+
+ <h3><a name="class_enhancements">Class Enhancements</a></h3>
+
+ <h4><a name="operators">Operators</a></h4>
+
+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
+<code>left_operand&lt;...&gt;/right_operand&lt;...&gt;</code> for
+asymmetric operands), I introduced a simple form of <a
+href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">expression
+templates</a> which allow users to simply write the expressions that
+should be wrapped, as in this <a href="operators.html#examples">example</a>.
+
+ <h4><a name="iterators">Iterators</a></h4>
+
+Python iterator support as required by the Kull project resulted in a
+highly flexible interface allowing:
+
+<dl>
+
+<dt>Direct exposure of a class' <code>begin()</code> and
+<code>end()</code> functions:
+
+<pre>
+ ...
+ .def(&quot;__iter__&quot;, iterator&lt;list_int&gt;())
+</pre>
+<dd>
+
+<dt>Creation of iterators from member functions...
+<pre>
+ ...
+ .def(&quot;__iter__&quot;
+ , range(&amp;my_class::x_begin, &amp;my_class::x_end))
+ )
+</pre>
+<dd>
+
+<dt>...and member data:
+<pre>
+ ...
+ .def(&quot;__iter__&quot;
+ , range(&amp;std::pair&lt;char*,char*&gt;::first, &amp;std::pair&lt;char*,char*&gt;::second))
+ )
+</pre>
+<dd>
+
+<dt>The ability to specify <a
+href="CallPolicies.html">CallPolicies</a>, e.g. to prevent copying of
+heavyweight values:
+
+<pre>
+ ...
+ .def(&quot;__iter__&quot;,
+ , range&lt;return_value_policy&lt;copy_non_const_reference&gt; &gt;(
+ &amp;my_sequence&lt;heavy&gt;::begin
+ , &amp;my_sequence&lt;heavy&gt;::end))
+</pre>
+<dd>
+
+</dl>
+
+ <h4><a name="properties">Properties</a></h4>
+
+The Kull iteration interfaces also required the ability to iterate
+over a sequence specified by an instance's attribute:
+<pre>
+&gt;&gt;&gt; f = field()
+&gt;&gt;&gt; for e in f.elements:
+... print e,
+</pre>
+
+This forced the exposure of the <a
+ href="http://www.python.org/2.2/descrintro.html#property"><code>property</code></a>
+ interface used internally to implement the data member exposure
+ facility described in <a
+ href="Mar2002.html#data_members">March</a>. Properties are an
+ incredibly useful idiom, so it's good to be able to provide them
+ at little new development cost.
+
+ <h4><a name="setattr">setattr</a></h4>
+
+<code>class_&lt;&gt;</code> acquired a <code>setattr</code> member
+function which allows users to easily add new Python objects as class
+attributes.
+
+ <h4><a name="module">__module__ Attribute</a></h4>
+
+Ralf Grosse-Kunstleve has been working on pickling support for v2. To
+make it work correctly, he had to make sure that a class'
+<code>__module__</code> attribute was set correctly.
+
+<h3><a name="back_reference"><code>back_reference</code></a></h3>
+
+The new <code>back_reference&lt;T&gt;</code> template can be used as a
+function parameter when the user needs access to both a <code>T</code>
+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 <code>T</code> substituted for
+<code>back_reference&lt;T&gt;</code>. This feature is not yet
+documented.
+
+<h2><a name="documentation">Documentation</a></h2>
+
+In a major effort to prepare Boost.Python v2 to replace v1, many pages
+of new reference documentation were added:
+
+<blockquote>
+
+<dl>
+ <dt><a href="CallPolicies.html">CallPolicies.html</a><dd>
+ <dt><a href="Dereferenceable.html">Dereferenceable.html</a><dd>
+ <dt><a href="Extractor.html">Extractor.html</a><dd>
+ <dt><a href="HolderGenerator.html">HolderGenerator.html</a><dd>
+ <dt><a href="ResultConverter.html">ResultConverter.html</a><dd>
+ <dt><a href="call_method.html">call_method.html</a><dd>
+ <dt><a href="callbacks.html">callbacks.html</a><dd>
+ <dt><a href="data_members.html">data_members.html</a><dd>
+ <dt><a href="has_back_reference.html">has_back_reference.html</a><dd>
+ <dt><a href="implicit.html">implicit.html</a><dd>
+ <dt><a href="instance_holder.html">instance_holder.html</a><dd>
+ <dt><a href="operators.html">operators.html</a><dd>
+ <dt><a href="ptr.html">ptr.html</a><dd>
+ <dt><a href="type_id.html">type_id.html</a><dd>
+ <dt><a href="with_custodian_and_ward.html">with_custodian_and_ward.html</a><dd>
+</dl>
+
+</blockquote>
+Major updates were made to the following pages:
+
+
+<blockquote>
+<dl>
+ <dt><a href="call.html">call.html</a><dd> <dt>updated<dd>
+ <dt><a href="class.html">class.html</a><dd>
+ <dt><a href="reference.html">reference.html</a><dd>
+</dl>
+</blockquote>
+
+ 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:
+
+<blockquote>
+<dl>
+ <dt>type_id.hpp<dd>
+ <dt>pointee.hpp<dd>
+ <dt>lvalue_from_pytype.hpp<dd></dl>
+</dl>
+</blockquote>
+
+<h2><a name="misc">Miscellaneous</a></h2>
+
+ <h3><a name="converters">Converters</a></h3>
+
+It appears that the world of C++ &lt;==&gt; Python conversion rules is
+an endlessly-rich area of exploration. Completing the conversions for
+<code>char</code> and <code>char const*</code> types, as described at
+the end of <a href="Apr2002.html#missing">April's report</a>,
+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
+<code>const</code>, it does understand immutability (c.f. Python
+strings, which expose an immutable <code>char</code> pointer). It is
+also worth recognizing types which represent lvalue <i>sequences</i>,
+to prevent Python <code>&quot;foobar&quot;</code> from being silently
+truncated to C++ <code>'f'</code>. More details on this insight can be
+found in the mailing list <a
+href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">
+archive</a>. 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.
+
+ <h3><a name="checkins">Checkins Mailing List</a></h3>
+
+In order to better coordinate changes made by multiple developers, I
+enabled <a
+href="http://sourceforge.net/docman/display_doc.php?docid=772&group_id=1">syncmail</a>
+for the Boost.Python CVS trees, and established an associated <a
+href="http://lists.sourceforge.net/lists/listinfo/boost-python-cvs">mailing
+list</a>. Subscribe to this list to receive notices of each new
+checkin.
+
+ <h3><a name="shared">Shared Libraries</a></h3>
+
+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 <a
+href="http://gcc.gnu.org/ml/gcc/">gcc</a> mailing list, concerns the
+behavior of GCC on Posix/ELF platforms.
+
+Some of the GCC threads are here:
+
+<blockquote>
+<a
+href="http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html">http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html</a><br>
+<a
+href="http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html">http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html</a><br>
+<a href="http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html">http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html</a>
+</blockquote>
+
+ <h2><a name="next">What's Next</a></h2>
+
+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.
+
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
+ 2002. </i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/ObjectWrapper.html b/libs/python/doc/v2/ObjectWrapper.html
new file mode 100644
index 000000000..7962e69fa
--- /dev/null
+++ b/libs/python/doc/v2/ObjectWrapper.html
@@ -0,0 +1,153 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - ObjectWrapper Concept</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">ObjectWrapper and TypeWrapper Concepts</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#concept-requirements">Concept Requirements</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#ObjectWrapper-concept">ObjectWrapper Concept</a></dt>
+
+ <dt><a href="#TypeWrapper-concept">TypeWrapper Concept</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#caveat">Caveat</a></dt>
+ </dl>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>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.</p>
+
+ <h2><a name="concept-requirements"></a>Concept Requirements</h2>
+
+ <h3><a name="ObjectWrapper-concept"></a>ObjectWrapper Concept</h3>
+ Models of the ObjectWrapper concept have <a href=
+ "object.html#object-spec">object</a> 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 <code>R</code> is itself an <a href=
+ "#TypeWrapper-concept">TypeWrapper</a>, a member function invocation of
+ the form
+<pre>
+x.<i>some_function</i>(<i>a<small>1</small>, a<small>2</small>,...a<small>n</small></i>)
+</pre>
+ always has semantics equivalent to:
+<pre>
+<a href=
+"extract.html#extract-spec">extract</a>&lt;R&gt;(x.attr("<i>some_function</i>")(<a
+ href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
+href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
+href="object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)))()
+</pre>
+ When the <code>R</code> is an <a href=
+ "#TypeWrapper-concept">TypeWrapper</a>, the result type may be
+ constructed by taking direct posession of:
+<pre>
+x.attr("<i>some_function</i>")(<a href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
+ href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
+ href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)).ptr()
+</pre>
+ [see <a href="#caveat">caveat</a> below]
+
+ <h3><a name="TypeWrapper-concept"></a>TypeWrapper Concept</h3>
+ TypeWrapper is a refinement of ObjectWrapper which is associated with a
+ particular Python type <code>X</code>. For a given TypeWrapper
+ <code>T</code>, a valid constructor expression
+<pre>
+T(<i>a<small>1</small>, a<small>2</small>,...a<small>n</small></i>)
+</pre>
+ builds a new <code>T</code> object managing the result of invoking
+ <code>X</code> with arguments corresponding to
+<pre>
+<a href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
+ href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
+ href=
+"object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)
+</pre>
+
+When used as arguments to wrapped C++ functions, or as the template
+parameter to <code><a
+href="extract.html#extract-spec">extract</a>&lt;&gt;</code>, only
+instances of the associated Python type will be considered a match.
+
+ <h3><a name="caveat">Caveat</a></h3>
+ 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 <code><a href=
+ "dict.html#dict-spec">dict</a></code> member function <code>items</code>
+ returns an object of type <code><a href=
+ "list.html#list-spec">list</a></code>. Now suppose the user defines this
+ <code>dict</code> subclass in Python:
+<pre>
+&gt;&gt;&gt; class mydict(dict):
+... def items(self):
+... return tuple(dict.items(self)) # return a tuple
+</pre>
+ Since an instance of <code>mydict</code> is also an instance of
+ <code>dict</code>, when used as an argument to a wrapped C++ function,
+ <code><a href="dict.html#dict-spec">boost::python::dict</a></code> can
+ accept objects of Python type <code>mydict</code>. Invoking
+ <code>items()</code> on this object can result in an instance of <code><a
+ href="list.html#list-spec">boost::python::list</a></code> which actually
+ holds a Python tuple. Subsequent attempts to use list methods (e.g.
+ <code>append</code>, or any other mutating operation) on this object will
+ raise the same exception that would occur if you tried to do it from
+ Python.
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/ResultConverter.html b/libs/python/doc/v2/ResultConverter.html
new file mode 100644
index 000000000..be53a9b97
--- /dev/null
+++ b/libs/python/doc/v2/ResultConverter.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../../../../boost.css">
+<title>Boost.Python - ResultConverter Concept</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">ResultConverter Concept</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ <dt><a href="#concept-requirements">Concept Requirements</a></dt>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
+ <dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
+ </dl>
+ </dd>
+</dl>
+
+<h2><a name="introduction"></a>Introduction</h2>
+
+<p>A ResultConverter for a type <code>T</code> is a type whose
+instances can be used to convert C++ return values of type
+<code>T</code> <code>to_python</code>. 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.
+
+<h2><a name="concept-requirements"></a>Concept Requirements</h2>
+<h3><a name="ResultConverter-concept"></a>ResultConverter Concept</h3>
+
+<p>In the table below, <code><b>C</b></code> denotes a ResultConverter
+type for a type <b><code>R</code></b> , <code><b>c</b></code> denotes
+an object of type <code><b>C</b></code> , and <code><b>r</b></code>
+denotes an object of type <code><b>R</b></code>.
+
+<table summary="ResultConverter expressions" border="1" cellpadding="5">
+
+ <tr>
+ <td><b>Expression</b></td>
+ <td><b>Type</b></td>
+ <td><b>Semantics</b></td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>C c;</code></td>
+ <td>
+ <td>Constructs a <code>C</code> object.
+ </tr>
+
+ <tr>
+ <td valign="top"><code>c.convertible()</code></td>
+ <td>convertible to <code>bool</code></td>
+ <td><code>false</code> iff no conversion from any <code>R</code> value
+ to a Python object is possible.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>c(r)</code></td>
+ <td>convertible to <code>PyObject*</code></td>
+ <td>A pointer to a Python object corresponding to <code>r</code>,
+ or <code>0</code> iff <code>r</code> could not be converted
+ <code>to_python</code>, in which case <a
+ href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
+ should return non-zero.</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>c.get_pytype()</code></td>
+ <td><code>PyTypeObject const*</code></td>
+ <td>A pointer to a Python Type object corresponding to result of the conversion,
+ or <code>0</code>. Used for documentation generation. If <code>0</code> is returned
+ the generated type in the documentation will be <b>object</b> .</td>
+ </tr>
+</table>
+
+<h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>
+<p>In the table below, <code><b>G</b></code> denotes a
+ResultConverterGenerator type and <code><b>R</b></code> denotes a possible
+C++ function return type.
+
+<table summary="ResultConverterGenerator expressions" border="1" cellpadding="5">
+ <tr>
+ <td><b>Expression</b></td>
+ <td><b>Requirements</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>G::apply&lt;R&gt;::type</code></td>
+ <td>A ResultConverter type for <code>R</code>.</td>
+</table>
+
+<hr>
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 09 May, 2002 <!--Luann's birthday! -->
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i>
+
+<p>Permission to copy, use, modify, sell
+ and distribute this software is granted provided this copyright notice appears
+ in all copies. This software is provided "as is" without express or implied
+ warranty, and with no claim as to its suitability for any purpose.
+</body>
+</html>
diff --git a/libs/python/doc/v2/acknowledgments.html b/libs/python/doc/v2/acknowledgments.html
new file mode 100644
index 000000000..28f1b1dbd
--- /dev/null
+++ b/libs/python/doc/v2/acknowledgments.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - Acknowledgments</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Acknowledgments</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <p><a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> is
+ the architect, designer, and implementor of <b>Boost.Python</b>.</p>
+
+ <p><a href="mailto:brett.calcott@paradise.net.nz">Brett Calcott</a>
+ contributed and maintains the Visual Studio project files and
+ documentation.</p>
+
+ <p><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
+ Ganßauge</a> supplied support for opaque pointer conversions,
+ complete with documentation and a regression test (and I didn't
+ even have to ask him for those)!
+
+ <p>Joel de Guzman implemented the <a href="overloads.html">default
+ argument support</a> and wrote the excellent <a href=
+ "../tutorial/index.html">tutorial documentation</a>.</p>
+
+ <p><a href="http://www.boost.org/people/ralf_w_grosse_kunstleve.htm">Ralf W.
+ Grosse-Kunstleve</a> implemented the <a href="pickle.html">pickle
+ support</a>, 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 <a href=
+ "faq.html#question2">extensions</a> 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.</p>
+
+ <p><a href="http://www.boost.org/people/aleksey_gurtovoy.htm">Aleksey Gurtovoy</a>
+ wrote an incredible C++ <a href="http://www.mywikinet.com/mpl">Template
+ Metaprogramming Library</a> 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.</p>
+
+ <p><a href="http://www.boost.org/people/paul_mensonides.htm">Paul Mensonides</a>,
+ building on the work <a href="http://www.boost.org/people/vesa_karvonen.htm">Vesa
+ Karvonen</a>, wrote a similarly amazing <a href=
+ "../../../preprocessor/doc/index.html">Preprocessor Metaprogramming
+ Library</a>, 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.</p>
+
+ <p><a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de
+ Oliveira</a> contributed the ingenious <a
+ href="../../pyste/index.html">Pyste</a> (&quot;Pie-Steh&quot;)
+ code generator.
+
+ <p><a href="mailto:nickm@sitius.com">Nikolay Mladenov</a> contributed
+ <code>staticmethod</code> support.</p>
+
+ <p>Martin Casado solved some sticky problems which allow us to build the
+ Boost.Python shared library for AIX's crazy dynamic linking model.</p>
+
+ <p><a href="mailto:achim@procoders.net">Achim Domma</a> contributed some
+ of the <a href="reference.html#object_wrappers">Object Wrappers</a> and
+ HTML templates for this documentation. Dave Hawkes contributed
+ inspiration for the use of the <code><a href=
+ "scope.html#scope-spec">scope</a></code> class to simplify module
+ definition syntax. Pearu Pearson wrote some of the test cases that are in
+ the current test suite.</p>
+
+ <p>The development of this version of Boost.Python was funded in part by
+ the <a href="http://www.llnl.gov/">Lawrence Livermore National
+ Laboratories</a> and by the <a href="http://cci.lbl.gov/">Computational
+ Crystallography Initiative</a> at Lawrence Berkeley National
+ Laboratories.</p>
+
+ <p><a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/">Ullrich
+ Koethe</a> 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.</p>
+
+ <p>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.</p>
+
+ <p>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.</p>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 26 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/args.html b/libs/python/doc/v2/args.html
new file mode 100644
index 000000000..e04720b7e
--- /dev/null
+++ b/libs/python/doc/v2/args.html
@@ -0,0 +1,199 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/args.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/args.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#keyword-expression"><i>keyword-expressions</i></a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#arg-spec">class <code>arg</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#arg-synopsis">class <code>arg</code>
+ synopsis</a></dt>
+
+ <dt><a href="#arg-ctor">class <code>arg</code>
+ constructor</a></dt>
+
+ <dt><a href="#arg-operator">class <code>arg</code> template
+ <code>operator =</code></a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#keyword-expression-operators"><i>Keyword-expression</i>
+ operator <code>,</code></a></dt>
+
+ <dt><a href="#functions">Functions (deprecated)</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><code><a href=
+ "#args-spec">args</a>(</code>...<code>)</code></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Supplies a family of overloaded functions for specifying argument
+ keywords for wrapped C++ functions.</p>
+
+ <h2><a name="keyword-expression"></a><i>keyword-expressions</i></h2>
+
+ <p>A <b>keyword-expression</b> results in an object which holds a
+ sequence of <a href="definitions.html#ntbs">ntbs</a>es, and whose type
+ encodes the number of keywords specified. The <b>keyword-expression</b>
+ may contain default values for some or all of the keywords it holds</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="arg-spec"></a><code>class arg;</code></h3>
+
+ <p>The objects of class arg are keyword-expressions holding one keyword (
+ size one )</p>
+
+ <h4><a name="arg-synopsis"></a>Class <code>arg</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct arg
+ {
+ template &lt;class T&gt;
+ arg &amp;operator = (T const &amp;value);
+ explicit arg (char const *name){elements[0].name = name;}
+ };
+
+}}
+</pre>
+
+ <h4><a name="arg-ctor"></a>Class <code>arg</code> constructor</h4>
+<pre>
+arg(char const* name);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> The argument must be a <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Effects:</b> Constructs an <code>arg</code> object holding a
+ keyword with name <code>name</code>.</dt>
+ </dl>
+
+ <h4><a name="arg-operator"></a>Class <code>arg</code> operator =</h4>
+<pre>
+template &lt;class T&gt; arg &amp;operator = (T const &amp;value);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> The argument must convertible to python.</dt>
+
+ <dt><b>Effects:</b> Assigns default value for the keyword.</dt>
+
+ <dt><b>Returns:</b> Reference to <code>this</code>.</dt>
+ </dl>
+
+ <h2><a name="keyword-expression-operators"><i>Keyword-expression</i>
+ operator <code>,</code></a></h2>
+<pre>
+ <i>keyword-expression</i> operator , (<i>keyword-expression</i>, const arg &amp;kw) const
+ <i>keyword-expression</i> operator , (<i>keyword-expression</i>, const char *name) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> The argument <code>name</code> must be a <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Effects:</b> Extends the <i>keyword-expression</i> argument with
+ one more keyword.</dt>
+
+ <dt><b>Returns:</b> The extended <i>keyword-expression</i>.</dt>
+ </dl>
+
+ <h2><font color="#7F7F7F"><a name="functions"></a>Functions
+ (deprecated)</font></h2>
+
+ <h3><a name="args-spec"></a><code><font color=
+ "#7F7F7F">args</font>(</code>...<code>)</code></h3>
+<pre>
+<font color="#7F7F7F"> <i>unspecified1</i> args(char const*);
+ <i>unspecified2</i> args(char const*, char const*);
+ .
+ .
+ .
+ <i>unspecifiedN</i> args(char const*, char const*, ... char const*);
+</font>
+</pre>
+
+ <dl class="function-semantics">
+ <dt><font color="#7F7F7F"><b>Requires:</b> Every argument must be a <a
+ href="definitions.html#ntbs">ntbs</a>.</font></dt>
+
+ <dt><font color="#7F7F7F"><b>Returns:</b> an object representing a <a
+ href="#keyword-expression"><i>keyword-expression</i></a> encapsulating
+ the arguments passed.</font></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+#include &lt;boost/python/def.hpp&gt;
+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 )
+ );
+}
+</pre>
+
+ <p>Revised 01 August, 2003</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/call.html b/libs/python/doc/v2/call.html
new file mode 100644
index 000000000..adba2b5fe
--- /dev/null
+++ b/libs/python/doc/v2/call.html
@@ -0,0 +1,85 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../boost.css">
+<title>Boost.Python - &lt;call.hpp&gt;</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">Header &lt;call.hpp&gt;</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<h2>Contents</h2>
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ <dt><a href="#functions">Functions</a></dt>
+ <dl class="page-index">
+ <dt><a href="#call-spec">call</a></dt>
+ </dl>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+
+</dl>
+<hr>
+<h2><a name="introduction"></a>Introduction</h2>
+<p>
+ <code>&lt;boost/python/call.hpp&gt;</code> defines the <a
+ href="#call-spec"><code>call</code></a> family of overloaded function
+ templates, used to invoke Python callable objects from C++.
+
+<h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name="call-spec">template &lt;class R, class A1, class A2, ... class A<i>n</i>&gt;</a>
+R call(PyObject* callable, A1 const&amp;, A2 const&amp;, ... A<i>n</i> const&amp;)
+</pre>
+<dl class="function-semantics">
+ <dt><b>Requires:</b> <code>R</code> is a pointer type, reference
+ type, or a complete type with an accessible copy constructor</dt>
+
+ <dt><b>Effects:</b> Invokes <code>callable(a1,&nbsp;a2,&nbsp;...a<i>n</i>)</code> in
+ Python, where <code>a1</code>...<code>a<i>n</i></code> are the arguments to
+ <code>call()</code>, converted to Python objects.
+ <dt><b>Returns:</b> The result of the Python call, converted to the C++ type <code>R</code>.</dt>
+
+</dt>
+ <dt><b>Rationale:</b> For a complete semantic description and
+ rationale, see <a href="callbacks.html">this page</a>.
+</dt>
+</dl>
+
+<h2><a name="examples"></a>Example(s)</h2>
+
+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 <code>double</code>, an exception
+is thrown.
+
+<pre>
+double apply2(PyObject* func, double x, double y)
+{
+ return boost::python::call&lt;double&gt;(func, x, y);
+}
+</pre>
+
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 9 May, 2002 <!-- Luann's birthday! -->
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
+ 2002. </i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/call_method.html b/libs/python/doc/v2/call_method.html
new file mode 100644
index 000000000..e54ffb26a
--- /dev/null
+++ b/libs/python/doc/v2/call_method.html
@@ -0,0 +1,161 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;call_method.hpp&gt;</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;call_method.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#call_method-spec">call_method</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/call_method.hpp&gt;</code> defines the <a href=
+ "#call_method-spec"><code>call_method</code></a> family of overloaded
+ function templates, used to invoke callable attributes of Python objects
+ from C++.</p>
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name=
+"call_method-spec">template &lt;class R, class A1, class A2, ... class A<i>n</i>&gt;</a>
+R call_method(PyObject* self, char const* method, A1 const&amp;, A2 const&amp;, ... A<i>n</i> const&amp;)
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>R</code> is a pointer type, reference type,
+ or a complete type with an accessible copy constructor</dt>
+
+ <dt><b>Effects:</b> Invokes
+ <code>self.<i>method</i>(a1,&nbsp;a2,&nbsp;...a<i>n</i>)</code> in
+ Python, where <code>a1</code>...<code>a<i>n</i></code> are the
+ arguments to <code>call_method()</code>, converted to Python objects.
+ For a complete semantic description, see <a href="callbacks.html">this
+ page</a>.</dt>
+
+ <dt><b>Returns:</b> The result of the Python call, converted to the C++
+ type <code>R</code>.</dt>
+
+ <dt><b>Rationale:</b> <code>call_method</code> is critical to
+ implementing C++ virtual functions which are overridable in Python, as
+ shown by the example below.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example(s)</h2>
+ The following C++ illustrates the use of <code>call_method</code> in
+ wrapping a class with a virtual function that can be overridden in
+ Python:
+
+ <h3>C++ Module Definition</h3>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/utility.hpp&gt;
+#include &lt;cstring&gt;
+
+// 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-&gt;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 <b>call_method</b>&lt;char const*&gt;(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_&lt;Base,Base_callback, noncopyable&gt;("Base")
+ .def("class_name", &amp;Base_callback::Base_name)
+ ;
+
+}
+</pre>
+
+ <h3>Python Code</h3>
+<pre>
+&gt;&gt;&gt; from my_module import *
+&gt;&gt;&gt; class Derived(Base):
+... def __init__(self):
+... Base.__init__(self)
+... def class_name(self):
+... return self.__class__.__name__
+...
+&gt;&gt;&gt; is_base(Base()) # calls the class_name() method from C++
+1
+&gt;&gt;&gt; is_base(Derived())
+0
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/callbacks.html b/libs/python/doc/v2/callbacks.html
new file mode 100644
index 000000000..4e91befad
--- /dev/null
+++ b/libs/python/doc/v2/callbacks.html
@@ -0,0 +1,254 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - Calling Python Functions and Methods</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Calling Python Functions and Methods</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#argument_handling">Argument Handling</a></dt>
+
+ <dt><a href="#result_handling">Result Handling</a></dt>
+
+ <dt><a href="#result_handling">Rationale</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction">Introduction</a></h2>
+ The simplest way to call a Python function from C++, given an <code><a
+ href="object.html#object-spec">object</a></code> instance <code>f</code>
+ holding the function, is simply to invoke its function call operator.
+<pre>
+f("tea", 4, 2) // In Python: f('tea', 4, 2)
+</pre>
+ And of course, a method of an <code><a href=
+ "object.html#object-spec">object</a></code> instance <code>x</code> can
+ be invoked by using the function-call operator of the corresponding
+ attribute:
+<pre>
+x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
+</pre>
+
+ <p>If you don't have an <code>object</code> instance, Boost.Python
+ provides two families of function templates, <code><a href=
+ "call.html#call-spec">call</a></code> and <code><a href=
+ "call_method.html#call_method-spec">call_method</a></code>, for invoking
+ Python functions and methods respectively on <code>PyObject*</code>s. The
+ interface for calling a Python function object (or any Python callable
+ object) looks like:</p>
+<pre>
+call&lt;ResultType&gt;(callable_object, a1, a2... a<i>N</i>);
+</pre>
+ Calling a method of a Python object is similarly easy:
+<pre>
+call_method&lt;ResultType&gt;(self_object, "<i>method-name</i>", a1, a2... a<i>N</i>);
+</pre>
+ This comparitively low-level interface is the one you'll use when
+ implementing C++ virtual functions that can be overridden in Python.
+
+ <h2><a name="argument_handling">Argument Handling</a></h2>
+
+ <p>Arguments are converted to Python according to their type. By default,
+ the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
+ new Python objects, but this behavior can be overridden by the use of
+ <code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a href=
+ "../../../bind/ref.html">ref()</a>:</p>
+<pre>
+class X : boost::noncopyable
+{
+ ...
+};
+
+void apply(PyObject* callable, X&amp; x)
+{
+ // Invoke callable, passing a Python object which holds a reference to x
+ boost::python::call&lt;void&gt;(callable, boost::ref(x));
+}
+</pre>
+ In the table below, <code><b>x</b></code> denotes the actual argument
+ object and <code><b>cv</b></code> denotes an optional
+ <i>cv-qualification</i>: "<code>const</code>", "<code>volatile</code>",
+ or "<code>const volatile</code>".
+
+ <table border="1" summary="class_ template parameters">
+ <tr>
+ <th>Argument Type</th>
+
+ <th>Behavior</th>
+ </tr>
+
+ <tr>
+ <td><code>T cv&amp;</code><br>
+ <code>T cv</code></td>
+
+ <td>The Python argument is created by the same means used for the
+ return value of a wrapped C++ function returning <code>T</code>. When
+ <code>T</code> is a class type, that normally means <code>*x</code>
+ is copy-constructed into the new Python object.</td>
+ </tr>
+
+ <tr>
+ <td><code>T*</code></td>
+
+ <td>If <code>x&nbsp;==&nbsp;0</code>, the Python argument will be
+ <code><a href=
+ "http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
+ Otherwise, the Python argument is created by the same means used for
+ the return value of a wrapped C++ function returning <code>T</code>.
+ When <code>T</code> is a class type, that normally means
+ <code>*x</code> is copy-constructed into the new Python object.</td>
+ </tr>
+
+ <tr>
+ <td><code><a href=
+ "../../../bind/ref.html">boost::reference_wrapper</a>&lt;T&gt;</code></td>
+
+ <td>The Python argument contains a pointer to, rather than a copy of,
+ <code>x.get()</code>. Note: failure to ensure that no Python code
+ holds a reference to the resulting object beyond the lifetime of
+ <code>*x.get()</code> <b>may result in a crash!</b></td>
+ </tr>
+
+ <tr>
+ <td><code><a href=
+ "ptr.html#pointer_wrapper-spec">pointer_wrapper</a>&lt;T&gt;</code></td>
+
+ <td>If <code>x.get()&nbsp;==&nbsp;0</code>, the Python argument will
+ be <code><a href=
+ "http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
+ Otherwise, the Python argument contains a pointer to, rather than a
+ copy of, <code>*x.get()</code>. Note: failure to ensure that no
+ Python code holds a reference to the resulting object beyond the
+ lifetime of <code>*x.get()</code> <b>may result in a crash!</b></td>
+ </tr>
+ </table>
+
+ <h2><a name="result_handling">Result Handling</a></h2>
+ In general, <code>call&lt;ResultType&gt;()</code> and
+ <code>call_method&lt;ResultType&gt;()</code> return
+ <code>ResultType</code> by exploiting all lvalue and rvalue
+ <code>from_python</code> converters registered for ResultType and
+ returning a copy of the result. However, when <code>ResultType</code> 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.
+
+ <h2><a name="rationale">Rationale</a></h2>
+ In general, to get Python arguments corresponding to
+ <code>a1</code>...<code>a<i>N</i></code>, 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.
+
+ <p>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 <code><a href="../../../bind/ref.html">boost::ref</a>(a1)</code>
+ 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[<a
+ href="#1">1</a>].</p>
+
+ <p>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
+ <code>*aN</code> to pass "by-value" or <code>ref(*aN)</code> to indicate
+ a pass-by-reference behavior. However, this creates a problem for the
+ expected null pointer to <code>None</code> conversion: it's illegal to
+ dereference a null pointer value.</p>
+
+ <p>The compromise I've settled on is this:</p>
+
+ <ol>
+ <li>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.</li>
+
+ <li>if you want by-reference behavior, use <code>ptr(aN)</code> if
+ <code>aN</code> is a pointer and <code>ref(aN)</code> otherwise. If a
+ null pointer is passed to <code>ptr(aN)</code>, the corresponding
+ Python argument will be <code>None</code>.</li>
+ </ol>
+
+ <p>As for results, we have a similar problem: if <code>ResultType</code>
+ 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 <code>ResultType</code> is char const* - the
+ corresponding Python String object is typically uniquely-referenced,
+ meaning that the pointer dangles as soon as <code>call&lt;char
+ const*&gt;(...)</code> returns.</p>
+
+ <p>The old Boost.Python v1 deals with this issue by refusing to compile
+ any uses of <code>call&lt;char const*&gt;()</code>, 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.</p>
+
+ <p>In Boost.Python v2 this is dealt with by:</p>
+
+ <ol>
+ <li>lifting the compile-time restriction on const char* callback
+ returns</li>
+
+ <li>detecting the case when the reference count on the result Python
+ object is 1 and throwing an exception inside of
+ <code>call&lt;U&gt;(...)</code> when <code>U</code> is a pointer or
+ reference type.</li>
+ </ol>
+ This should be acceptably safe because users have to explicitly specify a
+ pointer/reference for <code>U</code> in <code>call&lt;U&gt;</code>, and
+ they will be protected against dangles at runtime, at least long enough
+ to get out of the <code>call&lt;U&gt;(...)</code> invocation.
+ <hr>
+ <a name="1">[1]</a> 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.
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/callbacks.txt b/libs/python/doc/v2/callbacks.txt
new file mode 100644
index 000000000..2795680fd
--- /dev/null
+++ b/libs/python/doc/v2/callbacks.txt
@@ -0,0 +1,92 @@
+.. Copyright David Abrahams 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+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<ResultType>::call("method_name", self_object, a1, a2...);
+
+or
+
+ returning<ResultType>::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<char const*>::call() returns.
+
+Boost.Python v1 deals with this issue by refusing to compile any uses of
+callback<char const*>::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<U>::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<U>, and they will be protected
+against dangles at runtime, at least long enough to get out of the
+returning<U>::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/libs/python/doc/v2/class.html b/libs/python/doc/v2/class.html
new file mode 100644
index 000000000..edfc60970
--- /dev/null
+++ b/libs/python/doc/v2/class.html
@@ -0,0 +1,790 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st September 2004), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-latin-1-dos">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/class.hpp&gt;,
+ &lt;boost/python/class_fwd.hpp&gt;</title>
+</head>
+
+<body link="#0000FF" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Headers &lt;boost/python/class.hpp&gt;,
+ &lt;boost/python/class_fwd.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#class_-spec">Class template
+ <code>class_</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#class_-spec-synopsis">Class <code>class_</code>
+ synopsis</a></dt>
+
+ <dt><a href="#class_-spec-ctors">Class <code>class_</code>
+ constructors</a></dt>
+
+ <dt><a href="#class_-spec-modifiers">Class <code>class_</code>
+ modifier functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#bases-spec">Class template <code>bases</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#bases-spec-synopsis">Class template
+ <code>bases</code> synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/class.hpp&gt;</code> defines the interface
+ through which users expose their C++ classes to Python. It declares the
+ <code>class_</code> class template, which is parameterized on the class
+ type being exposed. It also exposes the <code>init</code>,
+ <code>optional</code> and <code>bases</code> utility class templates, which
+ are used in conjunction with <code>class_</code>.</p>
+
+ <p><code>&lt;boost/python/class_fwd.hpp&gt;</code> contains a forward
+ declaration of the <code>class_</code> class template.</p>
+
+ <h2><a name="classes" id="classes"></a>Classes</h2>
+
+ <h3><a name="class_-spec" id="class_-spec"></a>Class template
+ <code>class_&lt;T,&nbsp;<font color="#007F00">Bases,&nbsp;HeldType,
+ NonCopyable</font>&gt;</code></h3>
+
+ <p>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
+ <font color="#007F00"><b>in any order</b></font>; Boost.Python determines
+ the role of the argument from its type.<br>
+ <br></p>
+
+ <table border="1" summary="class_ template parameters">
+ <tr>
+ <th>Template Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Semantics</th>
+
+ <th>Default</th>
+ </tr>
+
+ <tr>
+ <td><code>T</code></td>
+
+ <td>A class type.</td>
+
+ <td>The class being wrapped</td>
+ </tr>
+
+ <tr>
+ <td><code><font color="#007F00">Bases</font></code></td>
+
+ <td>A specialization of <a href=
+ "#bases-spec"><code>bases&lt;</code>...<code>&gt;</code></a> which
+ specifies previously-exposed C++ base classes of <code>T</code><a href=
+ "#footnote_1">[1]</a>.</td>
+
+ <td>Registers <code>from_python</code> conversions from wrapped
+ <code>T</code> instances to each of its exposed direct and indirect
+ bases. For each polymorphic base <code>B</code>, registers conversions
+ from indirectly-held wrapped <code>B</code> instances to
+ <code>T</code>.</td>
+
+ <td><code><a href="#bases-spec">bases&lt;&gt;</a></code></td>
+ </tr>
+
+ <tr>
+ <td><code><font color="#007F00">HeldType</font></code></td>
+
+ <td>Must be <code>T</code>, a class derived from <code>T</code>, or a
+ <a href="Dereferenceable.html">Dereferenceable</a> type for which
+ <code><a href=
+ "pointee.html#pointee-spec">pointee</a>&lt;HeldType&gt;::type</code> is
+ <code>T</code> or a class derived from <code>T</code>.</td>
+
+ <td>Specifies the type that is actually embedded in a Python object
+ wrapping a <code>T</code> instance when <code>T</code>'s constructor is
+ called or when a <code>T</code> or <code>T*</code> is converted to
+ Python without the use of <a href=
+ "http://www.boost.org/libs/python/doc/v2/callbacks.html#argument_handling">
+ <code>ptr</code></a>, <a href=
+ "http://www.boost.org/libs/python/doc/v2/callbacks.html#argument_handling">
+ <code>ref</code></a>, or <a href="CallPolicies.html">Call Policies</a>
+ such as <code><a href=
+ "return_internal_reference.html">return_internal_reference</a></code>.
+ More details <a href="#HeldType">below</a>.</td>
+
+ <td><code>T</code></td>
+ </tr>
+
+ <tr>
+ <td><code><font color="#007F00">NonCopyable</font></code></td>
+
+ <td>If supplied, must be <a href=
+ "../../../utility/utility.htm#Class_noncopyable">boost::noncopyable</a>.</td>
+
+ <td>Suppresses automatic registration of <code>to_python</code>
+ conversions which copy <code>T</code> instances. Required when
+ <code>T</code> has no publicly-accessible copy constructor.</td>
+
+ <td>An unspecified type other than
+ <code>boost::noncopyable</code>.</td>
+ </tr>
+ </table>
+
+ <h4><a name="HeldType" id="HeldType">HeldType Semantics</a></h4>
+
+ <ol>
+ <li>If <code>HeldType</code> is derived from T, its exposed
+ constructor(s) must accept an initial <code>PyObject*</code> argument
+ which refers back to the Python object that contains the
+ <code>HeldType</code> instance, as shown in <a href=
+ "call_method.html#examples">this example</a>. This argument is not
+ included in the <em><a href=
+ "init.html#init-expressions">init-expression</a></em> passed to <a href=
+ "#class_-spec-modifiers"><code>def(init_expr)</code></a>, below, nor is
+ it passed explicitly by users when Python instances of <code>T</code> 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 <code>T</code> to be passed to wrapped C++
+ functions expecting <code>HeldType</code> arguments.</li>
+
+ <li>Because Boost.Python will always allow wrapped instances of
+ <code>T</code> to be passed in place of <code>HeldType</code> arguments,
+ specifying a smart pointer for <code>HeldType</code> allows users to pass
+ Python <code>T</code> instances where a smart pointer-to-<code>T</code>
+ is expected. Smart pointers such as <code>std::auto_ptr&lt;&gt;</code> or
+ <code><a href=
+ "../../../smart_ptr/shared_ptr.htm">boost::shared_ptr&lt;&gt;</a></code>
+ which contain a nested type <code>element_type</code> designating the
+ referent type are automatically supported; additional smart pointer types
+ can be supported by specializing <a href=
+ "pointee.html#pointee-spec">pointee&lt;HeldType&gt;</a>.</li>
+
+ <li>As in case 1 above, when <code>HeldType</code> is a smart pointer to
+ a class derived from <code>T</code>, the initial <code>PyObject*</code>
+ argument must be supplied by all of <code>HeldType</code>'s exposed
+ constructors.</li>
+
+ <li>Except in cases 1 and 3, users may optionally specify that T itself
+ gets initialized with a similar initial <code>PyObject*</code> argument
+ by specializing <a href=
+ "has_back_reference.html#has_back_reference-spec">has_back_reference&lt;T&gt;</a>.</li>
+ </ol>
+
+ <h4><a name="class_-spec-synopsis" id="class_-spec-synopsis"></a>Class
+ template <code>class_</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python
+{
+ template &lt;class T
+ <font color="#007F00"> , class Bases = bases&lt;&gt;
+ , class HeldType = T
+ , class NonCopyable = <i>unspecified</i>
+ &gt;
+</font> class class_ : public <a href="object.html#object-spec">object</a>
+ {
+ // Constructors with default __init__
+ class_(char const* name);
+ class_(char const* name, char const* docstring);
+
+ // Constructors, specifying non-default __init__
+ template &lt;class Init&gt;
+ class_(char const* name, Init);
+ template &lt;class Init&gt;
+ class_(char const* name, char const* docstring, Init);
+
+ // Exposing additional __init__ functions
+ template &lt;class Init&gt;
+ class_&amp; def(Init);
+
+ // defining methods
+ template &lt;class F&gt;
+ class_&amp; def(char const* name, F f);
+ template &lt;class Fn, class A1&gt;
+ class_&amp; def(char const* name, Fn fn, A1 const&amp;);
+ template &lt;class Fn, class A1, class A2&gt;
+ class_&amp; def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;);
+ template &lt;class Fn, class A1, class A2, class A3&gt;
+ class_&amp; def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
+
+ // declaring method as static
+ class_&amp; staticmethod(char const* name);
+
+ // exposing operators
+ template &lt;<i>unspecified</i>&gt;
+ class_&amp; def(<a href=
+"operators.html#operator_-spec">detail::operator_</a>&lt;unspecified&gt;);
+
+ // Raw attribute modification
+ template &lt;class U&gt;
+ class_&amp; setattr(char const* name, U const&amp;);
+
+ // exposing data members
+ template &lt;class D&gt;
+ class_&amp; def_readonly(char const* name, D T::*pm);
+
+ template &lt;class D&gt;
+ class_&amp; def_readwrite(char const* name, D T::*pm);
+
+ // exposing static data members
+ template &lt;class D&gt;
+ class_&amp; def_readonly(char const* name, D const&amp; d);
+ template &lt;class D&gt;
+ class_&amp; def_readwrite(char const* name, D&amp; d);
+
+ // property creation
+ template &lt;class Get&gt;
+ void add_property(char const* name, Get const&amp; fget, char const* doc=0);
+ template &lt;class Get, class Set&gt;
+ void add_property(
+ char const* name, Get const&amp; fget, Set const&amp; fset, char const* doc=0);
+
+ template &lt;class Get&gt;
+ void add_static_property(char const* name, Get const&amp; fget);
+ template &lt;class Get, class Set&gt;
+ void add_static_property(char const* name, Get const&amp; fget, Set const&amp; fset);
+
+ // pickle support
+ template &lt;typename PickleSuite&gt;
+ self&amp; def_pickle(PickleSuite const&amp;);
+ self&amp; enable_pickling();
+ };
+}}
+</pre>
+
+ <h4><a name="class_-spec-ctors" id="class_-spec-ctors"></a>Class template
+ <code>class_</code> constructors</h4>
+ <pre>
+class_(char const* name);
+class_(char const* name, char const* docstring);
+template &lt;class Init&gt;
+class_(char const* name, Init init_spec);
+template &lt;class Init&gt;
+class_(char const* name, char const* docstring, Init init_spec);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>. If <code>docstring</code> is supplied, it must be an
+ <a href="definitions.html#ntbs">ntbs</a>. If <code>init_spec</code> is
+ supplied, it must be either the special enumeration constant
+ <code>no_init</code> or an <a href=
+ "init.html#init-expressions">init-expression</a> compatible with
+ <code>T</code>.</dt>
+
+ <dt><b>Effects:</b> Constructs a <code>class_</code> object holding a
+ Boost.Python extension class named <code>name</code>. The
+ <code>name</code>d attribute of the <a href=
+ "scope.html#introduction">current scope</a> is bound to the new extension
+ class.</dt>
+
+ <dd>
+ <ul>
+ <li>If supplied, the value of <code>docstring</code> is bound to the
+ <code>__doc__</code> attribute of the extension class.</li>
+
+ <li>If <code>init_spec</code> is <code>no_init</code>, a special
+ <code>__init__</code> function is generated which always raises a
+ Python exception. Otherwise, <code>this-&gt;def(init_spec)</code> is
+ called.</li>
+
+ <li>If <code>init_spec</code> is not supplied,
+ <code>this-&gt;def(init&lt;&gt;())</code> is called.</li>
+ </ul>
+ </dd>
+
+ <dt><b>Rationale:</b>Allowing the user to specify constructor arguments
+ in the <code>class_&lt;&gt;</code> constructor helps her to avoid the
+ common run-time errors which result from invoking wrapped member
+ functions without having exposed an <code>__init__</code> function which
+ creates the requisite <code>T</code> instance. Types which are not
+ default-constructible will cause a compile-time error unless
+ <code>Init</code> is supplied. The user must always supply
+ <code>name</code> as there is currently no portable method to derive the
+ text of the class name from its type.</dt>
+ </dl>
+
+ <h4><a name="class_-spec-modifiers" id="class_-spec-modifiers"></a>Class
+ template <code>class_</code> modifier functions</h4>
+ <pre>
+template &lt;class Init&gt;
+class_&amp; def(Init init_expr);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>init_expr</code> is the result of an <a href=
+ "init.html#init-expressions">init-expression</a> compatible with
+ <code>T</code>.</dt>
+
+ <dt><b>Effects:</b> For each <a href="init.html#init-expressions">valid
+ prefix</a> <em>P</em> of <code>Init</code>, adds an
+ <code>__init__(</code>...<code>)</code> function overload to the
+ extension class accepting <em>P</em> as arguments. Each overload
+ generated constructs an object of <code>HeldType</code> according to the
+ semantics described <a href="#HeldType">above</a>, using a copy of
+ <code>init_expr</code>'s <a href="CallPolicies.html">call policies</a>.
+ If the longest <a href="init.html#init-expressions">valid prefix</a> of
+ <code>Init</code> contains <em>N</em> types and <code>init_expr</code>
+ holds <em>M</em> keywords, an initial sequence of the keywords are used
+ for all but the first <em>N</em> - <em>M</em> arguments of each
+ overload.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ <dt><b>Rationale:</b> Allows users to easily expose a class' constructor
+ to Python.</dt>
+ </dl><br>
+ <pre>
+template &lt;class F&gt;
+class_&amp; def(char const* name, Fn fn);
+template &lt;class Fn, class A1&gt;
+class_&amp; def(char const* name, Fn fn, A1 const&amp; a1);
+template &lt;class Fn, class A1, class A2&gt;
+class_&amp; def(char const* name, Fn fn, A1 const&amp; a1, A2 const&amp; a2);
+template &lt;class Fn, class A1, class A2, class A3&gt;
+class_&amp; def(char const* name, Fn fn, A1 const&amp; a1, A2 const&amp; a2, A3 const&amp; a3);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>.</dt>
+
+ <dd>
+ <ul>
+ <li>If <code>a1</code> is the result of an <a href=
+ "overloads.html#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>,
+ only the second form is allowed and fn must be a pointer to function
+ or pointer to member function whose <a href="definitions.html#arity">
+ arity</a> is the same as A1's <a href=
+ "overloads.html#overload-dispatch-expression"><em>maximum
+ arity</em></a>.
+
+ <dl>
+ <dt><b>Effects:</b> For each prefix <em>P</em> of
+ <code>Fn</code>'s sequence of argument types, beginning with the
+ one whose length is <code>A1</code>'s <a href=
+ "overloads.html#overload-dispatch-expression"><em>minimum
+ arity</em></a>, adds a
+ <code><em>name</em>(</code>...<code>)</code> method overload to
+ the extension class. Each overload generated invokes
+ <code>a1</code>'s call-expression with <em>P</em>, using a copy
+ of <code>a1</code>'s <a href="CallPolicies.html">call
+ policies</a>. If the longest valid prefix of <code>A1</code>
+ contains <em>N</em> types and <code>a1</code> holds <em>M</em>
+ keywords, an initial sequence of the keywords are used for all
+ but the first <em>N</em> - <em>M</em> arguments of each
+ overload.<br></dt>
+ </dl>
+ </li>
+
+ <li>Otherwise, a single method overload is built around fn, which
+ must not be null:
+
+ <ul>
+ <li>If fn is a function pointer, its first argument must be of
+ the form <code>U</code>, <code>U <em>cv</em>&amp;</code>, <code>U
+ <em>cv</em>*</code>, or <code>U <em>cv</em>* const&amp;</code>,
+ where <code>T*</code> is convertible to <code>U*</code>, and
+ <code>a1</code>-<code>a3</code>, if supplied, may be selected in
+ any order from the table below.</li>
+
+ <li>Otherwise, if fn is a member function pointer, its target
+ must be <code>T</code> or one of its public base classes, and
+ <code>a1</code>-<code>a3</code>, if supplied, may be selected in
+ any order from the table below.</li>
+
+ <li>Otherwise, <code>Fn</code> must be [derived from]
+ <code><a href="object.html#object-spec">object</a></code>, and
+ <code>a1-a2</code>, if supplied, may be selcted in any order from
+ the first two rows of the table below. To be useful,
+ <code>fn</code> should be <a href=
+ "http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">
+ callable</a>.</li>
+ </ul>
+
+ <table border="1" summary="def() optional arguments">
+ <tr>
+ <th>Memnonic Name</th>
+
+ <th>Requirements/Type properties</th>
+
+ <th>Effects</th>
+ </tr>
+
+ <tr>
+ <td>docstring</td>
+
+ <td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
+
+ <td>Value will be bound to the <code>__doc__</code> attribute
+ of the resulting method overload. If an earlier overload
+ supplied a docstring, two newline characters and the new
+ docstring are appended to it.</td>
+ </tr>
+
+ <tr>
+ <td>policies</td>
+
+ <td>A model of <a href=
+ "CallPolicies.html">CallPolicies</a></td>
+
+ <td>A copy will be used as the call policies of the resulting
+ method overload.</td>
+ </tr>
+
+ <tr>
+ <td>keywords</td>
+
+ <td>The result of a <a href=
+ "args.html#keyword-expression"><em>keyword-expression</em></a>
+ specifying no more arguments than the <a href=
+ "definitions.html#arity">arity</a> of <code>fn</code>.</td>
+
+ <td>A copy will be used as the call policies of the resulting
+ method overload.</td>
+ </tr>
+ </table>
+ </li>
+ </ul>
+ </dd>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+ </dl>
+ <pre>
+class_&amp; staticmethod(char const* name);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>, and corresponds to a method whose overloads have all
+ been defined.</dt>
+
+ <dt><b>Effects:</b> Replaces the existing named attribute <i>x</i> with
+ the result of invoking <code>staticmethod(</code><i>x</i><code>)</code>
+ 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:</dt>
+
+ <dd>
+ <pre>
+setattr(self, name, staticmethod(getattr(self, name)))
+</pre>
+ </dd>
+
+ <dt><b>Note:</b> Attempting to invoke <code>def(name,...)</code> after
+ invoking <code>staticmethod(name)</code> will <a href=
+ "definitions.html#raise">raise</a> a RuntimeError.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+ </dl><br>
+ <pre>
+template &lt;<i>unspecified</i>&gt;
+class_&amp; def(<a href=
+"operators.html#operator_-spec">detail::operator_</a>&lt;unspecified&gt;);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Adds a Python <a href=
+ "http://www.python.org/doc/ref/specialnames.html">special method</a> as
+ described <a href="operators.html">here</a>.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+ </dl>
+ <pre>
+template &lt;class U&gt;
+class_&amp; setattr(char const* name, U const&amp; u);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>.</dt>
+
+ <dt><b>Effects:</b> Converts u to Python and adds it to the attribute
+ dictionary of the extension class:</dt>
+
+ <dd>
+ <blockquote>
+ <code><a href=
+ "http://www.python.org/doc/current/api/object.html#l2h-166">PyObject_SetAttrString</a>(this-&gt;ptr(),
+ name, <a href=
+ "object.html#object-spec-ctors">object</a>(u).ptr());</code>
+ </blockquote>
+ </dd>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+ </dl><br>
+ <pre>
+template &lt;class Get&gt;
+void add_property(char const* name, Get const&amp; fget, char const* doc=0);
+template &lt;class Get, class Set&gt;
+void add_property(
+ char const* name, Get const&amp; fget, Set const&amp; fset, char const* doc=0);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conform to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>.</dt>
+
+ <dt><b>Effects:</b> Creates a new Python <a href=
+ "http://www.python.org/2.2.2/descrintro.html#property"><code>property</code></a>
+ class instance, passing <code><a href=
+ "object.html#object-spec-ctors">object</a>(fget)</code> (and
+ <code><a href="object.html#object-spec-ctors">object</a>(fset)</code> in
+ the second form) with an (optional) docstring <code>doc</code> to its
+ constructor, then adds that property to the Python class object under
+ construction with the given attribute <code>name</code>.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ <dt><b>Rationale:</b> Allows users to easily expose functions that can be
+ invoked from Python with attribute access syntax.</dt>
+ </dl><br>
+ <pre>
+template &lt;class Get&gt;
+void add_static_property(char const* name, Get const&amp; fget);
+template &lt;class Get, class Set&gt;
+void add_static_property(char const* name, Get const&amp; fget, Set const&amp; fset);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>.</dt>
+
+ <dt><b>Effects:</b> Creates a Boost.Python.StaticProperty object, passing
+ <code><a href="object.html#object-spec-ctors">object</a>(fget)</code>
+ (and <code><a href=
+ "object.html#object-spec-ctors">object</a>(fset)</code> in the second
+ form) to its constructor, then adds that property to the Python class
+ under construction with the given attribute <code>name</code>.
+ StaticProperty is a special subclass of Python's <a href=
+ "http://www.python.org/2.2.2/descrintro.html#property"><code>property</code></a>
+ class which can be called without an initial <code>self</code>
+ argument.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ <dt><b>Rationale:</b> Allows users to easily expose functions that can be
+ invoked from Python with static attribute access syntax.</dt>
+ </dl><br>
+ <pre>
+template &lt;class D&gt;
+class_&amp; def_readonly(char const* name, D T::*pm, char const* doc=0);
+template &lt;class D&gt;
+class_&amp; def_readonly(char const* name, D const&amp; d);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>. <code>doc</code> is also an ntbs.</dt>
+
+ <dt><b>Effects:</b></dt>
+
+ <dd>
+ <pre>
+this-&gt;add_property(name, <a href=
+"data_members.html#make_getter-spec">make_getter</a>(pm), doc);
+</pre>and
+ <pre>
+this-&gt;add_static_property(name, <a href=
+"data_members.html#make_getter-spec">make_getter</a>(d));
+</pre>respectively.<br>
+ <br>
+ </dd>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ <dt><b>Rationale:</b> Allows users to easily expose a class' data member
+ or free variable such that it can be inspected from Python with a natural
+ syntax.</dt>
+ </dl>
+ <pre>
+template &lt;class D&gt;
+class_&amp; def_readwrite(char const* name, D T::*pm, char const* doc=0);
+template &lt;class D&gt;
+class_&amp; def_readwrite(char const* name, D&amp; d);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b></dt>
+
+ <dd>
+ <pre>
+this-&gt;add_property(name, <a href=
+"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
+"data_members.html#make_setter-spec">make_setter</a>(pm), doc);
+</pre>and
+ <pre>
+this-&gt;add_static_property(name, <a href=
+"data_members.html#make_getter-spec">make_getter</a>(d), <a href=
+"data_members.html#make_setter-spec">make_setter</a>(d));
+</pre>respectively.<br>
+ <br>
+ </dd>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ <dt><b>Rationale:</b> 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.</dt>
+ </dl>
+ <pre>
+template &lt;typename PickleSuite&gt;
+class_&amp; def_pickle(PickleSuite const&amp;);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> PickleSuite must be publically derived from <a href=
+ "pickle.html"><code>pickle_suite</code></a>.</dt>
+
+ <dt><b>Effects:</b> Defines a legal combination of the special attributes
+ and methods: <code>__getinitargs__</code>, <code>__getstate__</code>,
+ <code>__setstate__</code>, <code>__getstate_manages_dict__</code>,
+ <code>__safe_for_unpickling__</code>, <code>__reduce__</code></dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ <dt><b>Rationale:</b> Provides an <a href="pickle.html">easy to use
+ high-level interface</a> for establishing complete pickle support for the
+ wrapped class. The user is protected by compile-time consistency
+ checks.</dt>
+ </dl><br>
+ <pre>
+class_&amp; enable_pickling();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Defines the <code>__reduce__</code> method and the
+ <code>__safe_for_unpickling__</code> attribute.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ <dt><b>Rationale:</b> Light-weight alternative to
+ <code>def_pickle()</code>. Enables implementation of <a href=
+ "pickle.html">pickle support</a> from Python.</dt>
+ </dl><br>
+
+ <h3><a name="bases-spec" id="bases-spec"></a>Class template
+ <code>bases&lt;T1, T2,</code>...<code>TN&gt;</code></h3>
+
+ <p>An <a href="../../../mpl/doc/refmanual/forward-sequence.html">MPL
+ sequence</a> which can be used in
+ <code>class_&lt;</code>...<code>&gt;</code> instantiations indicate a list
+ of base classes.</p>
+
+ <h4><a name="bases-spec-synopsis" id="bases-spec-synopsis"></a>Class
+ template <code>bases</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python
+{
+ template &lt;T1 = <i>unspecified</i>,...T<i>n</i> = <i>unspecified</i>&gt;
+ struct bases
+ {};
+}}
+</pre>
+
+ <h2><a name="examples" id="examples"></a>Example(s)</h2>
+
+ <p>Given a C++ class declaration:</p>
+ <pre>
+class Foo : public Bar, public Baz
+{
+ public:
+ Foo(int x, char const* y);
+ Foo(double);
+
+ std::string const&amp; name() { return m_name; }
+ void name(char const*);
+
+ double value; // public data
+ private:
+ ...
+};
+</pre>A corresponding Boost.Python extension class can be created with:
+ <pre>
+using namespace boost::python;
+
+class_&lt;Foo,bases&lt;Bar,Baz&gt; &gt;("Foo",
+ "This is Foo's docstring."
+ "It describes our Foo extension class",
+
+ init&lt;int,char const*&gt;(args("x","y"), "__init__ docstring")
+ )
+ .def(init&lt;double&gt;())
+ .def("get_name", &amp;Foo::get_name, return_internal_reference&lt;&gt;())
+ .def("set_name", &amp;Foo::set_name)
+ .def_readwrite("value", &amp;Foo::value)
+ ;
+</pre>
+ <hr>
+ <a name="footnote_1" id="footnote_1">[1]</a> By "previously-exposed" we
+ mean that the for each <code>B</code> in <code>bases</code>, an instance of
+ <code>class_&lt;B<font color="#007F00">, ...</font>&gt;</code> must have
+ already been constructed.
+ <pre>
+class_&lt;Base&gt;("Base");
+class_&lt;Derived, bases&lt;Base&gt; &gt;("Derived");
+</pre>Revised
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 1 November, 2005 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/configuration.html b/libs/python/doc/v2/configuration.html
new file mode 100644
index 000000000..1be862ed6
--- /dev/null
+++ b/libs/python/doc/v2/configuration.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - Configuration</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Configuration</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#app-defined">Application Defined Macros</a></dt>
+
+ <dt><a href="#lib-defined-impl">Library Defined Implementation
+ Macros</a></dt>
+ </dl>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><b>Boost.Python</b> uses several configuration macros in <a href=
+ "http://www.boost.org/libs/config/config.htm">&lt;boost/config.hpp&gt;</a>,
+ as well as configuration macros meant to be supplied by the application.
+ These macros are documented here.</p>
+
+ <h2><a name="app-defined"></a>Application Defined Macros</h2>
+
+ <p>These are the macros that may be defined by an application using
+ <b>Boost.Python</b>. 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 <b>Boost.Python</b> library itself) is a violation of the
+ <a href="definitions.html#ODR">ODR</a>. However, we know of no C++
+ implementations on which this particular violation is detectable or
+ causes any problems.</p>
+
+ <table summary="application defined macros" width="100%" cellpadding=
+ "10">
+ <tr>
+ <th align="left"><b>Macro</b></th>
+
+ <th><b>Default</b></th>
+
+ <th align="left"><b>Meaning</b></th>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_MAX_ARITY</code></td>
+
+ <td valign="top" align="center">15</td>
+
+ <td valign="top">The maximum <a href=
+ "definitions.html#arity">arity</a> of any function, member function,
+ or constructor to be wrapped, invocation of a <b>Boost.Python</b>
+ function wich is specified as taking arguments
+ <code>x1,&nbsp;x2,</code>...<code>X</code><i>n</i>. This includes, in
+ particular, callback mechanisms such as <code><a href=
+ "object.html#object-spec">object</a>::operator()(</code>...<code>)</code>
+ or <code><a href=
+ "call_method.html#call_method-spec">call_method</a>&lt;R&gt;(</code>...
+ <code>)</code>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_MAX_BASES</code></td>
+
+ <td valign="top" align="center">10</td>
+
+ <td valign="top">The maximum number of template arguments to the
+ <code><a href=
+ "class.html#bases-spec">bases</a>&lt;</code>...<code>&gt;</code>
+ class template, which is used to specify the bases of a wrapped C++
+ class..</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_STATIC_MODULE</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined, prevents your module initialization
+ function from being treated as an exported symbol on platforms which
+ support that distinction in-code</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_ENABLE_CDECL</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined, allows functions using the <code>__cdecl
+ </code> calling convention to be wrapped.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_ENABLE_STDCALL</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined, allows functions using the <code>__stdcall
+ </code> calling convention to be wrapped.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_ENABLE_FASTCALL</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined, allows functions using the <code>__fastcall
+ </code> calling convention to be wrapped.</td>
+ </tr>
+ </table>
+
+ <h2><a name="lib-defined-impl"></a>Library Defined Implementation
+ Macros</h2>
+
+ <p>These macros are defined by <b>Boost.Python</b> and are implementation
+ details of interest only to implementors and those porting to new
+ platforms.</p>
+
+ <table summary="library defined implementation macros" width="100%"
+ cellpadding="10">
+ <tr>
+ <th align="left"><b>Macro</b></th>
+
+ <th><b>Default</b></th>
+
+ <th align="left"><b>Meaning</b></th>
+ </tr>
+
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_TYPE_ID_NAME</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If 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
+ <code>typeid(T)</code> to a function in shared-lib-2 which compares
+ it to <code>typeid(T)</code>, that comparison may return
+ <code>false</code>. If this macro is #defined, Boost.Python uses and
+ compares <code>typeid(T).name()</code> instead of using and comparing
+ the <code>std::type_info</code> objects directly.</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_NO_PY_SIGNATURES</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined for a module no pythonic signatures are generated
+ for the docstrings of the module functions, and no python type is associated with any
+ of the converters registered by the module. This also reduces the binary size of the
+ module by about 14% (gcc compiled).<br>
+ If defined for the boost_python runtime library, the default for the
+ <code>docstring_options.enable_py_signatures()</code> is set to <code>false</code>.
+ </td>
+
+ </tr>
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code></td>
+
+ <td valign="top" align="center"><i>defined if <code>BOOST_PYTHON_NO_PY_SIGNATURES</code> is undefined</i></td>
+
+ <td valign="top">This macro is defined to enable a smooth transition from older Boost.Python versions
+ which do not support pythonic signatures. For example usage see
+ <a href="pytype_function.html#examples">here</a>.
+ </td>
+
+ </tr>
+ <tr>
+ <td valign="top"><code>BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE</code></td>
+
+ <td valign="top" align="center"><i>not&nbsp;defined</i></td>
+
+ <td valign="top">If defined the python type of <code>__init__</code> method "self" parameters
+ is properly generated, otherwise <code><b>object</b></code> is used. It is undefined
+ by default because it increases the binary size of the module by about 14% (gcc compiled).</td>
+
+ </tr>
+ </table>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 7 January, 2003
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/copy_const_reference.html b/libs/python/doc/v2/copy_const_reference.html
new file mode 100644
index 000000000..97c2a282c
--- /dev/null
+++ b/libs/python/doc/v2/copy_const_reference.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/copy_const_reference.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/copy_const_reference.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#copy_const_reference-spec">Class
+ <code>copy_const_reference</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#copy_const_reference-spec-synopsis">Class
+ <code>copy_const_reference</code> synopsis</a></dt>
+
+ <dt><a href="#copy_const_reference-spec-metafunctions">Class
+ <code>copy_const_reference</code> metafunctions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="copy_const_reference-spec"></a>Class
+ <code>copy_const_reference</code></h3>
+
+ <p><code>copy_const_reference</code> is a model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
+ 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.</p>
+
+ <h4><a name="copy_const_reference-spec-synopsis"></a>Class
+ <code>copy_const_reference</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct copy_const_reference
+ {
+ template &lt;class T&gt; struct apply;
+ };
+}}
+</pre>
+
+ <h4><a name="copy_const_reference-spec-metafunctions"></a>Class
+ <code>copy_const_reference</code> metafunctions</h4>
+<pre>
+template &lt;class T&gt; struct apply
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Requires:</b> <code>T</code> is <code>U const&amp;</code> for
+ some <code>U</code>.</dt>
+
+ <dt><b>Returns:</b> <code>typedef <a href=
+ "to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T&gt;
+ type;</code></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ Module Definition</h3>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/copy_const_reference.hpp&gt;
+#include &lt;boost/python/return_value_policy.hpp&gt;
+
+// classes to wrap
+struct Bar { int x; }
+
+struct Foo {
+ Foo(int x) : { b.x = x; }
+ Bar const&amp; get_bar() const { return b; }
+ private:
+ Bar b;
+};
+
+// Wrapper code
+using namespace boost::python;
+BOOST_PYTHON_MODULE(my_module)
+{
+ class_&lt;Bar&gt;("Bar");
+
+ class_&lt;Foo&gt;("Foo", init&lt;int&gt;())
+ .def("get_bar", &amp;Foo::get_bar
+ , return_value_policy&lt;copy_const_reference&gt;())
+ ;
+}
+</pre>
+
+ <h3>Python Code</h3>
+<pre>
+&gt;&gt;&gt; from my_module import *
+&gt;&gt;&gt; f = Foo(3) # create a Foo object
+&gt;&gt;&gt; b = f.get_bar() # make a copy of the internal Bar object
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/copy_non_const_reference.html b/libs/python/doc/v2/copy_non_const_reference.html
new file mode 100644
index 000000000..987efad83
--- /dev/null
+++ b/libs/python/doc/v2/copy_non_const_reference.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/copy_non_const_reference.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/copy_non_const_reference.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#copy_non_const_reference-spec">Class
+ <code>copy_non_const_reference</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#copy_non_const_reference-spec-synopsis">Class
+ <code>copy_non_const_reference</code> synopsis</a></dt>
+
+ <dt><a href=
+ "#copy_non_const_reference-spec-metafunctions">Class
+ <code>copy_non_const_reference</code> metafunctions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="copy_non_const_reference-spec"></a>Class
+ <code>copy_non_const_reference</code></h3>
+
+ <p><code>copy_non_const_reference</code> is a model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
+ 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.</p>
+
+ <h4><a name="copy_non_const_reference-spec-synopsis"></a>Class
+ <code>copy_non_const_reference</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct copy_non_const_reference
+ {
+ template &lt;class T&gt; struct apply;
+ };
+}}
+</pre>
+
+ <h4><a name="copy_non_const_reference-spec-metafunctions"></a>Class
+ <code>copy_non_const_reference</code> metafunctions</h4>
+<pre>
+template &lt;class T&gt; struct apply
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Requires:</b> <code>T</code> is <code>U&amp;</code> for some
+ non-const <code>U</code>.</dt>
+
+ <dt><b>Returns:</b> <code>typedef <a href=
+ "to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T&gt;
+ type;</code></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <p>C++ code:</p>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/copy_non_const_reference.hpp&gt;
+#include &lt;boost/python/return_value_policy.hpp&gt;
+
+// classes to wrap
+struct Bar { int x; }
+
+struct Foo {
+ Foo(int x) : { b.x = x; }
+ Bar&amp; get_bar() { return b; }
+ private:
+ Bar b;
+};
+
+// Wrapper code
+using namespace boost::python;
+BOOST_PYTHON_MODULE(my_module)
+{
+ class_&lt;Bar&gt;("Bar");
+
+ class_&lt;Foo&gt;("Foo", init&lt;int&gt;())
+ .def("get_bar", &amp;Foo::get_bar
+ , return_value_policy&lt;copy_non_const_reference&gt;())
+ ;
+}
+</pre>
+ Python Code:
+<pre>
+&gt;&gt;&gt; from my_module import *
+&gt;&gt;&gt; f = Foo(3) # create a Foo object
+&gt;&gt;&gt; b = f.get_bar() # make a copy of the internal Bar object
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/data_members.html b/libs/python/doc/v2/data_members.html
new file mode 100644
index 000000000..36f818d3d
--- /dev/null
+++ b/libs/python/doc/v2/data_members.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/data_members.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/data_members.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#make_getter-spec">make_getter</a></dt>
+
+ <dt><a href="#make_setter-spec">make_setter</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code><a href="#make_getter-spec">make_getter</a>()</code> and
+ <code><a href="#make_setter-spec">make_setter</a>()</code> are the
+ functions used internally by <code>class_&lt;&gt;::<a href=
+ "class.html#class_-spec-modifiers">def_readonly</a></code> and
+ <code>class_&lt;&gt;::<a href=
+ "class.html#class_-spec-modifiers">def_readwrite</a></code> to produce
+ Python callable objects which wrap C++ data members.</p>
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name="make_getter-spec">template &lt;class C, class D&gt;</a>
+<a href="object.html#object-spec">object</a> make_getter(D C::*pm);
+
+template &lt;class C, class D, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_getter(D C::*pm, Policies const&amp; policies);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
+ "CallPolicies.html">CallPolicies</a>.</dt>
+
+ <dt><b>Effects:</b> Creates a Python callable object which accepts a
+ single argument that can be converted <code>from_python</code> to
+ <code>C*</code>, and returns the corresponding member <code>D</code>
+ member of the <code>C</code> object, converted <code>to_python</code>.
+ If <code>policies</code> is supplied, it will be applied to the
+ function as described <a href="CallPolicies.html">here</a>. Otherwise,
+ the library attempts to determine whether <code>D</code> is a
+ user-defined class type, and if so uses <code><a href=
+ "return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a>&lt;&gt;</code></dt>
+
+ <dt>for <code>Policies</code>. Note that this test may inappropriately
+ choose <code>return_internal_reference&lt;&gt;</code> in some cases
+ when <code>D</code> is a smart pointer type. This is a known
+ defect.</dt>
+
+ <dt><b>Returns:</b> An instance of <a href=
+ "object.html#object-spec">object</a> which holds the new Python
+ callable object.</dt>
+ </dl>
+<pre>
+template &lt;class D&gt;
+<a href="object.html#object-spec">object</a> make_getter(D const&amp; d);
+template &lt;class D, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_getter(D const&amp; d, Policies const&amp; policies);
+
+template &lt;class D&gt;
+<a href="object.html#object-spec">object</a> make_getter(D const* p);
+template &lt;class D, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_getter(D const* p, Policies const&amp; policies);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
+ "CallPolicies.html">CallPolicies</a>.</dt>
+
+ <dt><b>Effects:</b> Creates a Python callable object which accepts no
+ arguments and returns <code>d</code> or <code>*p</code>, converted
+ <code>to_python</code> on demand. If <code>policies</code> is supplied,
+ it will be applied to the function as described <a href=
+ "CallPolicies.html">here</a>. Otherwise, the library attempts to
+ determine whether <code>D</code> is a user-defined class type, and if
+ so uses <code><a href=
+ "reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a></code></dt>
+
+ <dt>for <code>Policies</code>.</dt>
+
+ <dt><b>Returns:</b> An instance of <a href=
+ "object.html#object-spec">object</a> which holds the new Python
+ callable object.</dt>
+ </dl>
+<pre>
+<a name="make_setter-spec">template &lt;class C, class D&gt;</a>
+<a href="object.html#object-spec">object</a> make_setter(D C::*pm);
+
+template &lt;class C, class D, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_setter(D C::*pm, Policies const&amp; policies);
+</pre>
+
+ <dl class="function*-semantics">
+ <dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
+ "CallPolicies.html">CallPolicies</a>.</dt>
+
+ <dt><b>Effects:</b> Creates a Python callable object which, when called
+ from Python, expects two arguments which can be converted
+ <code>from_python</code> to <code>C*</code> and
+ <code>D&nbsp;const&amp;</code>, respectively, and sets the
+ corresponding <code>D</code> member of the <code>C</code> object. If
+ <code>policies</code> is supplied, it will be applied to the function
+ as described <a href="CallPolicies.html">here</a>.</dt>
+
+ <dt><b>Returns:</b> An instance of <a href=
+ "object.html#object-spec">object</a> which holds the new Python
+ callable object.</dt>
+ </dl>
+<pre>
+template &lt;class D&gt;
+<a href="object.html#object-spec">object</a> make_setter(D&amp; d);
+template &lt;class D, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_setter(D&amp; d, Policies const&amp; policies);
+
+template &lt;class D&gt;
+<a href="object.html#object-spec">object</a> make_setter(D* p);
+template &lt;class D, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_setter(D* p, Policies const&amp; policies);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
+ "CallPolicies.html">CallPolicies</a>.</dt>
+
+ <dt><b>Effects:</b> Creates a Python callable object which accepts one
+ argument, which is converted from Python to <code>D const&amp;</code>
+ and written into <code>d</code> or <code>*p</code>, respectively. If
+ <code>policies</code> is supplied, it will be applied to the function
+ as described <a href="CallPolicies.html">here</a>.</dt>
+
+ <dt><b>Returns:</b> An instance of <a href=
+ "object.html#object-spec">object</a> which holds the new Python
+ callable object.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <p>The code below uses make_getter and make_setter to expose a data
+ member as functions:</p>
+<pre>
+#include &lt;boost/python/data_members.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+
+struct X
+{
+ X(int x) : y(x) {}
+ int y;
+};
+
+using namespace boost::python;
+
+BOOST_PYTHON_MODULE_INIT(data_members_example)
+{
+ class_&lt;X&gt;("X", init&lt;int&gt;())
+ .def("get", make_getter(&amp;X::y))
+ .def("set", make_setter(&amp;X::y))
+ ;
+}
+</pre>
+ It can be used this way in Python:
+<pre>
+&gt;&gt;&gt; from data_members_example import *
+&gt;&gt;&gt; x = X(1)
+&gt;&gt;&gt; x.get()
+1
+&gt;&gt;&gt; x.set(2)
+&gt;&gt;&gt; x.get()
+2
+</pre>
+
+ <p>
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 5 August, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/def.html b/libs/python/doc/v2/def.html
new file mode 100644
index 000000000..3c71fd363
--- /dev/null
+++ b/libs/python/doc/v2/def.html
@@ -0,0 +1,191 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/def.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/def.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#def-spec">def</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code><a href="#def-spec">def</a>()</code> is the function which can
+ be used to expose C++ functions and callable objects as Python functions
+ in the current <code><a href="scope.html">scope</a></code>.</p>
+
+ <h2><a name="functions"></a>Functions</h2>
+ <a name="def-spec"></a>def
+<pre>
+template &lt;class F&gt;
+void def(char const* name, F f);
+
+template &lt;class Fn, class A1&gt;
+void def(char const* name, Fn fn, A1 const&amp;);
+
+template &lt;class Fn, class A1, class A2&gt;
+void def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;);
+
+template &lt;class Fn, class A1, class A2, class A3&gt;
+void def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>.</dt>
+
+ <dd>
+ <ul>
+ <li>If <code>Fn</code> is [derived from] <code><a href=
+ "object.html#object-spec">object</a></code>, it will be added to
+ the current scope as a single overload. To be useful,
+ <code>fn</code> should be <a href=
+ "http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">callable</a>.</li>
+
+ <li>
+ If <code>a1</code> is the result of an <a href=
+ "overloads.html#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>,
+ only the second form is allowed and fn must be a pointer to
+ function or pointer to member function whose <a href=
+ "definitions.html#arity">arity</a> is the same as A1's <a href=
+ "overloads.html#overload-dispatch-expression"><em>maximum
+ arity</em></a>.
+
+ <dl>
+ <dt><b>Effects:</b> For each prefix <em>P</em> of
+ <code>Fn</code>'s sequence of argument types, beginning with
+ the one whose length is <code>A1</code>'s <a href=
+ "overloads.html#overload-dispatch-expression"><em>minimum
+ arity</em></a>, adds a
+ <code><em>name</em>(</code>...<code>)</code> function overload
+ to the <a href="scope.html">current scope</a>. Each overload
+ generated invokes <code>a1</code>'s call-expression with
+ <em>P</em>, using a copy of <code>a1</code>'s <a href=
+ "CallPolicies.html">call policies</a>. If the longest valid
+ prefix of <code>A1</code> contains <em>N</em> types and
+ <code>a1</code> holds <em>M</em> keywords, an initial sequence
+ of the keywords are used for all but the first
+ <em>N</em>&nbsp;-&nbsp;<em>M</em> arguments of each
+ overload.<br>
+ </dt>
+ </dl>
+ </li>
+
+ <li>Otherwise, fn must be a non-null function or member function
+ pointer, and a single function overload built around fn is added to
+ the <a href="scope.html">current scope</a>. If any of
+ <code>a1</code>-<code>a3</code> are supplied, they may be selected
+ in any order from the table below.</li>
+ </ul>
+
+ <table border="1" summary="def() optional arguments">
+ <tr>
+ <th>Memnonic Name</th>
+
+ <th>Requirements/Type properties</th>
+
+ <th>Effects</th>
+ </tr>
+
+ <tr>
+ <td>docstring</td>
+
+ <td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
+
+ <td>Value will be bound to the <code>__doc__</code> attribute of
+ the resulting method overload.</td>
+ </tr>
+
+ <tr>
+ <td>policies</td>
+
+ <td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
+
+ <td>A copy will be used as the call policies of the resulting
+ method overload.</td>
+ </tr>
+
+ <tr>
+ <td>keywords</td>
+
+ <td>The result of a <a href=
+ "args.html#keyword-expression"><em>keyword-expression</em></a>
+ specifying no more arguments than the <a href=
+ "definitions.html#arity">arity</a> of <code>fn</code>.</td>
+
+ <td>A copy will be used as the call policies of the resulting
+ method overload.</td>
+ </tr>
+ </table>
+ </dd>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/args.hpp&gt;
+
+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");
+}
+</pre>
+
+ <p>
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 7 March, 2003
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/def_visitor.html b/libs/python/doc/v2/def_visitor.html
new file mode 100644
index 000000000..08fa0c514
--- /dev/null
+++ b/libs/python/doc/v2/def_visitor.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="Microsoft FrontPage 5.0">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/def_visitor.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html"><font size="7">Boost.Python</font></a></h1>
+
+ <h2 align="center">Header &lt;boost/python/def_visitor.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a>
+ <dt><a href="#classes">Classes</a>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#def_visitor-spec">Class <code>def_visitor</code></a>
+ <dd> <a href="#def_visitor-synopsis">Class <code>def_visitor</code>
+ synopsis</a></dd>
+ <dd> <a href="#def_visitor-requirements">Class <code>def_visitor</code>
+ requirements</a></dd>
+ </dl>
+ <dt><a href="#examples">Example</a>
+</dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+
+<p><code>&lt;boost/python/def_visitor.hpp&gt;</code> provides a generic visitation
+ interface through which the <a href="class.html">class_</a> <b>def</b> member
+ functionality can be extended non-intrusively to avoid cluttering the <a href="class.html">class_</a>
+ interface. It declares the <code>def_visitor&lt;T&gt; </code>class template,
+ which is parameterized on the derived type <tt>DerivedVisitor</tt>, which provides
+ the actual <b>def</b> functionality through its <b>visit</b> member functions.
+<h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="def_visitor-spec"></a>Class template <code>def_visitor&lt;DerivedVisitor&gt;</code></h3>
+
+
+<p>The class def_visitor is a base class paramaterized by its derived class. The
+ def_visitor class is a protocol class. Its derived class, DerivedVisitor, is
+ expected to have a member function visit. The def_visitor class is never instantiated
+ directly. Instead, an instance of its subclass, DerivedVisitor,&nbsp; is passed
+ on as an argument to the <a href="class.html">class_</a> def member function.
+<h4>
+<a name="def_visitor-synopsis" id="def_visitor-synopsis"></a>Class <code>def_visitor </code>synopsis</h4>
+<pre>namespace boost { namespace python {
+
+ template &lt;class DerivedVisitor&gt;
+ class def_visitor {};
+}</pre>
+<h3><a name="def_visitor-requirements"></a><code>def_visitor </code>requirements</h3>
+
+
+<p>The <span class="pre">client supplied class </span><span class="pre"></span><tt class="literal"><span class="pre">DerivedVisitor</span></tt>
+ template parameter is expected to:
+<ul>
+ <li>be privately derived from def_visitor</li>
+ <li>grant friend access to class def_visitor_access</li>
+ <li>define either or both visit member functions listed in the table below:</li>
+</ul>
+
+
+<table border class="table">
+ <tr>
+ <td width="181" nowrap><b>Expression</b></td>
+ <td width="85"><b>Return Type</b></td>
+ <td width="330"><b>Requirements</b></td>
+ <td width="259"><b>Effects</b></td>
+ </tr>
+ <tr>
+ <td nowrap>visitor.visit(cls)</td>
+ <td>void</td>
+ <td>cls is an instance of a <a href="class.html">class_</a>&nbsp; being wrapped
+ to Python. visitor is a def_visitor derived class.</td>
+ <td>A call to cls.def(visitor) forwards to this member function.</td>
+ </tr>
+ <tr>
+ <td nowrap>visitor.visit(cls, name, options)</td>
+ <td>void</td>
+ <td>cls is a class_ instance, name is a C string. visitor is a def_visitor
+ derived class. options is a context specific optional argument.</td>
+ <td>A call to cls.def(name, visitor) or cls.def(name, visitor, options) forwards
+ to this member function. </td>
+ </tr>
+</table>
+
+ <h2><a name="examples"></a>Example</h2>
+
+
+<pre>class X {/*...*/};<br>
+class my_def_visitor : boost::python::def_visitor&lt;my_def_visitor&gt;
+{
+ friend class def_visitor_access;
+
+ template &lt;class classT&gt;
+ void visit(classT&amp; c) const
+ {
+ c
+ .def(&quot;foo&quot;, &amp;my_def_visitor::foo)
+ .def(&quot;bar&quot;, &amp;my_def_visitor::bar)
+ ;
+ }
+
+ static void foo(X&amp; self);
+ static void bar(X&amp; self);
+};
+
+BOOST_PYTHON_MODULE(my_ext)
+{
+ class_&lt;X&gt;(&quot;X&quot;)
+ .def(my_def_visitor())
+ ;
+}
+</pre>
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->27 August, 2003<!--webbot bot="Timestamp" endspan i-checksum="34484" -->
+ </p>
+
+
+ <p><i>&copy; Copyright Joel de Guzman 2003. </i> Distributed under the Boost
+ Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
diff --git a/libs/python/doc/v2/default_call_policies.html b/libs/python/doc/v2/default_call_policies.html
new file mode 100644
index 000000000..30d0a50de
--- /dev/null
+++ b/libs/python/doc/v2/default_call_policies.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/default_call_policies.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/default_call_policies.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#default_call_policies-spec">Class
+ <code>default_call_policies</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#default_call_policies-spec-synopsis">Class
+ <code>default_call_policies</code> synopsis</a>
+
+ <dt><a href="#default_call_policies-spec-statics">Class
+ <code>default_call_policies</code> static functions</a>
+ </dl>
+
+ <dt><a href="#default_result_converter-spec">Class
+ <code>default_result_converter</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#default_result_converter-spec-synopsis">Class
+ <code>default_result_converter</code> synopsis</a>
+
+ <dt><a href="#default_result_converter-spec-metafunctions">Class
+ <code>default_result_converter</code> metafunctions</a>
+ </dl>
+ </dl>
+
+ <dt><a href="#examples">Example</a>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="default_call_policies-spec"></a>Class
+ <code>default_call_policies</code></h3>
+
+ <p><code>default_call_policies</code> is a model of <a href=
+ "CallPolicies.html">CallPolicies</a> with no <code>precall</code> or
+ <code>postcall</code> behavior and a <code>result_converter</code> which
+ handles by-value returns. Wrapped C++ functions and member functions use
+ <code>default_call_policies</code> unless otherwise specified. You may find
+ it convenient to derive new models of <a href=
+ "CallPolicies.html">CallPolicies</a> from
+ <code>default_call_policies</code>.
+
+ <h4><a name="default_call_policies-spec-synopsis"></a>Class
+ <code>default_call_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct default_call_policies
+ {
+ static bool precall(PyObject*);
+ static PyObject* postcall(PyObject*, PyObject* result);
+ typedef <a href=
+"#default_result_converter-spec">default_result_converter</a> result_converter;
+ template &lt;class Sig&gt; struct extract_return_type : mpl::front&lt;Sig&gt;{};
+ };
+}}
+</pre>
+
+ <h4><a name="default_call_policies-spec-statics"></a>Class
+ <code>default_call_policies</code> static functions</h4>
+<pre>
+bool precall(PyObject*);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>true</code>
+
+ <dt><b>Throws:</b> nothing
+ </dl>
+<pre>
+PyObject* postcall(PyObject*, PyObject* result);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>result</code>
+
+ <dt><b>Throws:</b> nothing
+ </dl>
+
+ <h3><a name="default_result_converter-spec"></a>Class
+ <code>default_result_converter</code></h3>
+
+ <p><code>default_result_converter</code> is a model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a> which can be
+ used to wrap C++ functions returning non-pointer types, <code>char
+ const*</code>, and <code>PyObject*</code>, by-value.
+
+ <h4><a name="default_result_converter-spec-synopsis"></a>Class
+ <code>default_result_converter</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct default_result_converter
+ {
+ template &lt;class T&gt; struct apply;
+ };
+}}
+</pre>
+
+ <h4><a name="default_result_converter-spec-metafunctions"></a>Class
+ <code>default_result_converter</code> metafunctions</h4>
+<pre>
+template &lt;class T&gt; struct apply
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Requires:</b> <code>T</code> is not a reference type. If
+ <code>T</code> is a pointer type, <code>T</code> is <code>const
+ char*</code> or <code>PyObject*</code>.
+
+ <dt><b>Returns:</b> <code>typedef <a href=
+ "to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T
+ const&amp;&gt; type;</code>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <p>This example comes from the Boost.Python implementation itself. Because
+ the <a href=
+ "return_value_policy.html#return_value_policy-spec">return_value_policy</a>
+ class template does not implement <code>precall</code> or
+ <code>postcall</code> behavior, its default base class is
+ <code>default_call_policies</code>:
+<pre>
+template &lt;class Handler, class Base = default_call_policies&gt;
+struct return_value_policy : Base
+{
+ typedef Handler result_converter;
+};
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 11 June, 2007
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002.</i> Distributed under the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)</p>
+
diff --git a/libs/python/doc/v2/definitions.html b/libs/python/doc/v2/definitions.html
new file mode 100644
index 000000000..cfec181c7
--- /dev/null
+++ b/libs/python/doc/v2/definitions.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - Definitions</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Definitions</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <dl class="definitions">
+ <dt><b><a name="arity">arity</a>:</b> The number of arguments accepted
+ by a function or member function. Unless otherwise specified, the
+ hidden "<code>this</code>" argument to member functions is not counted
+ when specifying arity</dt>
+
+ <dd><br>
+ </dd>
+
+ <dt><b><a name="ntbs">ntbs</a>:</b> Null-Terminated Byte String, or
+ `C'-string. C++ string literals are <strong>ntbs</strong>es. An
+ <strong>ntbs</strong> must never be null.</dt>
+
+ <dd><br>
+ </dd>
+
+ <dt><b><a name="raise">raise</a>:</b> 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 <a
+ href=
+ "http://www.python.org/doc/current/api/exceptionHandling.html">Python/'C'
+ API</a>, and <code><a href=
+ "errors.html#throw_error_already_set-spec">throw_error_already_set</a>()</code>
+ is called.</dt>
+
+ <dd><br>
+ </dd>
+
+ <dt><b><a name="POD">POD</a>:</b> 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).</dt>
+
+ <dd><br>
+ </dd>
+
+ <dt><b><a name="ODR">ODR</a>:</b> The &quot;One Definition
+ Rule&quot;, 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.
+ </dt>
+
+ <dd><br>
+ </dd>
+
+
+ </dl>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/dict.html b/libs/python/doc/v2/dict.html
new file mode 100644
index 000000000..82ea13653
--- /dev/null
+++ b/libs/python/doc/v2/dict.html
@@ -0,0 +1,152 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/dict.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/dict.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#dict-spec">Class <code>dict</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#dict-spec-synopsis">Class <code>dict</code>
+ synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
+ <a href=
+ "http://www.python.org/dev/doc/devel/lib/typesmapping.html">dict</a>
+ type.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="dict-spec"></a>Class <code>dict</code></h3>
+
+ <p>Exposes the <a href=
+ "http://www.python.org/dev/doc/devel/lib/typesmapping.html">mapping
+ protocol</a> of Python's built-in <code>dict</code> type. The semantics
+ of the constructors and member functions defined below can be fully
+ understood by reading the <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
+ definition. Since <code>dict</code> is publicly derived from <code><a
+ href="object.html#object-spec">object</a></code>, the public object
+ interface applies to <code>dict</code> instances as well.</p>
+
+ <h4><a name="dict-spec-synopsis"></a>Class <code>dict</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class dict : public object
+ {
+ dict();
+
+ template&lt; class T &gt;
+ dict(T const &amp; data);
+
+ // modifiers
+ void clear();
+ dict copy();
+
+ template &lt;class T1, class T2&gt;
+ tuple popitem();
+
+ template &lt;class T&gt;
+ object setdefault(T const &amp;k);
+
+ template &lt;class T1, class T2&gt;
+ object setdefault(T1 const &amp; k, T2 const &amp; d);
+
+ void update(object_cref E);
+
+ template&lt; class T &gt;
+ void update(T const &amp; E);
+
+ // observers
+ list values() const;
+
+ object get(object_cref k) const;
+
+ template&lt;class T&gt;
+ object get(T const &amp; k) const;
+
+ object get(object_cref k, object_cref d) const;
+ object get(T1 const &amp; k, T2 const &amp; d) const;
+
+ bool has_key(object_cref k) const;
+
+ template&lt; class T &gt;
+ bool has_key(T const &amp; k) const;
+
+ list items() const;
+ object iteritems() const;
+ object iterkeys() const;
+ object itervalues() const;
+ list keys() const;
+ };
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+using namespace boost::python;
+dict swap_object_dict(object target, dict d)
+{
+ dict result = extract&lt;dict&gt;(target.attr("__dict__"));
+ target.attr("__dict__") = d;
+ return result;
+}
+</pre>
+
+ <p>Revised 30 September, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/docstring_options.html b/libs/python/doc/v2/docstring_options.html
new file mode 100644
index 000000000..a2a0cc645
--- /dev/null
+++ b/libs/python/doc/v2/docstring_options.html
@@ -0,0 +1,386 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st September 2004), see www.w3.org">
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/docstring_options.hpp&gt;</title>
+</head>
+
+<body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href=
+ "../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/docstring_options.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#docstring_options-spec">Class
+ <code>docstring_options</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#docstring_options-spec-synopsis">Class
+ <code>docstring_options</code> synopsis</a></dt>
+
+ <dt><a href="#docstring_options-spec-ctors">Class
+ <code>docstring_options</code> constructors</a></dt>
+
+ <dt><a href="#docstring_options-spec-dtors">Class
+ <code>docstring_options</code> destructors</a></dt>
+
+ <dt><a href="#docstring_options-spec-modifiers">Class
+ <code>docstring_options</code> modifiers</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id=
+ "introduction"></a>Introduction</h2>
+
+ <p>Boost.Python supports user-defined docstrings with automatic
+ appending of C++ signatures. These features are enabled by
+ default. The <code>class docstring_options</code> is available to
+ selectively suppress the user-defined docstrings, signatures, or
+ both.</p>
+
+ <h2><a name="classes" id="classes"></a>Classes</h2>
+
+ <h3><a name="docstring_options-spec" id=
+ "docstring_options-spec"></a>Class
+ <code>docstring_options</code></h3>
+
+ <p>Controls the appearance of docstrings of wrapped functions and
+ member functions for the life-time of the instance. The instances
+ are noncopyable to eliminate the possibility of surprising side
+ effects.</p>
+
+ <h4><a name="docstring_options-spec-synopsis" id=
+ "docstring_options-spec-synopsis"></a>Class
+ <code>docstring_options</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python {
+
+ class docstring_options : boost::noncopyable
+ {
+ public:
+ docstring_options(bool show_all=true);
+
+ docstring_options(bool show_user_defined, bool show_signatures);
+
+ docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
+
+ ~docstring_options();
+
+ void
+ disable_user_defined();
+
+ void
+ enable_user_defined();
+
+ void
+ disable_signatures();
+
+ void
+ enable_signatures();
+
+ void
+ disable_py_signatures();
+
+ void
+ enable_py_signatures();
+
+ void
+ disable_cpp_signatures();
+
+ void
+ enable_cpp_signatures();
+
+ void
+ disable_all();
+
+ void
+ enable_all();
+ };
+
+}}
+</pre>
+
+ <h4><a name="docstring_options-spec-ctors" id=
+ "docstring_options-spec-ctors"></a>Class
+ <code>docstring_options</code> constructors</h4>
+ <pre>
+docstring_options(bool show_all=true);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Constructs a <code>docstring_options</code>
+ object which controls the appearance of function and
+ member-function docstrings defined in the code that follows. If
+ <code>show_all</code> is <code>true</code>, both the
+ user-defined docstrings and the automatically generated Python and C++
+ signatures are shown. If <code>show_all</code> is
+ <code>false</code> the <code>__doc__</code> attributes are
+ <code>None</code>.</dt>
+ </dl>
+ <pre>
+docstring_options(bool show_user_defined, bool show_signatures);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Constructs a <code>docstring_options</code>
+ object which controls the appearance of function and
+ member-function docstrings defined in the code that follows.
+ Iff <code>show_user_defined</code> is <code>true</code>, the
+ user-defined docstrings are shown. Iff
+ <code>show_signatures</code> is <code>true</code>, Python and C++
+ signatures are automatically added. If both
+ <code>show_user_defined</code> and <code>show_signatures</code>
+ are <code>false</code>, the <code>__doc__</code> attributes are
+ <code>None</code>.</dt>
+ </dl>
+ <pre>
+docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Constructs a <code>docstring_options</code>
+ object which controls the appearance of function and
+ member-function docstrings defined in the code that follows.
+ Iff <code>show_user_defined</code> is <code>true</code>, the
+ user-defined docstrings are shown. Iff
+ <code>show_py_signatures</code> is <code>true</code>, Python
+ signatures are automatically added. Iff
+ <code>show_cpp_signatures</code> is <code>true</code>, C++
+ signatures are automatically added. If all parameters are
+ <code>false</code>, the <code>__doc__</code> attributes are
+ <code>None</code>.</dt>
+ </dl>
+
+ <h4><a name="docstring_options-spec-dtors" id=
+ "docstring_options-spec-dtors"></a>Class
+ <code>docstring_options</code> destructors</h4>
+ <pre>
+~docstring_options();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Restores the previous state of the
+ docstring options. In particular, if
+ <code>docstring_options</code> instances are in nested C++
+ scopes the settings effective in the enclosing scope are
+ restored. If the last <code>docstring_options</code> instance
+ goes out of scope the default "all on" settings are
+ restored.</dt>
+ </dl>
+
+ <h4><a name="docstring_options-spec-modifiers" id=
+ "docstring_options-spec-modifiers"></a>Class
+ <code>docstring_options</code> modifier functions</h4>
+ <pre>
+void disable_user_defined();
+void enable_user_defined();
+void disable_signatures();
+void enable_signatures();
+void disable_py_signatures();
+void enable_py_signatures();
+void disable_cpp_signatures();
+void enable_cpp_signatures();
+void disable_all();
+void enable_all();
+</pre>
+
+ <dl class="function-semantics">
+ <dt>These member functions dynamically change the appearance of
+ docstrings in the code that follows. The
+ <code>*_user_defined()</code> and <code>*_signatures()</code>
+ member functions are provided for fine-grained control. The
+ <code>*_all()</code> member functions are convenient shortcuts
+ to manipulate all settings simultaneously.</dt>
+ </dl>
+
+ <h2><a name="examples" id="examples"></a>Examples</h2>
+
+ <h4>Docstring options defined at compile time</h4>
+ <pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/docstring_options.hpp&gt;
+
+void foo() {}
+
+BOOST_PYTHON_MODULE(demo)
+{
+ using namespace boost::python;
+ docstring_options doc_options(DEMO_DOCSTRING_SHOW_ALL);
+ def("foo", foo, "foo doc");
+}
+</pre>If compiled with <code>-DDEMO_DOCSTRING_SHOW_ALL=true</code>:
+ <pre>
+&gt;&gt;&gt; import demo
+&gt;&gt;&gt; print demo.foo.__doc__
+foo() -&gt; None : foo doc
+C++ signature:
+ foo(void) -&gt; void
+</pre>If compiled with
+<code>-DDEMO_DOCSTRING_SHOW_ALL=false</code>:
+ <pre>
+&gt;&gt;&gt; import demo
+&gt;&gt;&gt; print demo.foo.__doc__
+None
+</pre>
+
+ <h4>Selective suppressions</h4>
+ <pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/args.hpp&gt;
+#include &lt;boost/python/docstring_options.hpp&gt;
+
+int foo1(int i) { return i; }
+int foo2(long l) { return static_cast&lt;int&gt;(l); }
+int foo3(float f) { return static_cast&lt;int&gt;(f); }
+int foo4(double d) { return static_cast&lt;int&gt;(d); }
+
+BOOST_PYTHON_MODULE(demo)
+{
+ using namespace boost::python;
+ docstring_options doc_options;
+ def("foo1", foo1, arg("i"), "foo1 doc");
+ doc_options.disable_user_defined();
+ def("foo2", foo2, arg("l"), "foo2 doc");
+ doc_options.disable_signatures();
+ def("foo3", foo3, arg("f"), "foo3 doc");
+ doc_options.enable_user_defined();
+ def("foo4", foo4, arg("d"), "foo4 doc");
+ doc_options.enable_py_signatures();
+ def("foo5", foo4, arg("d"), "foo5 doc");
+ doc_options.disable_py_signatures();
+ doc_options.enable_cpp_signatures();
+ def("foo6", foo4, arg("d"), "foo6 doc");
+}
+</pre>Python code:
+ <pre>
+&gt;&gt;&gt; import demo
+&gt;&gt;&gt; print demo.foo1.__doc__
+foo1( (int)i) -&gt; int : foo1 doc
+C++ signature:
+ foo1(int i) -&gt; int
+&gt;&gt;&gt; print demo.foo2.__doc__
+foo2( (int)l) -&gt; int :
+C++ signature:
+ foo2(long l) -&gt; int
+&gt;&gt;&gt; print demo.foo3.__doc__
+None
+&gt;&gt;&gt; print demo.foo4.__doc__
+foo4 doc
+&gt;&gt;&gt; print demo.foo5.__doc__
+foo5( (float)d) -&gt; int : foo5 doc
+&gt;&gt;&gt; print demo.foo6.__doc__
+foo6 doc
+C++ signature:
+ foo6(double d) -&gt; int
+</pre>
+
+ <h4>Wrapping from multiple C++ scopes</h4>
+ <pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/args.hpp&gt;
+#include &lt;boost/python/docstring_options.hpp&gt;
+
+int foo1(int i) { return i; }
+int foo2(long l) { return static_cast&lt;int&gt;(l); }
+
+int bar1(int i) { return i; }
+int bar2(long l) { return static_cast&lt;int&gt;(l); }
+
+namespace {
+
+ void wrap_foos()
+ {
+ using namespace boost::python;
+ // no docstring_options here
+ // -&gt; settings from outer C++ scope are in effect
+ def("foo1", foo1, arg("i"), "foo1 doc");
+ def("foo2", foo2, arg("l"), "foo2 doc");
+ }
+
+ void wrap_bars()
+ {
+ using namespace boost::python;
+ bool show_user_defined = true;
+ bool show_signatures = false;
+ docstring_options doc_options(show_user_defined, show_signatures);
+ def("bar1", bar1, arg("i"), "bar1 doc");
+ def("bar2", bar2, arg("l"), "bar2 doc");
+ }
+}
+
+BOOST_PYTHON_MODULE(demo)
+{
+ boost::python::docstring_options doc_options(false);
+ wrap_foos();
+ wrap_bars();
+}
+</pre>Python code:
+ <pre>
+&gt;&gt;&gt; import demo
+&gt;&gt;&gt; print demo.foo1.__doc__
+None
+&gt;&gt;&gt; print demo.foo2.__doc__
+None
+&gt;&gt;&gt; print demo.bar1.__doc__
+bar1 doc
+&gt;&gt;&gt; print demo.bar2.__doc__
+bar2 doc
+</pre>
+
+ <h4>See also: <code>boost/libs/python/test/docstring.cpp</code>
+ and <code>docstring.py</code></h4>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 16 January, 2006
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/ralf_w_grosse_kunstleve.htm">Ralf W.
+ Grosse-Kunstleve</a> 2006.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/enum.html b/libs/python/doc/v2/enum.html
new file mode 100644
index 000000000..c5ec2b921
--- /dev/null
+++ b/libs/python/doc/v2/enum.html
@@ -0,0 +1,234 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/enum.hpp&gt;</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/enum.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#enum_-spec">Class template
+ <code>enum_</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#enum_-spec-synopsis">Class template <code>enum_</code>
+ synopsis</a></dt>
+
+ <dt><a href="#enum_-spec-ctors">Class template <code>enum_</code>
+ constructors</a></dt>
+
+ <dt><a href="#enum_-spec-modifiers">Class template <code>enum_</code>
+ modifier functions</a></dt>
+ </dl>
+ </dd>
+
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/enum.hpp&gt;</code> defines the
+ interface through which users expose their C++ enumeration types
+ to Python. It declares the
+ <code>enum_</code> class template, which is parameterized on the
+ enumeration type being exposed. </p>
+
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="enum_-spec"></a>Class template
+ <code>enum_&lt;T&gt;</code></h3>
+
+ <p>Creates a Python class derived from Python's <code>int</code>
+ type which is associated with the C++ type passed as its first
+ parameter.
+
+ <h4><a name="enum_-spec-synopsis"></a>Class template <code>enum_</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T&gt;
+ class enum_ : public <a href="object.html#object-spec">object</a>
+ {
+ enum_(char const* name, char const* doc = 0);
+ enum_&lt;T&gt;&amp; value(char const* name, T);
+ enum_&lt;T&gt;&amp; export_values();
+ };
+}}
+</pre>
+
+ <h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
+ constructors</h4>
+<pre>
+enum_(char const* name, char const* doc=0);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>.
+
+ <dt><b>Effects:</b> Constructs an <code>enum_</code> object
+ holding a Python extension type derived from <code>int</code>
+ which is named <code>name</code>. The
+ <code>name</code>d attribute of the <a href=
+ "scope.html#introduction">current scope</a> is bound to the new
+ extension type.</dt>
+ </dl>
+
+ <h4><a name="enum_-spec-modifiers"></a>Class template
+ <code>enum_</code> modifier functions</h4>
+<pre>
+inline enum_&lt;T&gt;&amp; value(char const* name, T x);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a> which conforms to Python's <a
+ href=
+ "http://www.python.org/doc/current/ref/identifiers.html">identifier
+ naming rules</a>.
+
+ <dt><b>Effects:</b> adds an instance of the wrapped enumeration
+ type with value <code>x</code> to the type's dictionary as the
+ <code>name</code>d attribute.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ </dl>
+
+<pre>
+inline enum_&lt;T&gt;&amp; export_values();
+</pre>
+
+ <dl class="function-semantics">
+
+ <dt><b>Effects:</b> sets attributes in the current <a
+ href="scope.html#scope-spec"><code>scope</code></a> with the
+ same names and values as all enumeration values exposed so far
+ by calling <code>value()</code>.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code></dt>
+
+ </dl>
+
+ <h2><a name="examples"></a>Example(s)</h2>
+
+ <p>C++ module definition
+<pre>
+#include &lt;boost/python/enum.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+
+using namespace boost::python;
+
+enum color { red = 1, green = 2, blue = 4 };
+
+color identity_(color x) { return x; }
+
+BOOST_PYTHON_MODULE(enums)
+{
+ enum_&lt;color&gt;(&quot;color&quot;)
+ .value(&quot;red&quot;, red)
+ .value(&quot;green&quot;, green)
+ .export_values()
+ .value(&quot;blue&quot;, blue)
+ ;
+
+ def(&quot;identity&quot;, identity_);
+}
+</pre>
+ <p>Interactive Python:
+<pre>
+&gt;&gt;&gt; from enums import *
+
+&gt;&gt;&gt; identity(red)
+enums.color.red
+
+&gt;&gt;&gt; identity(color.red)
+enums.color.red
+
+&gt;&gt;&gt; identity(green)
+enums.color.green
+
+&gt;&gt;&gt; identity(color.green)
+enums.color.green
+
+&gt;&gt;&gt; identity(blue)
+Traceback (most recent call last):
+ File &quot;&lt;stdin&gt;&quot;, line 1, in ?
+NameError: name blue' is not defined
+
+&gt;&gt;&gt; identity(color.blue)
+enums.color.blue
+
+&gt;&gt;&gt; identity(color(1))
+enums.color.red
+
+&gt;&gt;&gt; identity(color(2))
+enums.color.green
+
+&gt;&gt;&gt; identity(color(3))
+enums.color(3)
+
+&gt;&gt;&gt; identity(color(4))
+enums.color.blue
+
+&gt;&gt;&gt; identity(1)
+Traceback (most recent call last):
+ File &quot;&lt;stdin&gt;&quot;, line 1, in ?
+TypeError: bad argument type for built-in operation
+</pre>
+ <hr>
+
+ Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 December, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/errors.html b/libs/python/doc/v2/errors.html
new file mode 100644
index 000000000..69a3cf570
--- /dev/null
+++ b/libs/python/doc/v2/errors.html
@@ -0,0 +1,289 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/errors.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/errors.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#error_already_set-spec">Class
+ <code>error_already_set</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#error_already_set-spec-synopsis">Class
+ <code>error_already_set</code> synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#handle_exception-spec">handle_exception</a></dt>
+
+ <dt><a href="#expect_non_null-spec">expect_non_null</a></dt>
+
+ <dt><a href=
+ "#throw_error_already_set-spec">throw_error_already_set</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/errors.hpp&gt;</code> 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.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="error_already_set-spec"></a>Class
+ <code>error_already_set</code></h3>
+
+ <p><code>error_already_set</code> is an exception type which can be
+ thrown to indicate that a Python error has occurred. If thrown, the
+ precondition is that <a href=
+ "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred()</a>
+ returns a value convertible to <code>true</code>. Portable code shouldn't
+ throw this exception type directly, but should instead use <code><a href=
+ "#throw_error_already_set-spec">throw_error_already_set</a>()</code>,
+ below.</p>
+
+ <h4><a name="error_already_set-spec-synopsis"></a>Class error_already_set
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class error_already_set {};
+}}
+</pre>
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name=
+"handle_exception-spec">template &lt;class T&gt; bool handle_exception</a>(T f) throw();
+
+void handle_exception() throw();
+</pre>
+
+ <dl class="handle_exception-semantics">
+ <dt><b>Requires:</b> The first form requires that the expression
+ <code><a href=
+ "../../../../doc/html/functionN.html">function0</a>&lt;void&gt;(f)</code>
+ is valid. The second form requires that a C++ exception is currently
+ being handled (see section 15.1 in the C++ standard).</dt>
+
+ <dt><b>Effects:</b> The first form calls <code>f()</code> inside a
+ <code>try</code> block which first attempts to use all registered <a
+ href="exception_translator.html">exception translators</a>. If none of
+ those translates the exception, the <code>catch</code> clauses then set
+ an appropriate Python exception for the C++ exception caught, returning
+ <code>true</code> if an exception was thrown, <code>false</code>
+ otherwise. The second form passes a function which rethrows the
+ exception currently being handled to the first form.</dt>
+
+ <dt><b>Postconditions:</b> No exception is being handled</dt>
+
+ <dt><b>Throws:</b> nothing</dt>
+
+ <dt><b>Rationale:</b> At inter-language boundaries it is important to
+ ensure that no C++ exceptions escape, since the calling language
+ usually doesn't have the equipment necessary to properly unwind the
+ stack. Use <code>handle_exception</code> 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: <code><a href=
+ "make_function.html#make_function-spec">make_function</a>()</code>,
+ <code><a href=
+ "make_function.html#make_constructor-spec">make_constructor</a>()</code>,
+ <code><a href="def.html#class_-spec-modifiers">def</a>()</code> and <code><a href=
+ "class.html#def-spec">class_::def</a>()</code>. The second form can be
+ more convenient to use (see the <a href="#examples">example</a> below),
+ but various compilers have problems when exceptions are rethrown from
+ within an enclosing <code>try</code> block.</dt>
+ </dl>
+<pre>
+<a name=
+"expect_non_null-spec">template &lt;class T&gt; T* expect_non_null(T* x);</a>
+</pre>
+
+ <dl class="expect_non_null-semantics">
+ <dt><b>Returns:</b> <code>x</code></dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "#error_already_set-spec">error_already_set</a>()</code> iff <code>x ==
+ 0</code>.</dt>
+
+ <dt><b>Rationale:</b> Simplifies error-handling when calling functions
+ in the <a href="http://www.python.org/doc/2.2/api/api.html">Python/C
+ API</a> which return 0 on error.</dt>
+ </dl>
+<pre>
+<a name="throw_error_already_set-spec">void throw_error_already_set();</a>
+</pre>
+
+ <dl class="throw_error_already_set-semantics">
+ <dt><b>Effects:</b> <code>throw&nbsp;<a href=
+ "#error_already_set-spec">error_already_set</a>();</code></dt>
+ </dl>
+
+ <dl>
+ <dt><b>Rationale:</b> 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 <code>catch</code> block in <code><a href=
+ "#handle_exception-spec">handle_exception</a>()</code> can catch the
+ exception.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Examples</h2>
+<pre>
+#include &lt;string&gt;
+#include &lt;boost/python/errors.hpp&gt;
+#include &lt;boost/python/object.hpp&gt;
+#include &lt;boost/python/handle.hpp&gt;
+
+// 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*&amp; 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&lt;&gt;(
+ 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&lt;char*&gt;("OO"), &amp;a1, &amp;a2))
+ return 0;
+
+ // Use boost::bind to make an object compatible with
+ // boost::Function0&lt;void&gt;
+ if (boost::python::handle_exception(
+ boost::bind&lt;void&gt;(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&lt;char*&gt;("OO"), &amp;a1, &amp;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;
+ }
+}
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/exception_translator.html b/libs/python/doc/v2/exception_translator.html
new file mode 100644
index 000000000..4cc7bb91b
--- /dev/null
+++ b/libs/python/doc/v2/exception_translator.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/exception_translator.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/exception_translator.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href=
+ "#register_exception_translator-spec">register_exception_translator</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>As described <a href="errors.html#handle_exception-spec">here</a>, 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 <a href=
+ "http://www.python.org/doc/current/lib/module-exceptions.html">RuntimeError</a>
+ exception whose representation is
+ <code>'Unidentifiable&nbsp;C++&nbsp;Exception'</code>. To produce better
+ error messages, users can register additional exception translators as
+ described below.</p>
+
+ <h2><a name="functions"></a>Functions</h2>
+
+<h3><code><a name="register_exception_translator-spec">register_exception_translator</a></code></h3>
+
+<pre>
+<a name="register_exception_translator-spec">template&lt;class ExceptionType, class Translate&gt;</a>
+void register_exception_translator(Translate translate);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b></dt>
+
+ <dd>
+ <code>Translate</code> is <a href=
+ "../../../utility/CopyConstructible.html">Copyconstructible</a>, and
+ the following code must be well-formed:
+<pre>
+void f(ExceptionType x) { translate(x); }
+</pre>
+ The expression <code>translate(x)</code> must either throw a C++
+ exception, or a subsequent call to <code><a href=
+ "http://www.python.org/doc/current/api/exceptionHandling.html">PyErr_Occurred</a>()</code>
+ must return 1.
+ </dd>
+
+ <p>
+
+ <dt><b>Effects:</b> Adds a copy of <code>translate</code> 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).</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/exception_translator.hpp&gt;
+#include &lt;exception&gt;
+
+struct my_exception : std::exception
+{
+ char const* what() throw() { return "One of my exceptions"; }
+};
+
+void translate(my_exception const&amp; 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&lt;my_exception&gt;(&amp;translate);
+
+ def("something_which_throws", something_which_throws);
+}
+</pre>
+ <br>
+ <br>
+
+ <hr>
+
+ <p>Revised 03 October, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/exec.html b/libs/python/doc/v2/exec.html
new file mode 100644
index 000000000..83d2c9b89
--- /dev/null
+++ b/libs/python/doc/v2/exec.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/exec.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/exec.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#eval-spec"><code>eval</code></a></dt>
+ <dt><a href="#exec-spec"><code>exec</code></a></dt>
+ <dt><a href="#exec_file-spec"><code>exec_file</code></a></dt>
+ </dl>
+ </dd>
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a mechanism for embedding the python interpreter into C++ code.</p>
+
+ <h2><a name="functions"></a>Functions</h2>
+
+ <h3><a name="eval-spec"></a><code>eval</code></h3>
+ <pre>
+object eval(str expression,
+ object globals = object(),
+ object locals = object());
+ </pre>
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Evaluate Python expression from <code>expression</code> in the context
+ specified by the dictionaries <code>globals</code> and <code>locals</code>.
+ </dt>
+ <dt><b>Returns:</b>
+ An instance of <a href="object.html#object-spec">object</a>
+ which holds the value of the expression.
+ </dt>
+ </dl>
+
+ <h3><a name="exec-spec"></a><code>exec</code></h3>
+ <pre>
+object exec(str code,
+ object globals = object(),
+ object locals = object());
+ </pre>
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Execute Python source code from <code>code</code> in the context
+ specified by the dictionaries <code>globals</code> and <code>locals</code>.
+ </dt>
+ <dt><b>Returns:</b>
+ An instance of <a href="object.html#object-spec">object</a>
+ which holds the result of executing the code.
+ </dt>
+ </dl>
+
+ <h3><a name="exec_file-spec"></a><code>exec_file</code></h3>
+ <pre>
+object exec_file(str filename,
+ object globals = object(),
+ object locals = object());
+ </pre>
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Execute Python source code from the file named by <code>filename</code>
+ in the context specified by the dictionaries <code>globals</code> and
+ <code>locals</code>.
+ </dt>
+ <dt><b>Returns:</b>
+ An instance of <a href="object.html#object-spec">object</a>
+ which holds the result of executing the code.
+ </dt>
+ </dl>
+
+ <h2><a name="examples"></a>Examples</h2>
+
+ <para>The following example demonstrates the use of <function>import</function>
+ and <function>exec</function> to define a function in python, and later call
+ it from within C++.</para>
+
+<pre>
+#include &lt;iostream&gt;
+#include &lt;string&gt;
+
+using namespace boost::python;
+
+void greet()
+{
+ // Retrieve the main module.
+ object main = import("__main__");
+
+ // Retrieve the main module's namespace
+ object global(main.attr("__dict__"));
+
+ // Define greet function in Python.
+ object result = exec(
+ "def greet(): \n"
+ " return 'Hello from Python!' \n",
+ global, global);
+
+ // Create a reference to it.
+ object greet = global["greet"];
+
+ // Call it.
+ std::string message = extract&lt;std::string&gt;(greet());
+ std::cout &lt;&lt; message &lt;&lt; std::endl;
+}
+</pre>
+
+ <para>Instead of embedding the python script into a string,
+ we could also store it in an a file...</para>
+
+<pre>
+def greet():
+ return 'Hello from Python!'
+</pre>
+ <para>... and execute that instead.</para>
+<pre>
+ // ...
+ // Load the greet function from a file.
+ object result = exec_file(script, global, global);
+ // ...
+}
+</pre>
+ <p>Revised 01 November, 2005</p>
+
+ <p><i>&copy; Copyright Stefan Seefeld 2005.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/extract.html b/libs/python/doc/v2/extract.html
new file mode 100644
index 000000000..3c6b77f2f
--- /dev/null
+++ b/libs/python/doc/v2/extract.html
@@ -0,0 +1,232 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/extract.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/extract.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#extract-spec">Class <code>extract</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#extract-spec-synopsis">Class <code>extract</code>
+ synopsis</a></dt>
+
+ <dt><a href="#extract-spec-ctors">Class <code>extract</code>
+ constructors and destructor</a></dt>
+
+ <dt><a href="#extract-spec-observers">Class
+ <code>extract</code> observer functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a mechanism for extracting C++ object values from
+ generalized Python objects. Note that
+ <code>extract&lt;</code>...<code>&gt;</code> can also be used to
+ &quot;downcast&quot; an <a
+ href="object.html#object-spec">object</a> to some specific <a
+ href="ObjectWrapper.html#ObjectWrapper-concept">ObjectWrapper</a>. Because
+ invoking a mutable python type with an argument of the same type
+ (e.g. <code>list([1,2])</code> typically makes a <em>copy</em> of
+ the argument object, this may be the only way to access the <a
+ href="ObjectWrapper.html#ObjectWrapper-concept">ObjectWrapper</a>'s
+ interface on the original object.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="extract-spec"></a>Class template <code>extract</code></h3>
+
+ <p><code>extract&lt;T&gt;</code> can be used to extract a value of
+ an arbitrary C++ type from an instance of <code><a
+ href="object.html#object-spec">object</a></code>. Two usages are supported:
+<ol>
+<li><b><code>extract&lt;T&gt;(o)</code></b> is a temporary object
+which is implicitly convertible to <code>T</code> (explicit conversion
+is also available through the object's function-call
+operator). However, if no conversion is available which can convert
+<code>o</code> to an object of type <code>T</code>, a Python
+<code>TypeError</code> exception will be <a
+href="definitions.html#raise">raised</a>.
+
+<li><b><code>extract&lt;T&gt; x(o);</code></b> constructs an extractor
+whose <code>check()</code> member function can be used to ask whether
+a conversion is available without causing an exception to be thrown.
+</ol>
+
+ <h4><a name="extract-spec-synopsis"></a>Class template <code>extract</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T&gt;
+ struct extract
+ {
+ typedef <i>unspecified</i> result_type;
+
+ extract(PyObject*);
+ extract(object const&amp;);
+
+ result_type operator()() const;
+ operator result_type() const;
+
+ bool check() const;
+ };
+}}
+</pre>
+
+ <h4><a name="extract-spec-ctors"></a>Class <code>extract</code>
+ constructors and destructor</h4>
+<pre>
+extract(PyObject* p);
+extract(object const&amp;);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> The first form requires that <code>p</code> is non-null.</dt>
+
+ <dt><b>Effects:</b>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.</dt>
+ </dl>
+
+ <h4><a name="extract-spec-observers"></a>Class <code>extract</code>
+ observer functions</h4>
+<pre>
+result_type operator()() const;
+operator result_type() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Converts the stored pointer to
+ <code>result_type</code>, which is either <code>T</code> or
+ <code>T const&amp;</code>.
+ </dt>
+
+ <dt><b>Returns:</b> An object of <code>result_type</code>
+ corresponding to the one referenced by the stored pointer.</dt>
+
+ <dt><b>Throws:</b> <code><a
+ href="errors.html#error_already_set-spec">error_already_set</a></code>
+ and sets a <code>TypeError</code> if no such conversion is
+ available. May also emit other unspecified exceptions thrown by
+ the converter which is actually used.</dt>
+ </dl>
+
+<pre>
+bool check() const;
+</pre>
+
+ <dl class="function-semantics">
+
+ <dt><b>Postconditions:</b> None. In particular, note that a
+ return value of <code>true</code> does not preclude an exception
+ being thrown from <code>operator result_type()</code> or
+ <code>operator()()</code>.</dt>
+
+ <dt><b>Returns:</b> <code>false</code> <i>only</i> if no conversion from the
+ stored pointer to <code>T</code> is available.</dt>
+
+ </dl>
+
+
+ <h2><a name="examples"></a>Examples</h2>
+
+<pre>
+#include &lt;cstdio&gt;
+using namespace boost::python;
+int Print(str s)
+{
+ // extract a C string from the Python string object
+ char const* c_str = extract&lt;char const*&gt;(s);
+
+ // Print it using printf
+ std::printf(&quot;%s\n&quot;, c_str);
+
+ // Get the Python string's length and convert it to an int
+ return extract&lt;int&gt;(s.attr(&quot;__len__&quot;)())
+}
+</pre>
+
+The following example shows how extract can be used along with
+<code><a
+href="class.html#class_-spec">class_</a>&lt;</code>...<code>&gt;</code>
+to create and access an instance of a wrapped C++ class.
+
+<pre>
+struct X
+{
+ X(int x) : v(x) {}
+ int value() { return v; }
+ private:
+ int v;
+};
+
+BOOST_PYTHON_MODULE(extract_ext)
+{
+ object x_class(
+ class_&lt;X&gt;(&quot;X&quot;, init&lt;int&gt;())
+ .def(&quot;value&quot;, &amp;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&amp; x = extract&lt;X&amp;&gt;(x_obj);
+ assert(x.value() == 3);
+}
+</pre>
+ <p>Revised 15 November, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/faq.html b/libs/python/doc/v2/faq.html
new file mode 100644
index 000000000..75283d77c
--- /dev/null
+++ b/libs/python/doc/v2/faq.html
@@ -0,0 +1,861 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - FAQ</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Frequently Asked Questions (FAQs)</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <dl class="page-index">
+
+ <dt><a href="#funcptr">How can I wrap a function which takes a
+ function pointer as an argument?</a><dd>
+
+ <dt><a href="#dangling">I'm getting the "attempt to return dangling
+ reference" error. What am I doing wrong?</a></dt>
+
+ <dt><a href="#question1">Is return_internal_reference
+ efficient?</a></dt>
+
+ <dt><a href="#question2">How can I wrap functions which take C++
+ containers as arguments?</a></dt>
+
+ <dt><a href="#c1204">fatal error C1204:Compiler limit:internal
+ structure overflow</a></dt>
+
+ <dt><a href="#debugging">How do I debug my Python extensions?</a></dt>
+
+ <dt><a href="#imul">Why doesn't my <code>*=</code> operator
+ work?</a></dt>
+
+ <dt><a href="#macosx">Does Boost.Python work with Mac OS X?</a></dt>
+
+ <dt><a href="#xref">How can I find the existing PyObject that holds a
+ C++ object?</a></dt>
+
+ <dt><a href="#ownership">How can I wrap a function which needs to take
+ ownership of a raw pointer?</a></dt>
+
+ <dt><a href="#slow_compilation">Compilation takes too much time and eats too much memory!
+ What can I do to make it faster?</a></dt>
+
+ <dt><a href="#packages">How do I create sub-packages using Boost.Python?</a></dt>
+
+ <dt><a href="#msvcthrowbug"
+ >error C2064: term does not evaluate to a function taking 2 arguments</a>
+ </dt>
+
+ <dt><a href="#custom_string"
+ >How can I automatically convert my custom string type to
+ and from a Python string?</a></dt>
+
+ <dt><a href="#topythonconversionfailed">Why is my automatic to-python conversion not being
+ found?</a></dt>
+
+ <dt><a href="#threadsupport">Is Boost.Python thread-aware/compatible with multiple interpreters?</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="funcptr">How can I wrap a function which takes a
+ function pointer as an argument?</a></h2>
+
+ If what you're trying to do is something like this:
+<pre>
+typedef boost::function&lt;void (string s) &gt; funcptr;
+
+void foo(funcptr fp)
+{
+ fp(&quot;hello,world!&quot;);
+}
+
+BOOST_PYTHON_MODULE(test)
+{
+ def(&quot;foo&quot;,foo) ;
+}
+</pre>
+
+And then:
+
+<pre>
+&gt;&gt;&gt; def hello(s):
+... print s
+...
+&gt;&gt;&gt; foo(hello)
+hello, world!
+</pre>
+
+ The short answer is: &quot;you can't&quot;. 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 <code>foo</code>. In other words, this could work if the C++
+ function is always going to invoke the <em>same</em> Python
+ function, but you probably don't want that.
+
+ <p>If you have the luxury of changing the C++ code you're
+ wrapping, pass it an <code>object</code> instead and call that;
+ the overloaded function call operator will invoke the Python
+ function you pass it behind the <code>object</code>.
+
+ <p>For more perspective on the issue, see <a
+ href="http://aspn.activestate.com/ASPN/Mail/Message/1554837">this
+ posting</a>.
+
+ <hr>
+
+ <h2><a name="dangling">I'm getting the "attempt to return dangling
+ reference" error. What am I doing wrong?</a></h2>
+ That exception is protecting you from causing a nasty crash. It usually
+ happens in response to some code like this:
+<pre>
+period const&amp; get_floating_frequency() const
+{
+ return boost::python::call_method&lt;period const&amp;&gt;(
+ m_self,"get_floating_frequency");
+}
+</pre>
+ And you get:
+<pre>
+ReferenceError: Attempt to return dangling reference to object of type:
+class period
+</pre>
+
+ <p>In this case, the Python method invoked by <code>call_method</code>
+ constructs a new Python object. You're trying to return a reference to a
+ C++ object (an instance of <code>class period</code>) 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
+ <code>get_floating_frequency()</code> above. When the function returns,
+ the Python object will be destroyed, destroying the instance of
+ <code>class period</code>, 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.<br>
+ &nbsp;</p>
+ <hr>
+
+ <h2><a name="question1"></a>Is return_internal_reference efficient?</h2>
+
+ <blockquote>
+ <b>Q:</b> <i>I have an object composed of 12 doubles. A const&amp; 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?</i>
+
+ <p><b>A:</b> 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.</p>
+ </blockquote>
+ <hr>
+
+ <h2><a name="question2"></a>How can I wrap functions which take C++
+ containers as arguments?</h2>
+
+ <p>Ralf W. Grosse-Kunstleve provides these notes:</p>
+
+ <ol>
+ <li>
+ Using the regular <code>class_&lt;&gt;</code> wrapper:
+<pre>
+class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
+ .def(...)
+ ...
+ ;
+</pre>
+ 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
+
+ <blockquote>
+ scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h
+ </blockquote>
+ in the "scitbx" package. The file could easily be modified for
+ wrapping std::vector&lt;&gt; instantiations.
+
+ <p>This type of C++/Python binding is most suitable for containers
+ that may contain a large number of elements (&gt;10000).</p>
+ </li>
+
+ <li>
+ Using custom rvalue converters. Boost.Python "rvalue converters"
+ match function signatures such as:
+<pre>
+void foo(std::vector&lt;double&gt; const&amp; array); // pass by const-reference
+void foo(std::vector&lt;double&gt; array); // pass by value
+</pre>
+ Some custom rvalue converters are implemented in the file
+
+ <blockquote>
+ scitbx/include/scitbx/boost_python/container_conversions.h
+ </blockquote>
+ This code can be used to convert from C++ container types such as
+ std::vector&lt;&gt; or std::list&lt;&gt; to Python tuples and vice
+ versa. A few simple examples can be found in the file
+
+ <blockquote>
+ scitbx/array_family/boost_python/regression_test_module.cpp
+ </blockquote>
+ Automatic C++ container &lt;-&gt; Python tuple conversions are most
+ suitable for containers of moderate size. These converters generate
+ significantly less object code compared to alternative 1 above.
+ </li>
+ </ol>
+ 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]
+
+ <p>It would also be useful to also have "custom lvalue converters" such
+ as std::vector&lt;&gt; &lt;-&gt; Python list. These converters would
+ support the modification of the Python list from C++. For example:</p>
+
+ <p>C++:</p>
+<pre>
+void foo(std::vector&lt;double&gt;&amp; array)
+{
+ for(std::size_t i=0;i&lt;array.size();i++) {
+ array[i] *= 2;
+ }
+}
+</pre>
+ Python:
+<pre>
+&gt;&gt;&gt; l = [1, 2, 3]
+&gt;&gt;&gt; foo(l)
+&gt;&gt;&gt; print l
+[2, 4, 6]
+</pre>
+ Custom lvalue converters require changes to the Boost.Python core library
+ and are currently not available.
+
+ <p>P.S.:</p>
+
+ <p>The "scitbx" files referenced above are available via anonymous
+ CVS:</p>
+<pre>
+cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
+cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
+</pre>
+ <hr>
+
+ <h2><a name="c1204"></a>fatal error C1204:Compiler limit:internal
+ structure overflow</h2>
+
+ <blockquote>
+ <b>Q:</b> <i>I get this error message when compiling a large source
+ file. What can I do?</i>
+
+ <p><b>A:</b> You have two choices:</p>
+
+ <ol>
+ <li>Upgrade your compiler (preferred)</li>
+
+ <li>
+ Break your source file up into multiple translation units.
+
+ <p><code><b>my_module.cpp</b></code>:</p>
+<pre>
+...
+void more_of_my_module();
+BOOST_PYTHON_MODULE(my_module)
+{
+ def("foo", foo);
+ def("bar", bar);
+ ...
+ more_of_my_module();
+}
+</pre>
+ <code><b>more_of_my_module.cpp</b></code>:
+<pre>
+void more_of_my_module()
+{
+ def("baz", baz);
+ ...
+}
+</pre>
+ If you find that a <code><a href=
+ "class.html#class_-spec">class_</a>&lt;...&gt;</code> declaration
+ can't fit in a single source file without triggering the error, you
+ can always pass a reference to the <code>class_</code> object to a
+ function in another source file, and call some of its member
+ functions (e.g. <code>.def(...)</code>) in the auxilliary source
+ file:
+
+ <p><code><b>more_of_my_class.cpp</b></code>:</p>
+<pre>
+void more_of_my_class(class&lt;my_class&gt;&amp; x)
+{
+ x
+ .def("baz", baz)
+ .add_property("xx", &amp;my_class::get_xx, &amp;my_class::set_xx)
+ ;
+
+ ...
+}
+</pre>
+ </li>
+ </ol>
+ </blockquote>
+ <hr>
+
+ <h2><a name="debugging"></a>How do I debug my Python extensions?</h2>
+
+ <p>Greg Burley gives the following answer for Unix GCC users:</p>
+
+ <blockquote>
+ 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 ;-).
+
+ <p>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.</p>
+<pre>
+(gdb) target exec python
+(gdb) run
+ &gt;&gt;&gt; from my_ext import *
+ &gt;&gt;&gt; [C-c]
+(gdb) break MyClass::MyBuggyFunction
+(gdb) cont
+ &gt;&gt;&gt; pyobj = MyClass()
+ &gt;&gt;&gt; pyobj.MyBuggyFunction()
+Breakpoint 1, MyClass::MyBuggyFunction ...
+Current language: auto; currently c++
+(gdb) do debugging stuff
+</pre>
+ </blockquote>
+
+ <p>Greg's approach works even better using Emacs' "<code>gdb</code>"
+ command, since it will show you each line of source as you step through
+ it.</p>
+
+ <p>On <b>Windows</b>, 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.</p>
+
+ <p>Raoul Gough has provided the following for gdb on Windows:</p>
+
+ <blockquote>
+
+ <p>gdb support for Windows DLLs has improved lately, so it is
+ now possible to debug Python extensions using a few
+ tricks. Firstly, you will need an up-to-date gdb with support
+ for minimal symbol extraction from a DLL. Any gdb from version 6
+ onwards, or Cygwin gdb-20030214-1 and onwards should do. A
+ suitable release will have a section in the gdb.info file under
+ Configuration &ndash; Native &ndash; Cygwin Native &ndash;
+ Non-debug DLL symbols. Refer to that info section for more
+ details of the procedures outlined here.</p>
+
+ <p>Secondly, it seems necessary to set a breakpoint in the
+ Python interpreter, rather than using ^C to break execution. A
+ good place to set this breakpoint is PyOS_Readline, which will
+ stop execution immediately before reading each interactive
+ Python command. You have to let Python start once under the
+ debugger, so that it loads its own DLL, before you can set the
+ breakpoint:</p>
+
+<p>
+<pre>
+$ gdb python
+GNU gdb 2003-09-02-cvs (cygwin-special)
+[...]
+
+(gdb) run
+Starting program: /cygdrive/c/Python22/python.exe
+Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
+Type "help", "copyright", "credits" or "license" for more information.
+&gt;&gt;&gt; ^Z
+
+
+Program exited normally.
+(gdb) break *&amp;PyOS_Readline
+Breakpoint 1 at 0x1e04eff0
+(gdb) run
+Starting program: /cygdrive/c/Python22/python.exe
+Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
+Type "help", "copyright", "credits" or "license" for more information.
+
+Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
+ from /cygdrive/c/WINNT/system32/python22.dll
+(gdb) cont
+Continuing.
+&gt;&gt;&gt; from my_ext import *
+
+Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
+ from /cygdrive/c/WINNT/system32/python22.dll
+(gdb) # my_ext now loaded (with any debugging symbols it contains)
+</pre>
+ </blockquote>
+
+ <h3>Debugging extensions through Boost.Build</h3>
+ If you are launching your extension module tests with <a href=
+ "../../../../tools/build/v1/build_system.htm">Boost.Build</a> using the
+ <code>boost-python-runtest</code> rule, you can ask it to launch your
+ debugger for you by adding "--debugger=<i>debugger</i>" to your bjam
+ command-line:
+<pre>
+bjam -sTOOLS=vc7.1 "--debugger=devenv /debugexe" test
+bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
+</pre>
+ It can also be extremely useful to add the <code>-d+2</code> 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.
+ <hr>
+
+ <h2><a name="imul"></a>Why doesn't my <code>*=</code> operator work?</h2>
+
+ <blockquote>
+ <b>Q:</b> <i>I have exported my class to python, with many overloaded
+ operators. it works fine for me except the</i> <code>*=</code>
+ <i>operator. It always tells me "can't multiply sequence with non int
+ type". If I use</i> <code>p1.__imul__(p2)</code> <i>instead of</i>
+ <code>p1 *= p2</code><i>, it successfully executes my code. What's
+ wrong with me?</i>
+
+ <p><b>A:</b> 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).</p>
+<pre>
+&gt;&gt;&gt; class X(object):
+... def __imul__(self, x):
+... print 'imul'
+...
+&gt;&gt;&gt; x = X()
+&gt;&gt;&gt; x *= 1
+</pre>
+ To cure this problem, all you need to do is upgrade your Python to
+ version 2.2.1 or later.
+ </blockquote>
+ <hr>
+
+ <h2><a name="macosx"></a>Does Boost.Python work with Mac OS X?</h2>
+
+ It is known to work under 10.2.8 and 10.3 using
+ Apple's gcc 3.3 compiler:
+ <pre>gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1493)</pre>
+ Under 10.2.8 get the August 2003 gcc update (free at
+ <a href="http://connect.apple.com/">http://connect.apple.com/</a>).
+ Under 10.3 get the Xcode Tools v1.0 (also free).
+ <p>
+ Python 2.3 is required. The Python that ships with 10.3 is
+ fine. Under 10.2.8 use these commands to install Python
+ as a framework:
+ <pre>./configure --enable-framework
+make
+make frameworkinstall</pre>
+ The last command requires root privileges because the target
+ directory is
+ <tt>/Library/Frameworks/Python.framework/Versions/2.3</tt>.
+ However, the installation does not interfere with the Python
+ version that ships with 10.2.8.
+ <p>
+ It is also crucial to increase the <tt>stacksize</tt> before
+ starting compilations, e.g.:
+ <pre>limit stacksize 8192k</pre>
+ If the <tt>stacksize</tt> is too small the build might crash with
+ internal compiler errors.
+ <p>
+ Sometimes Apple's compiler exhibits a bug by printing an error
+ like the following while compiling a
+ <tt>boost::python::class_&lt;your_type&gt;</tt>
+ template instantiation:
+ <pre>.../inheritance.hpp:44: error: cannot
+ dynamic_cast `p' (of type `struct cctbx::boost_python::&lt;unnamed&gt;::add_pair*
+ ') to type `void*' (source type is not polymorphic)</pre>
+
+ We do not know a general workaround, but if the definition of
+ <tt>your_type</tt> can be modified the following was found
+ to work in all cases encountered so far:<pre>struct your_type
+{
+ // before defining any member data
+#if defined(__MACH__) &amp;&amp; defined(__APPLE_CC__) &amp;&amp; __APPLE_CC__ == 1493
+ bool dummy_;
+#endif
+ // now your member data, e.g.
+ double x;
+ int j;
+ // etc.
+};</pre>
+
+ <hr>
+ <h2><a name="xref">How can I find the existing PyObject that holds a C++
+ object?</a></h2>
+
+ <blockquote>
+ "I am wrapping a function that always returns a pointer to an
+ already-held C++ object."
+ </blockquote>
+ 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:
+<pre>
+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&lt;&gt; f_wrap()
+{
+ X_wrap* xw = dynamic_cast&lt;X_wrap*&gt;(f());
+ assert(xw != 0);
+ return handle&lt;&gt;(borrowed(xw-&gt;self));
+}
+
+...
+
+def("f", f_wrap());
+class_&lt;X,X_wrap,boost::noncopyable&gt;("X", init&lt;int&gt;())
+ ...
+ ;
+</pre>
+ Of course, if X has no virtual functions you'll have to use
+ <code>static_cast</code> instead of <code>dynamic_cast</code> with no
+ runtime check that it's valid. This approach also only works if the
+ <code>X</code> object was constructed from Python, because
+ <code>X</code>s constructed from C++ are of course never
+ <code>X_wrap</code> objects.
+
+ <p>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 <code>shared_ptr&lt;X&gt;</code> is
+ converted from Python, the shared_ptr actually manages a reference to the
+ containing Python object. When a shared_ptr&lt;X&gt; 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 <code>object(p)</code> 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.</p>
+
+ <p>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.</p>
+
+ <hr>
+
+ <h2><a name="ownership">How can I wrap a function which needs to take
+ ownership of a raw pointer?</a></h2>
+
+ <blockquote>
+ <i>Part of an API that I'm wrapping goes something like this:</i>
+<pre>
+struct A {}; struct B { void add( A* ); }
+where B::add() takes ownership of the pointer passed to it.
+</pre>
+
+ <p><i>However:</i></p>
+<pre>
+a = mod.A()
+b = mod.B()
+b.add( a )
+del a
+del b
+# python interpreter crashes
+# later due to memory corruption.
+</pre>
+
+ <p><i>Even binding the lifetime of a</i> 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?</p>
+
+ <p><i>--Bruce Lowery</i></p>
+ </blockquote>
+ Yes: Make sure the C++ object is held by auto_ptr:
+<pre>
+class_&lt;A, std::auto_ptr&lt;A&gt; &gt;("A")
+ ...
+ ;
+</pre>
+ Then make a thin wrapper function which takes an auto_ptr parameter:
+<pre>
+void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
+{
+ b.insert(a.get());
+ a.release();
+}
+</pre>
+ Wrap that as B.add. Note that pointers returned via <code><a href=
+ "manage_new_object.html#manage_new_object-spec">manage_new_object</a></code>
+ will also be held by <code>auto_ptr</code>, so this transfer-of-ownership
+ will also work correctly.
+
+ <hr>
+ <h2><a name="slow_compilation">Compilation takes too much time and eats too
+ much memory! What can I do to make it faster?</a></h2>
+ <p>
+ Please refer to the <a href="../tutorial/doc/html/python/techniques.html#python.reducing_compiling_time"
+ >Reducing Compiling Time</a> section in the tutorial.
+ </p>
+
+ <hr>
+ <h2><a name="packages">How do I create sub-packages using Boost.Python?</a></h2>
+ <p>
+ Please refer to the <a href="../tutorial/doc/html/python/techniques.html#python.creating_packages"
+ >Creating Packages</a> section in the tutorial.
+ </p>
+
+ <hr>
+ <h2><a name="msvcthrowbug"></a>error C2064: term does
+ not evaluate to a function taking 2 arguments</h2>
+ <font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
+ If you see Microsoft Visual C++ 7.1 (MS Visual Studio .NET 2003) issue
+ an error message like the following it is most likely due to a bug
+ in the compiler:
+ <pre>boost\boost\python\detail\invoke.hpp(76):
+error C2064: term does not evaluate to a function taking 2 arguments"</pre>
+ This message is triggered by code like the following:
+<pre>#include &lt;boost/python.hpp&gt;
+
+using namespace boost::python;
+
+class FXThread
+{
+public:
+ bool setAutoDelete(bool doso) throw();
+};
+
+void Export_FXThread()
+{
+ class_< FXThread >("FXThread")
+ .def("setAutoDelete", &amp;FXThread::setAutoDelete)
+ ;
+}
+ </pre>
+ The bug is related to the <code>throw()</code> modifier.
+ As a workaround cast off the modifier. E.g.:
+<pre>
+ .def("setAutoDelete", (bool (FXThread::*)(bool)) &amp;FXThread::setAutoDelete)</pre>
+ <p>(The bug has been reported to Microsoft.)</p>
+
+ <hr>
+ <h2><a name="custom_string"></a>How can I automatically
+ convert my custom string type to and from a Python string?</h2>
+ <font size="-1"><i>Ralf W. Grosse-Kunstleve provides these
+ notes:</i></font><p>
+ Below is a small, self-contained demo extension module that shows
+ how to do this. Here is the corresponding trivial test:
+ <pre>import custom_string
+assert custom_string.hello() == "Hello world."
+assert custom_string.size("california") == 10</pre>
+
+ If you look at the code you will find:
+
+ <ul>
+ <li>A custom <tt>to_python</tt> converter (easy):
+ <tt>custom_string_to_python_str</tt>
+
+ <li>A custom lvalue converter (needs more code):
+ <tt>custom_string_from_python_str</tt>
+ </ul>
+
+ The custom converters are registered in the global Boost.Python
+ registry near the top of the module initialization function. Once
+ flow control has passed through the registration code the automatic
+ conversions from and to Python strings will work in any module
+ imported in the same process.
+
+<pre>#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/to_python_converter.hpp&gt;
+
+namespace sandbox { namespace {
+
+ class custom_string
+ {
+ public:
+ custom_string() {}
+ custom_string(std::string const&amp; value) : value_(value) {}
+ std::string const&amp; value() const { return value_; }
+ private:
+ std::string value_;
+ };
+
+ struct custom_string_to_python_str
+ {
+ static PyObject* convert(custom_string const&amp; s)
+ {
+ return boost::python::incref(boost::python::object(s.value()).ptr());
+ }
+ };
+
+ struct custom_string_from_python_str
+ {
+ custom_string_from_python_str()
+ {
+ boost::python::converter::registry::push_back(
+ &amp;convertible,
+ &amp;construct,
+ boost::python::type_id&lt;custom_string&gt;());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ if (!PyString_Check(obj_ptr)) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ const char* value = PyString_AsString(obj_ptr);
+ if (value == 0) boost::python::throw_error_already_set();
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage&lt;custom_string&gt;*)
+ data)-&gt;storage.bytes;
+ new (storage) custom_string(value);
+ data-&gt;convertible = storage;
+ }
+ };
+
+ custom_string hello() { return custom_string(&quot;Hello world.&quot;); }
+
+ std::size_t size(custom_string const&amp; s) { return s.value().size(); }
+
+ void init_module()
+ {
+ using namespace boost::python;
+
+ boost::python::to_python_converter&lt;
+ custom_string,
+ custom_string_to_python_str&gt;();
+
+ custom_string_from_python_str();
+
+ def(&quot;hello&quot;, hello);
+ def(&quot;size&quot;, size);
+ }
+
+}} // namespace sandbox::&lt;anonymous&gt;
+
+BOOST_PYTHON_MODULE(custom_string)
+{
+ sandbox::init_module();
+}</pre>
+
+ <hr>
+ <h2><a name="topythonconversionfailed"></a
+ >Why is my automatic to-python conversion not being found?</h2>
+ <font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
+ If you define custom converters similar to the ones
+ shown above the <tt>def_readonly()</tt> and <tt>def_readwrite()</tt>
+ member functions provided by <tt>boost::python::class_</tt> for
+ direct access to your member data will not work as expected.
+ This is because <tt>def_readonly("bar",&nbsp;&amp;foo::bar)</tt> is
+ equivalent to:
+
+<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()))</pre>
+
+ Similarly, <tt>def_readwrite("bar",&nbsp;&amp;foo::bar)</tt> is
+ equivalent to:
+
+<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()),
+ make_setter(&amp;foo::bar, return_internal_reference())</pre>
+
+ In order to define return value policies compatible with the
+ custom conversions replace <tt>def_readonly()</tt> and
+ <tt>def_readwrite()</tt> by <tt>add_property()</tt>. E.g.:
+
+<pre>.add_property("bar", make_getter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()),
+ make_setter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()))</pre>
+
+ <hr>
+ <h2><a name="threadsupport"></a
+ >Is Boost.Python thread-aware/compatible with multiple interpreters?</h2>
+ <font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
+ The quick answer to this is: no.</p>
+ <p>
+ The longer answer is that it can be patched to be so, but it's
+ complex. You will need to add custom lock/unlock wrapping of every
+ time your code enters Boost.Python (particularly every virtual
+ function override) plus heavily modify
+ <tt>boost/python/detail/invoke.hpp</tt> with custom unlock/lock
+ wrapping of every time Boost.Python enters your code. You must
+ furthermore take care to <i>not</i> unlock/lock when Boost.Python
+ is invoking iterator changes via <tt>invoke.hpp</tt>.</p>
+ <p>
+ There is a patched <tt>invoke.hpp</tt> posted on the C++-SIG
+ mailing list archives and you can find a real implementation of all
+ the machinery necessary to fully implement this in the TnFOX
+ project at <a href="http://sourceforge.net/projects/tnfox/"> this
+ SourceForge project location</a>.</p>
+
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 12 March, 2006
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002-2006.</i></p>
+ </body>
+</html>
diff --git a/libs/python/doc/v2/feb2002.html b/libs/python/doc/v2/feb2002.html
new file mode 100644
index 000000000..5f15aeace
--- /dev/null
+++ b/libs/python/doc/v2/feb2002.html
@@ -0,0 +1,367 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - February 2002 Progress Report</title>
+<style type="text/css">
+ :link { color: #0000ff }
+ :visited { color: #800080 }
+ p.c3 {font-style: italic}
+ h2.c2 {text-align: center}
+ h1.c1 {text-align: center}
+</style>
+
+ <table border="0" cellpadding="7" cellspacing="0" width=
+ "100%" summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 class="c2">February 2002 Progress Report</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="index">
+ <dt><a href="#Python10">Python10 Conference Report</a>
+
+ <dt><a href="#progress">Boost.Python v2 Progress</a>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="#documentation">Documentation</a>
+
+ <dt><a href="#conversion">Overhaul of
+ <code>to_python</code>/<code>from_python</code>
+ conversion mechanism</a>
+
+ <dt><a href="#miscellaneous">Miscellaneous</a>
+ </dl>
+ </dl>
+
+ <h2><a name="Python10">Python10 Conference Report</a></h2>
+ I spent the first week of February at the Python10 conference
+ in Alexandria, VA. I&#39;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.
+
+ <p>Andy Koenig, of all people, was the keynote speaker of
+ this year&#39;s opening plenary session. He presented his
+ &quot;impressions of a polyglot outsider&quot;, 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&#39;s request for a standard, the process was forced to
+ start: it was a matter of participating or having
+ standardization proceed without one&#39;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
+
+ <p>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&#39;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&#39;ve asked them to
+ send me some information on that.
+
+ <p>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&#39;s strengths (coverage of many langauages) and
+ weaknesses (incomplete C++ language support) haven&#39;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 &quot;C-Tran&quot;: C++ code which
+ traffics in built-in types with little use of abstraction.
+ I&#39;m not knocking that, either: I&#39;m sure a lot of that
+ code exists, so it&#39;s a valuable service. One feature Swig
+ has which I&#39;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.
+
+ <p>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.
+
+ <p>They also have a highly-refined and successful development
+ procedure which I&#39;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&#39;ve never heard before.
+
+ <p>Guido Van Rossum&#39;s &quot;State of the Python
+ Union&quot; 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&#39;ve
+ offered to work with anyone from the Python community who
+ wants to set up something like Boost.
+
+ <p>There was some discussion of &quot;string
+ interpolation&quot; (variable substitution in strings), and
+ Guido mentioned that he had some thoughts about the
+ strengths/weaknesses of Python&#39;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.
+
+ <p>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&#39;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&#39;ll move the yahoogroups
+ discussions into the mailman archive so old discussions can
+ be easily accessed in the same fashion.
+
+ <p>And, just because it&#39;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&#39;s research into
+ moving parts of C++ template compilation to runtime, only
+ coming from the opposite end of things.
+
+ <h2><a name="progress">Boost.Python v2 Progress</a></h2>
+ Here&#39;s what actually got accomplished.
+
+ <h3><a name="documentation">Documentation</a></h3>
+
+ <p>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&#39;t quite work, I settled down to use Bill Kempf&#39;s
+ HTML templates designed to be a boost standard. While they
+ are working well, it is highly labor-intensive.
+
+ <p>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.
+
+ <p>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&#39;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
+
+ <p>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.
+
+ <h3><a name="conversion">Overhaul of
+ <code>to_python</code>/<code>from_python</code> conversion
+ mechanism</a></h3>
+
+ <p>There were two basic realizations involved here:
+
+ <ol>
+ <li><code>to_python</code> conversion could be a one-step
+ process, once an appropriate conversion function is found.
+ This allows elimination of the separate indirect
+ convertibility check
+
+ <li>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++
+ <code>complex&lt;double&gt;</code> or a Python tuple is
+ converted to a C++ <code>std::vector&lt;&gt;</code>. 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.
+ </ol>
+ The latter realization allowed the following collapse, which
+ considerably simplified things:
+
+ <blockquote>
+ <table border="1" summary="Conversion protocol">
+ <tr>
+ <th>Target Type
+
+ <th>Eligible Converters
+
+ <tr>
+ <td><code>T</code>
+
+ <td rowspan="5"><code>T</code> rvalue or lvalue
+
+ <tr>
+ <td><code>T const</code>
+
+ <tr>
+ <td><code>T volatile</code>
+
+ <tr>
+ <td><code>T const volatile</code>
+
+ <tr>
+ <td><code>T const&amp;</code>
+
+ <tr>
+ <td><code>T const*</code>
+
+ <td rowspan="9"><code>T</code> lvalue
+
+ <tr>
+ <td><code>T volatile*</code>
+
+ <tr>
+ <td><code>T const volatile*</code>
+
+ <tr>
+ <td><code>T&amp;</code>
+
+ <tr>
+ <td><code>T volatile&amp;</code>
+
+ <tr>
+ <td><code>T const volatile&amp;</code>
+
+ <tr>
+ <td><code>T* const&amp;</code>
+
+ <tr>
+ <td><code>T const* const&amp;</code>
+
+ <tr>
+ <td><code>T volatile*const&amp;</code>
+
+ <tr>
+ <td><code>T const volatile*const&amp;</code>
+ </table>
+ </blockquote>
+ This job included the following additional enhancements:
+
+ <ul>
+ <li>Elimination of virtual functions, which cause object
+ code bloat
+
+ <li>Registration of a single converter function for all
+ lvalue conversions, two for all rvalue conversions
+
+ <li>Killed lots of unneeded code
+
+ <li>Increased opacity of registry interface
+
+ <li>Eliminated all need for decorated runtime type
+ identifiers
+
+ <li>Updated test modules to reflect new interface
+
+ <li>Eliminated the need for users to worry about converter
+ lifetime issues Additional Builtin Conversion Enhancements
+
+ <li>Support for complex&lt;float&gt;,
+ complex&lt;double&gt;, and complex&lt;long double&gt;
+ conversions
+
+ <li>Support for bool conversions
+
+ <li>NULL pointers representable by None in Python
+
+ <li>Support for conversion of Python classic classes to
+ numeric types
+ </ul>
+
+ <h3><a name="miscellaneous">Miscellaneous</a></h3>
+ These don&#39;t fit easily under a large heading:
+
+ <ul>
+ <li>Support CallPolicies for class member functions
+
+ <li>from_python_data.hpp: revamped type alignment
+ metaprogram so that it&#39;s fast enough for KCC
+
+ <li>classfwd.hpp header forward-declares class_&lt;T&gt;
+
+ <li>indirect_traits.hpp:
+
+ <li>added is_pointer_to_reference
+
+ <li>fixed bugs
+
+ <li>Reduced recompilation dependencies
+
+ <li>msvc_typeinfo works around broken MS/Intel typeid()
+ implementation
+
+ <li>Many fixes and improvements to the type_traits library
+ in order to work around compiler bugs and suppress warnings
+
+ <li>Eliminated the need for explicit acquisition of
+ converter registrations
+
+ <li>Expanded constructor support to 6 arguments
+
+ <li>Implemented generalized pointer lifetime support
+
+ <li>Updated code generation for returning.hpp
+
+ <li>Tracked down and fixed cycle GC bugs
+
+ <li>Added comprehensive unit tests for destroy_reference,
+ pointer_type_id, select_from_python, complex&lt;T&gt;,
+ bool, and classic class instance conversions
+ </ul>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p class="c3">&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002. Distributed
+ under the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</p>
+
diff --git a/libs/python/doc/v2/function_doc_signature.html b/libs/python/doc/v2/function_doc_signature.html
new file mode 100644
index 000000000..e439a77ac
--- /dev/null
+++ b/libs/python/doc/v2/function_doc_signature.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright Nikolay Mladenov 2007. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/doobject/function_doc_signature.hpp&gt;</title>
+</head>
+
+<body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href=
+ "../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/object/function_doc_signature.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#function_doc_signature_generator-spec">Class
+ <code>function_doc_signature_generator</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#function_doc_signature_generator-spec-synopsis">Class
+ <code>function_doc_signature_generator</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id=
+ "introduction"></a>Introduction</h2>
+
+ <p>Boost.Python supports docstrings with automatic
+ appending of Pythonic and C++ signatures. This feature is implemented
+ by <code>class function_doc_signature_generator</code>
+ The class uses all of the overloads, supplied arg names and default values, as well as
+ the user-defined docstrings, to generate documentation for a given function.</p>
+
+ <h2><a name="classes" id="classes"></a>Classes</h2>
+
+ <h3><a name="function_doc_signature_generator-spec" id=
+ "function_doc_signature_generator-spec"></a>Class
+ <code>function_doc_signature_generator</code></h3>
+
+ <p>
+ The class has only one public function which returns a list of strings documenting the
+ overloads of a function.
+ </p>
+
+ <h4><a name="function_doc_signature_generator-spec-synopsis" id=
+ "function_doc_signature_generator-spec-synopsis"></a>Class
+ <code>function_doc_signature_generator</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace objects {
+
+ class function_doc_signature_generator
+ {
+ public:
+ static list function_doc_signatures(function const *f);
+ };
+
+}}}
+</pre>
+
+
+ <h2><a name="examples" id="examples"></a>Examples</h2>
+
+ <h4>Docstrings generated with <code>function_doc_signature_generator</code></h4>
+ <pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/args.hpp&gt;
+#include &lt;boost/python/tuple.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/overloads.hpp&gt;
+#include &lt;boost/python/raw_function.hpp&gt;
+
+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 X
+{
+ tuple f(int x = 1, double y = 4.25, char const* z = "wow")
+ {
+ return make_tuple(x, y, z);
+ }
+};
+
+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, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
+ , "This is f's docstring"
+ );
+
+ def("raw", raw_function(raw_func));
+
+ def("f1", f, f_overloads("f1's docstring", args("x", "y", "z")));
+
+
+ class_&lt;X&gt;("X", "This is X's docstring", init&lt;&gt;(args("self")))
+ .def("f", &amp;X::f
+ , "This is X.f's docstring"
+ , args("self","x", "y", "z"))
+
+ ;
+
+}
+
+</pre>
+Python code:
+ <pre>
+&gt;&gt;&gt; import args_ext
+&gt;&gt;&gt; help(args_ext)
+Help on module args_ext:
+
+NAME
+ args_ext
+
+FILE
+ args_ext.pyd
+
+CLASSES
+ Boost.Python.instance(__builtin__.object)
+ X
+
+ class X(Boost.Python.instance)
+ | This is X's docstring
+ |
+ | Method resolution order:
+ | X
+ | Boost.Python.instance
+ | __builtin__.object
+ |
+ | Methods defined here:
+ |
+ | __init__(...)
+ | __init__( (object)self) -> None :
+ | C++ signature:
+ | void __init__(struct _object *)
+ |
+ | f(...)
+ | f( (X)self, (int)x, (float)y, (str)z) -> tuple : This is X.f's docstring
+ | C++ signature:
+ | class boost::python::tuple f(struct X {lvalue},int,double,char const *)
+ |
+ | .................
+ |
+FUNCTIONS
+ f(...)
+ f([ (int)x=1 [, (float)y=4.25 [, (str)z='wow']]]) -> tuple : This is f's docstring
+ C++ signature:
+ class boost::python::tuple f([ int=1 [,double=4.25 [,char const *='wow']]])
+
+ f1(...)
+ f1([ (int)x [, (float)y [, (str)z]]]) -> tuple : f1's docstring
+ C++ signature:
+ class boost::python::tuple f1([ int [,double [,char const *]]])
+
+ raw(...)
+ object raw(tuple args, dict kwds) :
+ C++ signature:
+ object raw(tuple args, dict kwds)
+
+
+</pre>
+
+ <p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/handle.html b/libs/python/doc/v2/handle.html
new file mode 100644
index 000000000..b20d94a1f
--- /dev/null
+++ b/libs/python/doc/v2/handle.html
@@ -0,0 +1,336 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/handle.hpp&gt;</title>
+
+ <style type="text/css">
+ p.c4 {font-style: italic}
+ span.c3 {color: #ff0000}
+ h2.c2 {text-align: center}
+ h1.c1 {text-align: center}
+ </style>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 class="c2">Header &lt;boost/python/handle.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#handle-spec">Class template
+ <code>handle</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#handle-spec-synopsis">Class <code>handle</code>
+ synopsis</a></dt>
+
+ <dt><a href="#handle-spec-ctors">Class <code>handle</code>
+ constructors and destructor</a></dt>
+
+ <dt><a href="#handle-spec-modifiers">Class <code>handle</code>
+ modifier functions</a></dt>
+
+ <dt><a href="#handle-spec-observers">Class <code>handle</code>
+ observer functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#borrowed-spec"><code>borrowed</code></a></dt>
+
+ <dt><a href="#allow_null-spec"><code>allow_null</code></a></dt>
+ </dl>
+ </dd>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/handle.hpp&gt;</code> provides
+ <code>class&nbsp;template&nbsp;handle</code>, a smart pointer for
+ managing reference-counted Python objects.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="handle-spec"></a>Class template <code>handle</code></h3>
+
+ <p><code>handle</code> is a smart pointer to a Python object type; it
+ holds a pointer of type <code>T*</code>, where T is its template
+ parameter. <code>T</code> must be either a type derived from
+ <code>PyObject</code> or a <a href="definitions.html#POD">POD</a> type
+ whose initial <code>sizeof(PyObject)</code> bytes are layout-compatible
+ with <code>PyObject</code>. Use <code>handle&lt;&gt;</code> at the
+ boundary between the Python/'C' API and high-level code; prefer <code><a
+ href="object.html#object-spec">object</a></code> for a generalized
+ interface to Python objects.</p>
+
+ <p><a name="upcast"></a>In this document, the term "upcast" refers to an
+ operation which converts a pointer <code>Y*</code> to a base class
+ pointer <code>T*</code> via <code>static_cast&lt;T*&gt;</code> if
+ <code>Y</code> is derived from <code>T</code>, or via C-style cast
+ <code>(T*)</code> if it is not. However, in the latter case the "upcast"
+ is ill-formed if the initial <code>sizeof(PyObject)</code> bytes of
+ <code>Y</code> are not layout-compatible with <code>PyObject</code>.</p>
+
+ <h4><a name="handle-spec-synopsis"></a>Class template handle
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T&gt;
+ class handle
+ {
+ typedef <i>unspecified-member-function-pointer</i> bool_type;
+
+ public: // types
+ typedef T element_type;
+
+ public: // member functions
+ ~handle();
+
+ template &lt;class Y&gt;
+ explicit handle(detail::borrowed&lt;null_ok&lt;Y&gt; &gt;* p);
+
+ template &lt;class Y&gt;
+ explicit handle(null_ok&lt;detail::borrowed&lt;Y&gt; &gt;* p);
+
+ template &lt;class Y&gt;
+ explicit handle(detail::borrowed&lt;Y&gt;* p);
+
+ template &lt;class Y&gt;
+ explicit handle(null_ok&lt;Y&gt;* p);
+
+ template &lt;class Y&gt;
+ explicit handle(Y* p);
+
+ handle();
+
+ handle&amp; operator=(handle const&amp; r);
+
+ template&lt;typename Y&gt;
+ handle&amp; operator=(handle&lt;Y&gt; const &amp; r); // never throws
+
+
+ template &lt;typename Y&gt;
+ handle(handle&lt;Y&gt; const&amp; r);
+
+ handle(handle const&amp; r);
+
+ T* operator-&gt; () const;
+ T&amp; operator* () const;
+ T* get() const;
+ void reset();
+ T* release();
+
+ operator bool_type() const; // never throws
+ private:
+ T* m_p;
+ };
+
+ template &lt;class T&gt; struct null_ok;
+ namespace detail { template &lt;class T&gt; struct borrowed; }
+}}
+</pre>
+
+ <h4><a name="handle-spec-ctors">Class <code>handle</code> constructors
+ and destructor</a></h4>
+<pre>
+virtual ~handle();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>Py_XDECREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(m_p))</code></dt>
+ </dl>
+<pre>
+template &lt;class Y&gt;
+explicit handle(detail::borrowed&lt;null_ok&lt;Y&gt; &gt;* p);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(p));
+ m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
+ </dl>
+<pre>
+template &lt;class Y&gt;
+explicit handle(null_ok&lt;detail::borrowed&lt;Y&gt; &gt;* p);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(p));
+ m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
+ </dl>
+<pre>
+template &lt;class Y&gt;
+explicit handle(detail::borrowed&lt;Y&gt;* p);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(p));
+ m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a href=
+ "errors.html#expect_non_null-spec">expect_non_null</a>(p));</code></dt>
+ </dl>
+<pre>
+template &lt;class Y&gt;
+explicit handle(null_ok&lt;Y&gt;* p);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
+ </dl>
+<pre>
+template &lt;class Y&gt;
+explicit handle(Y* p);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a href=
+ "errors.html#expect_non_null-spec">expect_non_null</a>(p));</code></dt>
+ </dl>
+<pre>
+handle();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> <code>m_p&nbsp;=&nbsp;0;</code></dt>
+ </dl>
+<pre>
+template &lt;typename Y&gt;
+handle(handle&lt;Y&gt; const&amp; r);
+handle(handle const&amp; r);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>m_p&nbsp;=&nbsp;r.m_p;&nbsp;Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(m_p));</code></dt>
+ </dl>
+
+ <h4><a name="handle-spec-modifiers">Class <code>handle</code>
+ modifiers</a></h4>
+<pre>
+handle&amp; operator=(handle const&amp; r);
+template&lt;typename Y&gt;
+handle&amp; operator=(handle&lt;Y&gt; const &amp; r); // never throws
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(r.m_p));&nbsp;Py_XDECREF(</code><i>
+ upcast</i><code>&lt;PyObject*&gt;(m_p));&nbsp;m_p&nbsp;=&nbsp;r.m_p;</code></dt>
+ </dl>
+<pre>
+T* release();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> <code>T* x = m_p;&nbsp;m_p&nbsp;=&nbsp;0;return
+ x;</code></dt>
+ </dl>
+<pre>
+void reset();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>*this&nbsp;=&nbsp;handle&lt;T&gt;();</code></dt>
+ </dl>
+
+ <h4><a name="handle-spec-observers">Class <code>handle</code>
+ observers</a></h4>
+<pre>
+T* operator-&gt; () const;
+T* get() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>m_p;</code></dt>
+ </dl>
+<pre>
+T&amp; operator* () const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>*m_p;</code></dt>
+ </dl>
+<pre>
+operator bool_type() const; // never throws
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> 0 if <code>m_p&nbsp;==&nbsp;0</code>, a pointer
+ convertible to <code>true</code> otherwise.</dt>
+ </dl>
+
+ <h2><a name="functions"></a>Functions</h2>
+
+ <h3><a name="borrowed-spec"></a><code>borrowed</code></h3>
+<pre>
+template &lt;class T&gt;
+detail::borrowed&lt;T&gt;* borrowed(T* p)
+{
+ return (detail::borrowed&lt;T&gt;*)p;
+}
+</pre>
+
+ <h3><a name="allow_null-spec"></a><code>allow_null</code></h3>
+<pre>
+template &lt;class T&gt;
+null_ok&lt;T&gt;* allow_null(T* p)
+{
+ return (null_ok&lt;T&gt;*)p;
+}
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p class="c4">&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002
+.</p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/has_back_reference.html b/libs/python/doc/v2/has_back_reference.html
new file mode 100644
index 000000000..29b81506c
--- /dev/null
+++ b/libs/python/doc/v2/has_back_reference.html
@@ -0,0 +1,225 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/has_back_reference.hpp&gt;</title>
+
+ <style type="text/css">
+ p.c3 {font-style: italic}
+ h2.c2 {text-align: center}
+ h1.c1 {text-align: center}
+ </style>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 class="c2">Header
+ &lt;boost/python/has_back_reference.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#has_back_reference-spec">Class template
+ <code>has_back_reference</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#has_back_reference-spec-synopsis">Class template
+ <code>has_back_reference</code> synopsis</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/has_back_reference.hpp&gt;</code> defines the
+ predicate metafunction <code>has_back_reference&lt;&gt;</code>, which can
+ be specialized by the user to indicate that a wrapped class instance
+ holds a <code>PyObject*</code> corresponding to a Python object.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="has_back_reference-spec"></a>Class template
+ <code>has_back_reference</code></h3>
+
+ <p>A unary metafunction whose <code>value</code> is true iff its argument
+ is a <code>pointer_wrapper&lt;&gt;</code>.</p>
+
+ <h4><a name="has_back_reference-spec-synopsis"></a>Class template
+ <code>has_back_reference</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template&lt;class WrappedClass&gt; class has_back_reference
+ {
+ typedef mpl::false_ type;
+ };
+}}
+</pre>
+ <p>A "<a href="../../../mpl/doc/refmanual/metafunction.html">
+ metafunction</a>" that is inspected by Boost.Python to determine how
+ wrapped classes can be constructed.</p>
+
+ <dl class="traits-semantics">
+ <dt><code>type::value</code> is an integral constant convertible to bool
+ of unspecified type.</dt>
+
+ <dt>Specializations may substitute a <code>true</code>-valued integral constant wrapper for
+ <code>type</code> iff for each invocation of
+ <code>class_&lt;WrappedClass&gt;::def(init&lt;</code>
+ <i>type-sequence...</i><code>&gt;())</code> and the implicitly wrapped
+ copy constructor (unless it is <a href="class.html#class_-spec">
+ noncopyable</a>), there exists a corresponding constructor
+ <code>WrappedClass::WrappedClass(PyObject*,&nbsp;</code>
+ <i>type-sequence...</i><code>)</code>. If such a specialization exists,
+ the <code>WrappedClass</code> constructors will be called with a "back
+ reference" pointer to the corresponding Python object whenever they are
+ invoked from Python. The easiest way to provide this nested <code>
+type
+</code>
+ is to
+ derive the specialization from <code>mpl::true_</code>.
+ </dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/has_back_reference.hpp&gt;
+#include &lt;boost/python/handle.hpp&gt;
+#include &lt;boost/shared_ptr.hpp&gt;
+
+using namespace boost::python;
+using boost::shared_ptr;
+
+struct X
+{
+ X(PyObject* self) : m_self(self), m_x(0) {}
+ X(PyObject* self, int x) : m_self(self), m_x(x) {}
+ X(PyObject* self, X const& other) : m_self(self), m_x(other.m_x) {}
+
+ handle&lt;&gt; self() { return handle&lt;&gt;(borrowed(m_self)); }
+ int get() { return m_x; }
+ void set(int x) { m_x = x; }
+
+ PyObject* m_self;
+ int m_x;
+};
+
+// specialize has_back_reference for X
+namespace boost { namespace python
+{
+ template &lt;&gt;
+ struct has_back_reference&lt;X&gt;
+ : mpl::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 m_x;
+};
+
+shared_ptr&lt;Y&gt;
+Y_self(shared_ptr&lt;Y&gt; self) { return self; }
+
+BOOST_PYTHON_MODULE(back_references)
+{
+ class_&lt;X&gt;("X")
+ .def(init&lt;int&gt;())
+ .def("self", &amp;X::self)
+ .def("get", &amp;X::get)
+ .def("set", &amp;X::set)
+ ;
+
+ class_&lt;Y, shared_ptr&lt;Y&gt; &gt;("Y")
+ .def(init&lt;int&gt;())
+ .def("get", &amp;Y::get)
+ .def("set", &amp;Y::set)
+ .def("self", Y_self)
+ ;
+}
+</pre>
+ The following Python session illustrates that <code>x.self()</code>
+ returns the same Python object on which it is invoked, while
+ <code>y.self()</code> must create a new Python object which refers to the
+ same Y instance.
+
+ <h3>Python code</h3>
+<pre>
+&gt;&gt;&gt; from back_references import *
+&gt;&gt;&gt; x = X(1)
+&gt;&gt;&gt; x2 = x.self()
+&gt;&gt;&gt; x2 is x
+<b>1</b>
+&gt;&gt;&gt; (x.get(), x2.get())
+(1, 1)
+&gt;&gt;&gt; x.set(10)
+&gt;&gt;&gt; (x.get(), x2.get())
+(10, 10)
+&gt;&gt;&gt;
+&gt;&gt;&gt;
+&gt;&gt;&gt; y = Y(2)
+&gt;&gt;&gt; y2 = y.self()
+&gt;&gt;&gt; y2 is y
+<b>0</b>
+&gt;&gt;&gt; (y.get(), y2.get())
+(2, 2)
+&gt;&gt;&gt; y.set(20)
+&gt;&gt;&gt; (y.get(), y2.get())
+(20, 20)
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 18 July, 2004
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p class="c3">&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002
+.</p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/implicit.html b/libs/python/doc/v2/implicit.html
new file mode 100644
index 000000000..e9d5cac58
--- /dev/null
+++ b/libs/python/doc/v2/implicit.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/implicit.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/implicit.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#implicitly_convertible-spec">Function Template
+ <code>implicitly_convertible</code></a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+ <code>implicitly_convertible</code> allows Boost.Python to implicitly
+ take advantage of a C++ implicit or explicit conversion when matching
+ Python objects to C++ argument types.
+
+ <h2><a name="functions"></a>Functions</h2>
+
+ <h3><a name="implicitly_convertible-spec"></a>Function template
+ <code>implicitly_convertible</code></h3>
+<pre>
+template &lt;class Source, class Target&gt;
+void implicitly_convertible();
+</pre>
+
+ <table border="1" summary="implicitly_convertible template parameters">
+ <caption>
+ <b><code>implicitly_convertible</code> template parameters</b><br>
+ </caption>
+
+ <tr>
+ <th>Parameter</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td><code>Source</code></td>
+
+ <td>The source type of the implicit conversion</td>
+ </tr>
+
+ <tr>
+ <td><code>Target</code></td>
+
+ <td>The target type of the implicit conversion</td>
+ </tr>
+ </table>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> The declaration <code>Target t(s);</code>, where
+ <code>s</code> is of type <code>Source</code>, is valid.</dt>
+
+ <dt><b>Effects:</b> registers an rvalue <code>from_python</code>
+ converter to <code>Target</code> which can succeed for any
+ <code>PyObject*&nbsp;p</code> iff there exists any registered converter
+ which can produce <code>Source</code> rvalues</dt>
+
+ <dt><b>Rationale:</b> C++ users expect to be able to take advantage of
+ the same sort of interoperability in Python as they do in C++.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/implicit.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+
+using namespace boost::python;
+
+struct X
+{
+ X(int x) : v(x) {}
+ operator int() const { return v; }
+ int v;
+};
+
+int x_value(X const&amp; 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_&lt;X&gt;("X",
+ init&lt;int&gt;())
+ ;
+
+ implicitly_convertible&lt;X,int&gt;();
+ implicitly_convertible&lt;int,X&gt;();
+}
+</pre>
+
+ <h3>Python code</h3>
+<pre>
+&gt;&gt;&gt; from implicit_ext import *
+&gt;&gt;&gt; x_value(X(42))
+42
+&gt;&gt;&gt; x_value(42)
+42
+&gt;&gt;&gt; x = make_x(X(42))
+&gt;&gt;&gt; x_value(x)
+42
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/import.html b/libs/python/doc/v2/import.html
new file mode 100644
index 000000000..15c1c68c5
--- /dev/null
+++ b/libs/python/doc/v2/import.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/import.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/import.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#import-spec"><code>import</code></a></dt>
+ </dl>
+ </dd>
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a mechanism for importing python modules.</p>
+
+ <h2><a name="functions"></a>Functions</h2>
+
+ <h3><a name="import-spec"></a><code>import</code></h3>
+ <pre>
+object import(str name);
+ </pre>
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Imports the module named by <code>name</code>.</dt>
+ <dt><b>Returns:</b> An instance of <a href="object.html#object-spec">object</a>
+ which holds a reference to the imported module.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Examples</h2>
+
+ <para>The following example demonstrates the use of <function>import</function>
+ to access a function in python, and later call it from within C++.</para>
+
+<pre>
+#include &lt;iostream&gt;
+#include &lt;string&gt;
+
+using namespace boost::python;
+
+void print_python_version()
+{
+ // Load the sys module.
+ object sys = import("sys");
+
+ // Extract the python version.
+ std::string version = extract&lt;std::string&gt;(sys.attr("version"));
+ std::cout &lt;&lt; version &lt;&lt; std::endl;
+}
+</pre>
+ <p>Revised 01 November, 2005</p>
+
+ <p><i>&copy; Copyright Stefan Seefeld 2005.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/index.html b/libs/python/doc/v2/index.html
new file mode 100644
index 000000000..92593d06e
--- /dev/null
+++ b/libs/python/doc/v2/index.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="refresh" content="0; URL=../index.html">
+
+ <title></title>
+ </head>
+
+ <body>
+ Loading index page; if nothing happens, please go to <a href=
+ "../index.html">../index.html</a>.
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/indexing.html b/libs/python/doc/v2/indexing.html
new file mode 100644
index 000000000..72c999c41
--- /dev/null
+++ b/libs/python/doc/v2/indexing.html
@@ -0,0 +1,695 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st February 2003), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+ <title>
+ Indexing Support
+ </title>
+ </head>
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3>
+ <a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a>
+ </h3>
+ </td>
+ <td valign="top">
+ <h1 align="center">
+ <a href="../index.html">Boost.Python</a>
+ </h1>
+
+ <h2> Headers &lt;boost/python/indexing/indexing_suite.hpp&gt;<br>
+ &lt;boost/python/indexing/vector_indexing_suite.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+ <h2>
+ Contents
+ </h2>
+ <dl class="page-index">
+ <dt>
+ <a href="#introduction">Introduction</a>
+ </dt>
+ <dt>
+ <a href="#interface">Interface</a>
+ </dt>
+ <dd>
+ <dl class="page-index">
+ <dt>
+ <a href="#indexing_suite">indexing_suite</a>
+ </dt>
+ <dt>
+ <a href="#indexing_suite_subclasses">indexing_suite
+ sub-classes</a>
+ </dt>
+ <dd>
+ <dl class="page-index">
+ <dt>
+ <a href="#vector_indexing_suite">vector_indexing_suite</a>
+ </dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <a href="#indexing_suite_class">indexing_suite class</a>
+ </dt>
+ <dt>
+ <a href="#vector_indexing_suite_class">vector_indexing_suite
+ class<br>
+ </a><a href="#map_indexing_suite_class">map_indexing_suite class</a> </dt>
+ </dl>
+ <hr>
+ <h2>
+ <a name="introduction" id="introduction"></a>Introduction
+ </h2>
+ <p>
+ 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).
+ </p>
+ <p>
+ 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, <a href=
+ "http://www.python.org/doc/current/ref/sequence-types.html">Emulating
+ container types</a>) 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
+ <strong>__len__</strong>, <strong>__getitem__</strong>,
+ <strong>__setitem__</strong>, <strong>__delitem__,</strong>
+ <strong>__iter__</strong> and <strong>__contains</strong>.
+ </p>
+ <p>
+ The goals:
+ </p>
+ <ul>
+ <li>
+ <div>
+ Make indexable C++ containers behave exactly as one would expect a
+ Python container to behave.
+ </div>
+ </li>
+ <li>
+ Provide default reference semantics for container element indexing
+ (<tt>__getitem__</tt>) such that <tt>c[i]</tt> can be mutable.
+ Require:
+ <div>
+ <pre>
+ val = c[i]
+ c[i].m()
+ val == c[i]
+ </pre>
+ </div>where <tt>m</tt> is a non-const (mutating) member function
+ (method).
+ </li>
+ <li>
+ Return safe references from <tt>__getitem__</tt> such that subsequent
+ adds and deletes to and from the container will not result in
+ dangling references (will not crash Python).
+ </li>
+ <li>
+ Support slice indexes.
+ </li>
+ <li>
+ Accept Python container arguments (e.g. lists, tuples) wherever
+ appropriate.
+ </li>
+ <li>
+ Allow for extensibility through re-definable policy classes.
+ </li>
+ <li>
+ Provide predefined support for the most common STL and STL like
+ indexable containers.
+ </li>
+ </ul>
+ <hr>
+
+<h2> <a name="interface"></a>The Boost.Python Indexing Interface</h2>
+<h3> <a name="indexing_suite"></a>indexing_suite [ Header &lt;boost/python/indexing/indexing_suite.hpp&gt;
+ ]</h3>
+ <p>
+ The <tt>indexing_suite</tt> class is the base 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: <a href=
+ "http://www.python.org/doc/current/ref/sequence-types.html">Emulating
+ container types</a>):
+ </p>
+ <dl>
+ <dd>
+ <dl>
+ <dt>
+ <b><a name="l2h-126"><tt class=
+ "method">__len__</tt></a></b>(<var>self</var>)
+ </dt>
+ <dd>
+ Called to implement the built-in function <tt class=
+ "function">len()</tt><a name="l2h-134">&nbsp;</a> Should return
+ the length of the object, an integer <code>&gt;=</code> 0. Also,
+ an object that doesn't define a <tt class=
+ "method">__nonzero__()</tt> method and whose <tt class=
+ "method">__len__()</tt> method returns zero is considered to be
+ false in a Boolean context. <a name="l2h-128">&nbsp;</a>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b><a name="l2h-129"><tt class=
+ "method">__getitem__</tt></a></b>(<var>self, key</var>)
+ </dt>
+ <dd>
+ Called to implement evaluation of
+ <code><var>self</var>[<var>key</var>]</code>. For sequence types,
+ the accepted keys should be integers and slice
+ objects.<a name="l2h-135">&nbsp;</a> Note that the special
+ interpretation of negative indexes (if the class wishes to
+ emulate a sequence type) is up to the <tt class=
+ "method">__getitem__()</tt> method. If <var>key</var> is of
+ an inappropriate type, <tt class="exception">TypeError</tt>
+ may be raised; if of a value outside the set of indexes for
+ the sequence (after any special interpretation of negative
+ values), <tt class="exception">IndexError</tt> should be
+ raised. <span class="note"><b class="label">Note:</b>
+ <tt class="keyword">for</tt> loops expect that an <tt class=
+ "exception">IndexError</tt> will be raised for illegal
+ indexes to allow proper detection of the end of the
+ sequence.</span>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b><a name="l2h-130"><tt class=
+ "method">__setitem__</tt></a></b>(<var>self, key, value</var>)
+ </dt>
+ <dd>
+ Called to implement assignment to
+ <code><var>self</var>[<var>key</var>]</code>. Same note as for
+ <tt class="method">__getitem__()</tt>. 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 <var>key</var> values as for the <tt class=
+ "method">__getitem__()</tt> method.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b><a name="l2h-131"><tt class=
+ "method">__delitem__</tt></a></b>(<var>self, key</var>)
+ </dt>
+ <dd>
+ Called to implement deletion of
+ <code><var>self</var>[<var>key</var>]</code>. Same note as for
+ <tt class="method">__getitem__()</tt>. 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 <var>key</var>
+ values as for the <tt class="method">__getitem__()</tt> method.
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b><a name="l2h-132"><tt class=
+ "method">__iter__</tt></a></b>(<var>self</var>)
+ </dt>
+ <dd>
+ 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 <tt class=
+ "method">iterkeys()</tt>.
+ <p>
+ Iterator objects also need to implement this method; they are
+ required to return themselves. For more information on iterator
+ objects, see ``<a class="ulink" href=
+ "http://www.python.org/doc/current/lib/typeiter.html">Iterator
+ Types</a>'' in the <em class="citetitle"><a href=
+ "http://www.python.org/doc/current/lib/lib.html" title=
+ "Python Library Reference">Python Library Reference</a></em>.
+ </p>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <b><a name="l2h-133"><tt class=
+ "method">__contains__</tt></a></b>(<var>self, item</var>)
+ </dt>
+ <dd>
+ Called to implement membership test operators. Should return true
+ if <var>item</var> is in <var>self</var>, false otherwise. For
+ mapping objects, this should consider the keys of the mapping
+ rather than the values or the key-item pairs.
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+
+<h3> <a name="indexing_suite_subclasses"></a>indexing_suite sub-classes</h3>
+ <p>
+ The <tt>indexing_suite</tt> is not meant to be used as is. A couple of
+ policy functions must be supplied by subclasses of
+ <tt>indexing_suite</tt>. However, a set of <tt>indexing_suite</tt>
+ 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.
+ </p>
+
+<h3> <a name="vector_indexing_suite"></a>vector_indexing_suite [ Header &lt;boost/python/indexing/vector_indexing_suite.hpp&gt;
+ ] </h3>
+<p>
+ The <tt>vector_indexing_suite</tt> class is a predefined
+ <tt>indexing_suite</tt> derived class designed to wrap
+ <tt>std::vector</tt> (and <tt>std::vector</tt> like [i.e. a class with
+ std::vector interface]) classes. It provides all the policies required by the
+ <tt>indexing_suite</tt>.
+ </p>
+ <p>
+ Example usage:
+ </p>
+ <pre>
+ class X {...};
+ ...
+
+ class_&lt;std::vector&lt;X&gt; &gt;("XVec")
+ .def(vector_indexing_suite&lt;std::vector&lt;X&gt; &gt;())
+ ;
+</pre>
+ <p>
+ <tt>XVec</tt> is now a full-fledged Python container (see the
+ <a href="../../test/vector_indexing_suite.cpp">example in full</a>,
+ along with its <a href="../../test/vector_indexing_suite.py">python
+ test</a>).
+</p>
+ <h3><a name="map_indexing_suite" id="map_indexing_suite"></a>map_indexing_suite [ Header &lt;boost/python/indexing/map_indexing_suite.hpp&gt; ] </h3>
+ <p> The <tt>map_indexing_suite</tt> class is a predefined <tt>indexing_suite</tt> derived class designed to wrap <tt>std::map</tt> (and <tt>std::map</tt> like [i.e. a class with std::map interface]) classes. It provides all the policies required by the <tt>indexing_suite</tt>. </p>
+ <p> Example usage: </p>
+ <pre>
+ class X {...};
+ ...
+
+ class_&lt;std::map&lt;X&gt; &gt;("XMap")
+ .def(map_indexing_suite&lt;std::map&lt;X&gt; &gt;())
+ ;
+</pre>
+ <p> By default indexed elements are returned by proxy. This can be disabled by supplying <tt>true</tt> in the NoProxy template parameter. <tt>XMap</tt> is now a full-fledged Python container (see the <a href="../../test/map_indexing_suite.cpp">example in full</a>, along with its <a href="../../test/map_indexing_suite.py">python test</a>).</p>
+ <hr>
+ <h2>
+ <a name="indexing_suite_class"></a>indexing_suite class </h2>
+ <h2> <tt>indexing_suite&lt;<br>
+ </tt><tt>class Container<br>
+ , class DerivedPolicies<font color="#007F00"><br>
+ </font></tt> <tt>,
+ bool NoProxy<br>
+ ,
+ bool NoSlice<br>
+ </tt><tt>, class Data<br>
+ , class Index<br>
+ </tt><tt>, class Key</tt></h2>
+ <table width="100%" border="1">
+ <tr>
+ <td>
+ <strong>Template Parameter</strong><br>
+ </td>
+ <td>
+ <strong>Requirements</strong>
+ </td>
+ <td>
+ <strong>Semantics</strong>
+ </td>
+ <td>
+ <strong>Default</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>Container</tt></font>
+ </td>
+ <td>
+ A class type
+ </td>
+ <td>
+ The container type to be wrapped to Python.
+ </td>
+ <td>&nbsp;
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>DerivedPolicies</tt></font>
+ </td>
+ <td>
+ A subclass of indexing_suite
+ </td>
+ <td>
+ Derived classes provide the policy hooks. See <a href=
+ "#DerivedPolicies">DerivedPolicies</a> below.
+ </td>
+ <td>&nbsp;
+
+ </td>
+ </tr>
+ <tr>
+ <td> <font color="#007F00"><tt>NoProxy</tt></font> </td>
+ <td> A boolean </td>
+ <td> By default indexed elements have Python reference semantics and are returned by proxy. This can be disabled by supplying <strong>true</strong> in the <tt>NoProxy</tt> template parameter. </td>
+ <td> false </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>NoSlice</tt></font>
+ </td>
+ <td>
+ A boolean
+ </td>
+ <td>
+ Do not allow slicing. </td>
+ <td>
+ false
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>Data</tt></font>
+ </td>
+ <td>&nbsp;
+
+ </td>
+ <td>
+ The container's data type.
+ </td>
+ <td>
+ <tt>Container::value_type</tt>
+ </td>
+ </tr>
+ <tr>
+ <td> <font color="#007F00"><tt>Index</tt></font> </td>
+ <td>&nbsp; </td>
+ <td> The container's index type. </td>
+ <td> <tt>Container::size_type</tt> </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>Key</tt></font>
+ </td>
+ <td>&nbsp;
+
+ </td>
+ <td>
+ The container's key type.
+ </td>
+ <td>
+ <tt>Container::value_type</tt>
+ </td>
+ </tr>
+ </table>
+ <pre>
+ template &lt;<br> class Container
+ , class DerivedPolicies
+ , bool NoProxy = false<br> , bool NoSlice = false
+ , class Data = typename Container::value_type
+ , class Index = typename Container::size_type
+ , class Key = typename Container::value_type
+ &gt;<br> class indexing_suite
+ : unspecified
+ {
+ public:
+
+ indexing_suite(); // default constructor
+ }
+ </pre>
+ <h2>
+ <tt><a name="DerivedPolicies"></a>DerivedPolicies</tt>
+ </h2>
+ <dl>
+ <dd>
+ Derived classes provide the hooks needed by
+ the <tt>indexing_suite:</tt>
+ </dd>
+ </dl>
+ <pre> data_type&amp;
+ get_item(Container&amp; container, index_type i);
+
+ static object
+ get_slice(Container&amp; container, index_type from, index_type to);
+
+ static void
+ set_item(Container&amp; container, index_type i, data_type const&amp; v);
+
+ static void
+ set_slice(
+ Container&amp; container, index_type from,
+ index_type to, data_type const&amp; v
+ );
+
+ template &lt;class Iter&gt;
+ static void<br> set_slice(Container&amp; container, index_type from,
+ index_type to, Iter first, Iter last
+ );
+
+ static void
+ delete_item(Container&amp; container, index_type i);
+
+ static void
+ delete_slice(Container&amp; container, index_type from, index_type to);
+
+ static size_t
+ size(Container&amp; container);
+
+ template &lt;class T&gt;
+ static bool
+ contains(Container&amp; container, T const&amp; val);
+
+ static index_type
+ convert_index(Container&amp; container, PyObject* i);
+
+ static index_type
+ adjust_index(index_type current, index_type from,
+ index_type to, size_type len
+ );
+</pre>
+ <blockquote>
+ <p>
+ Most of these policies are self explanatory. <tt>However,
+ <strong>convert_index</strong></tt> and
+ <tt><strong>adjust_index</strong></tt> deserve some explanation.
+ </p>
+ <p>
+ <strong><tt>convert_index</tt></strong> 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.
+ <tt>C[-1]</tt> indexes the rightmost element in <tt>C</tt>).
+ <strong><tt>convert_index</tt></strong> should handle the necessary
+ conversion for the C++ container (e.g. convert <tt>-1</tt> to
+ <tt>C.size()-1</tt>). <tt><strong>convert_index</strong></tt> should
+ also be able to convert the type of the index (A dynamic Python type)
+ to the actual type that the C++ container expects.
+ </p>
+ <p>
+ 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:
+ </p>
+ <pre>
+ [a][b][c][d][e] ---&gt; [d][e]
+ ^ ^
+ 4 1
+</pre>
+ <p>
+ <strong><tt>adjust_index</tt></strong> takes care of the adjustment.
+ Given a current index, the function should return the adjusted index
+ when data in the container at index <tt>from</tt>..<tt>to</tt> is
+ replaced by <tt>len</tt> elements.
+ </p>
+ </blockquote>
+ <div>
+ <hr>
+ <h2>
+ <a name="vector_indexing_suite_class"></a>vector_indexing_suite class
+ </h2>
+ <h3>
+ Class template <tt><br>
+ vector_indexing_suite&lt;<br>
+ class <font color="#007F00">Container</font><br>
+ , bool <font color="#007F00">NoProxy</font><br>
+ , class <font color="#007F00">DerivedPolicies</font>&gt;</tt>
+ </h3>
+ <table width="100%" border="1">
+ <tr>
+ <td>
+ <strong>Template Parameter</strong><br>
+ </td>
+ <td>
+ <strong>Requirements</strong>
+ </td>
+ <td>
+ <strong>Semantics</strong>
+ </td>
+ <td>
+ <strong>Default</strong>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>Container</tt></font>
+ </td>
+ <td>
+ A class type
+ </td>
+ <td>
+ The container type to be wrapped to Python.
+ </td>
+ <td>&nbsp;
+
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>NoProxy</tt></font>
+ </td>
+ <td>
+ A boolean
+ </td>
+ <td>
+ By default indexed elements have Python reference semantics and
+ are returned by proxy. This can be disabled by supplying
+ <strong>true</strong> in the <tt>NoProxy</tt> template parameter.
+ </td>
+ <td>
+ false
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <font color="#007F00"><tt>DerivedPolicies</tt></font>
+ </td>
+ <td>
+ A subclass of indexing_suite
+ </td>
+ <td>
+ The <tt>vector_indexing_suite</tt> 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
+ <tt>indexing_suite</tt> class to call policy function of the most
+ derived class
+ </td>
+ <td>&nbsp;
+
+ </td>
+ </tr>
+ </table>
+ <pre>
+ template &lt;<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite : unspecified_base<br> {<br> public:<br><br> typedef typename Container::value_type data_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> data_type&amp;<br> get_item(Container&amp; container, index_type i);
+
+ static object
+ get_slice(Container&amp; container, index_type from, index_type to);
+
+ static void<br> set_item(Container&amp; container, index_type i, data_type const&amp; v);
+
+ static void
+ set_slice(Container&amp; container, index_type from,
+ index_type to, data_type const&amp; v);
+
+ template &lt;class Iter&gt;<br> static void<br> set_slice(Container&amp; container, index_type from,<br> index_type to, Iter first, Iter last);
+
+ static void
+ delete_item(Container&amp; container, index_type i);
+
+ static void
+ delete_slice(Container&amp; container, index_type from, index_type to);<br>
+ static size_t
+ size(Container&amp; container);
+
+ static bool
+ contains(Container&amp; container, key_type const&amp; key);
+
+ static index_type
+ convert_index(Container&amp; container, PyObject* i);
+
+ static index_type
+ adjust_index(index_type current, index_type from,
+ index_type to, size_type len);
+ };
+
+</pre>
+ <h2><a name="vector_indexing_suite_class"></a>map_indexing_suite class </h2>
+ <h3> Class template <tt><br>
+ map_indexing_suite&lt;<br>
+ class <font color="#007F00">Container</font><br>
+ , bool <font color="#007F00">NoProxy</font><br>
+ , class <font color="#007F00">DerivedPolicies</font>&gt;</tt> </h3>
+ <table width="100%" border="1">
+ <tr>
+ <td> <strong>Template Parameter</strong><br>
+ </td>
+ <td> <strong>Requirements</strong> </td>
+ <td> <strong>Semantics</strong> </td>
+ <td> <strong>Default</strong> </td>
+ </tr>
+ <tr>
+ <td> <font color="#007F00"><tt>Container</tt></font> </td>
+ <td> A class type </td>
+ <td> The container type to be wrapped to Python. </td>
+ <td>&nbsp; </td>
+ </tr>
+ <tr>
+ <td> <font color="#007F00"><tt>NoProxy</tt></font> </td>
+ <td> A boolean </td>
+ <td> By default indexed elements have Python reference semantics and are returned by proxy. This can be disabled by supplying <strong>true</strong> in the <tt>NoProxy</tt> template parameter. </td>
+ <td> false </td>
+ </tr>
+ <tr>
+ <td> <font color="#007F00"><tt>DerivedPolicies</tt></font> </td>
+ <td> A subclass of indexing_suite </td>
+ <td> The <tt>vector_indexing_suite</tt> 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 <tt>indexing_suite</tt> class to call policy function of the most derived class </td>
+ <td>&nbsp; </td>
+ </tr>
+ </table>
+ <pre>
+ template &lt;<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class map_indexing_suite : unspecified_base<br> {<br> public:<br><br> typedef typename Container::value_type value_type;<br> typedef typename Container::value_type::second_type data_type;<br> typedef typename Container::key_type key_type;<br> typedef typename Container::key_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br><br> static data_type&amp;<br> get_item(Container&amp; container, index_type i);
+
+ static void<br> set_item(Container&amp; container, index_type i, data_type const&amp; v);
+
+ static void
+ delete_item(Container&amp; container, index_type i);<br>
+ static size_t
+ size(Container&amp; container);
+
+ static bool
+ contains(Container&amp; container, key_type const&amp; key);
+
+ static bool<br> compare_index(Container&amp; container, index_type a, index_type b);
+<br> static index_type
+ convert_index(Container&amp; container, PyObject* i);
+ };
+
+</pre>
+ <hr>
+ &copy; 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.
+ </div>
+ </body>
+</html>
diff --git a/libs/python/doc/v2/init.html b/libs/python/doc/v2/init.html
new file mode 100644
index 000000000..2aacaad9f
--- /dev/null
+++ b/libs/python/doc/v2/init.html
@@ -0,0 +1,251 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/init.hpp&gt;</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Headers &lt;boost/python/init.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href=
+ "#init-expressions"><em>init-expressions</em></a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#init-spec">Class template <code>init</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#init-spec-synopsis">Class template
+ <code>init</code> synopsis</a></dt>
+
+ <dt><a href="#init-spec-ctors">Class <code>init</code>
+ constructors</a></dt>
+
+ </dl>
+ </dd>
+
+ <dt><a href="#optional-spec">Class template
+ <code>optional</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#optional-spec-synopsis">Class template
+ <code>optional</code> synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/init.hpp&gt;</code> defines the interface for
+ exposing C++ constructors to Python as extension class
+ <code>__init__</code> functions.</p>
+
+ <h2><a name="init-expressions"><em>init-expressions</em></a></h2>
+ An <em>init-expression</em> is used to describe a family of
+ <code>__init__</code> methods to be generated for an extension class, and
+ the result has the following properties:
+
+ <blockquote>
+ <dl class="properties">
+ <dt><b>docstring:</b> An <a href="definitions.html#ntbs">ntbs</a>
+ whose value will bound to the method's <code>__doc__</code>
+ attribute</dt>
+
+ <dt><b>keywords:</b> A <a href=
+ "args.html#keyword-expression">keyword-expression</a> which will be
+ used to name (a trailing subsequence of) the arguments to the
+ generated <code>__init__</code> function(s).</dt>
+
+ <dt><b>call policies:</b> An instance of a model of <a href=
+ "CallPolicies.html">CallPolicies</a>.</dt>
+
+ <dt><b>argument types:</b> An MPL sequence of C++ argument types
+ which will be used to construct the wrapped C++ object. An init
+ expression has one or more
+ <b>valid prefixes</b> which are given by a sequence of
+ prefixes of its argument types.</dt>
+ </dl>
+ </blockquote>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="init-spec"></a>Class template <code>init&lt;T1 =</code>
+ <i>unspecified</i><code>,&nbsp;T2 =</code>
+ <i>unspecified</i><code>,</code>...<code>Tn</code> =
+ <i>unspecified</i><code>&gt;</code></h3>
+
+ <p>A <a href="../../../mpl/doc/refmanual/forward-sequence.html">MPL sequence</a> which
+ can be used to specify a family of one or more <code>__init__</code>
+ functions. Only the last <code>T</code><i><small>i</small></i> supplied
+ may be an instantiation of <a href=
+ "#optional-spec"><code>optional</code></a><code>&lt;</code>...<code>&gt;</code>.</p>
+
+ <h4><a name="init-spec-synopsis"></a>Class template <code>init</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;T1 = <i>unspecified</i>,...T<i>n</i> = <i>unspecified</i>&gt;
+ struct init
+ {
+ init(char const* doc = 0);
+ template &lt;class Keywords&gt; init(Keywords const&amp; kw, char const* doc = 0);
+ template &lt;class Keywords&gt; init(char const* doc, Keywords const&amp; kw);
+
+ template &lt;class CallPolicies&gt;
+ <em>unspecified</em> operator[](CallPolicies const&amp; policies) const
+ };
+}}
+</pre>
+
+ <h4><a name="init-spec-ctors"></a>Class template <code>init</code>
+ constructors</h4>
+<pre>
+init(char const* doc = 0);
+template &lt;class Keywords&gt; init(Keywords const&amp; kw, char const* doc = 0);
+template &lt;class Keywords&gt; init(char const* doc, Keywords const&amp; kw);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> If supplied, <code>doc</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a>. If supplied, <code>kw</code> is the
+ result of a <a href="args.html#keyword-expression"></a></dt>
+
+ <dt><b>Effects:</b> The result is an <em>init-expression</em> whose
+ <em>docstring</em> is <code>doc</code> and whose <em>keywords</em> are
+ a reference to <code>kw</code>. If the first form is used, the
+ resulting expression's <em>keywords</em> are empty. The expression's
+ <em>call policies</em> are an instance of <a href=
+ "default_call_policies.html#default_call_policies-spec">default_call_policies</a>.
+ If <code>T</code><i><small>n</small></i> is <a href=
+ "#optional-spec"><code>optional</code></a><code>&lt;U1,&nbsp;U2,</code>...
+ <code>U</code><small><i>m</i></small><code>&gt;</code>, the
+ expression's <em>valid prefixes</em> are given by:</dt>
+
+ <dd>
+ <blockquote>
+ (<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>),
+ (<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>
+ <code>,&nbsp;U1</code>),
+ (<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>
+ <code>,&nbsp;U1,&nbsp;U2</code>),
+ ...(<code>T1,&nbsp;T2,</code>...<code>T</code><i><small>n-1</small></i>
+ <code>,&nbsp;U1,&nbsp;U2,</code>...<code>U</code><i><small>m</small></i>).
+ </blockquote>
+ Otherwise, the expression has one <em>valid prefix</em> given by the
+ the template arguments the user specified.
+ </dd>
+ </dl>
+
+ <h4><a name="init-spec-observers"></a>Class template <code>init</code>
+ observer functions</h4>
+<pre>
+template &lt;class Policies&gt;
+<em>unspecified</em> operator[](Policies const&amp; policies) const
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> Policies is a model of <a href=
+ "CallPolicies.html">CallPolicies</a>.</dt>
+
+ <dt><b>Effects:</b> Returns a new <a href=
+ "#init-expressions"><em>init-expression</em></a> with all the same
+ properties as the <code>init</code> object except that its <em>call
+ policies</em> are replaced by a reference to
+ <code>policies</code>.</dt>
+ </dl>
+
+ <h3><a name="optional-spec"></a>Class template <code>optional&lt;T1
+ =</code> <i>unspecified</i><code>,&nbsp;T2 =</code>
+ <i>unspecified</i><code>,</code>...<code>Tn</code> =
+ <i>unspecified</i><code>&gt;</code></h3>
+
+ <p>A <a href="../../../mpl/doc/refmanual/forward-sequence.html">MPL sequence</a> which
+ can be used to specify the optional arguments to an <code>__init__</code>
+ function.</p>
+
+ <h4><a name="optional-spec-synopsis"></a>Class template
+ <code>optional</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;T1 = <i>unspecified</i>,...T<i>n</i> = <i>unspecified</i>&gt;
+ struct optional {};
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example(s)</h2>
+
+ <p>Given the C++ declarations:</p>
+<pre>
+class Y;
+class X
+{
+ public:
+ X(int x, Y* y) : m_y(y) {}
+ X(double);
+ private:
+ Y* m_y;
+};
+</pre>
+ A corresponding Boost.Python extension class can be created with:
+<pre>
+using namespace boost::python;
+
+class_&lt;X&gt;("X", "This is X's docstring.",
+ init&lt;int,char const*&gt;(args("x","y"), "X.__init__'s docstring")[
+ with_custodian_and_ward&lt;1,3&gt;()]
+ )
+ .def(init&lt;double&gt;())
+ ;
+</pre>
+ <hr>
+ Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/instance_holder.html b/libs/python/doc/v2/instance_holder.html
new file mode 100644
index 000000000..87571d1da
--- /dev/null
+++ b/libs/python/doc/v2/instance_holder.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/instance_holder.hpp&gt;</title>
+ </head>
+
+<style type="text/css">
+ p.c4 {font-style: italic}
+ span.c3 {color: #ff0000}
+ h2.c2 {text-align: center}
+ h1.c1 {text-align: center}
+</style>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+
+ <td valign="top">
+ <h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 class="c2">Header &lt;boost/python/instance_holder.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a>
+
+ <dt><a href="#classes">Classes</a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#instance_holder-spec">Class
+ <code>instance_holder</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#instance_holder-spec-synopsis">Class
+ <code>instance_holder</code> synopsis</a>
+
+ <dt><a href="#instance_holder-spec-ctors">Class
+ <code>instance_holder</code> destructor</a>
+
+ <dt><a href="#instance_holder-spec-modifiers">Class
+ <code>instance_holder</code> modifier functions</a>
+
+ <dt><a href="#instance_holder-spec-observers">Class
+ <code>instance_holder</code> observer functions</a>
+ </dl>
+ </dl>
+
+ <dt><a href="#examples">Example</a>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/instance_holder.hpp&gt;</code> provides
+ <code>class&nbsp;instance_holder</code>, the base class for types
+ which hold C++ instances of wrapped classes.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="instance_holder-spec"></a>Class <code>instance_holder</code></h3>
+
+ <p><code>instance_holder</code> 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 <code>instance_holder</code>s. When an <code>__init__</code>
+ function for a wrapped C++ class is invoked, a new
+ <code>instance_holder</code> instance is created and installed in
+ the Python object using its <code><a
+ href="#instance_holder-spec-modifiers">install</a></code>()
+ function. Each concrete class derived from
+ <code>instance_holder</code> must provide a <code><a
+ href="#instance_holder-spec-observers">holds</a>()</code>
+ 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 <code>PyObject*</code> 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
+ <code>instance_holder</code> subclass.
+
+ <h4><a name="instance_holder-spec-synopsis"></a>Class instance_holder
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class instance_holder : <a href="../../../utility/utility.htm#Class_noncopyable">noncopyable</a>
+ {
+ public:
+ // destructor
+ virtual ~instance_holder();
+
+ // instance_holder modifiers
+ void install(PyObject* inst) throw();
+
+ // instance_holder observers
+ virtual void* holds(type_info) = 0;
+ };
+}}
+</pre>
+
+ <h4><a name="instance_holder-spec-ctors">Class <code>instance_holder</code>
+ destructor</a></h4>
+<pre>
+virtual ~instance_holder();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> destroys the object
+ </dl>
+
+ <h4><a name="instance_holder-spec-modifiers">Class
+ <code>instance_holder</code> modifiers</a></h4>
+<pre>
+void install(PyObject* inst) throw();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>inst</code> is a Python instance of a
+ wrapped C++ class type, or is a type derived from a wrapped C++
+ class type.
+ <dt><b>Effects:</b> installs the new instance at the head of the
+ Python object's chain of held instances.
+ <dt><b>Throws:</b> nothing
+ </dl>
+
+ <h4><a name="instance_holder-spec-observers">Class <code>instance_holder</code>
+ observers</a></h4>
+<pre>
+virtual void* holds(type_info x) = 0;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> A pointer to an object of the type described
+ by <code>x</code> if <code>*this</code> contains such an object,
+ 0 otherwise.
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+The following is a simplified version of the instance holder template
+used by Boost.Python to wrap classes held by smart pointers:
+<pre>
+template &lt;class SmartPtr, class Value&gt;
+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&lt;class A0&gt;
+ pointer_holder(PyObject*,A0 a0)
+ :m_p(new Value(a0))
+ {
+ }
+
+ template&lt;class A0,class A1&gt;
+ 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&lt;SmartPtr&gt;())
+ return &amp;this-&gt;m_p;
+
+ // ...and an instance of the SmartPtr's element_type, if the
+ // pointer is non-null
+ return python::type_id&lt;Value&gt;() == dst_t ? &amp;*this-&gt;m_p : 0;
+ }
+
+ private: // data members
+ SmartPtr m_p;
+};
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p class="c4">&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.
+
+ </body>
+</html>
diff --git a/libs/python/doc/v2/iterator.html b/libs/python/doc/v2/iterator.html
new file mode 100644
index 000000000..3557ffb9a
--- /dev/null
+++ b/libs/python/doc/v2/iterator.html
@@ -0,0 +1,398 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/iterator.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/iterator.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#iterator-spec">Class template
+ <code>iterator</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#iterator-spec-synopsis">Class
+ <code>iterator</code> synopsis</a></dt>
+
+ <dt><a href="#iterator-spec-constructors">Class template
+ <code>iterator</code> constructor</a></dt>
+ </dl>
+ </dd>
+ </dl>
+
+ <dl class="page-index">
+ <dt><a href="#iterators-spec">Class template
+ <code>iterators</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#iterators-spec-synopsis">Class
+ <code>iterators</code> synopsis</a></dt>
+
+ <dt><a href="#iterators-spec-types">Class template
+ <code>iterators</code> nested types</a></dt>
+
+ <dt><a href="#iterators-spec-statics">Class template
+ <code>iterators</code> static functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#range-spec">range</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/iterator.hpp&gt;</code> provides types and
+ functions for creating <a href=
+ "http://www.python.org/doc/current/lib/typeiter.html">Python
+ iterators</a> from <a href=
+ "http://www.sgi.com/tech/stl/Container.html">C++ Containers</a> and <a
+ href="http://www.sgi.com/tech/stl/Iterators.html">Iterators</a>. Note
+ that if your <code>class_</code> supports random-access iterators,
+ implementing <code><a href=
+ "http://www.python.org/doc/current/ref/sequence-types.html#l2h-128">__getitem__</a></code>
+ (also known as the Sequence Protocol) may serve you better than using
+ this facility: Python will automatically create an iterator type for you
+ (see <a href=
+ "http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-35">iter()</a>),
+ and each access can be range-checked, leaving no possiblity of accessing
+ through an invalidated C++ iterator.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="iterator-spec"></a>Class Template <code>iterator</code></h3>
+
+ <p>Instances of <code>iterator&lt;C,P&gt;</code> hold a reference to a
+ callable Python object which, when invoked from Python, expects a single
+ argument <code>c</code> convertible to <code>C</code> and creates a
+ Python iterator that traverses [<code>c.begin()</code>,
+ <code>c.end()</code>). The optional <a href=
+ "CallPolicies.html">CallPolicies</a> <code>P</code> can be used to
+ control how elements are returned during iteration.</p>
+
+ <p>In the table below, <code><b>c</b></code> is an instance of
+ <code>Container</code>.</p>
+
+ <table border="1" summary="iterator template parameters">
+ <tr>
+ <th>Template Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Semantics</th>
+
+ <th>Default</th>
+ </tr>
+
+ <tr>
+ <td><code>Container</code></td>
+
+ <td>[c.begin(),c.end()) is a valid <a href=
+ "http://www.sgi.com/tech/stl/Iterators.html">Iterator range</a>.</td>
+
+ <td>The result will convert its argument to <code>c</code> and call
+ <code>c.begin()</code> and <code>c.end()</code> to acquire iterators.
+ To invoke <code>Container</code>'s <code>const</code>
+ <code>begin()</code> and <code>end()</code> functions, make it
+ <code>const</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code>NextPolicies</code></td>
+
+ <td>A default-constructible model of <a href=
+ "CallPolicies.html#CallPolicies-concept">CallPolicies</a>.</td>
+
+ <td>Applied to the resulting iterators' <code>next()</code>
+ method.</td>
+
+ <td>An unspecified model of <a href=
+ "CallPolicies.html#CallPolicies-concept">CallPolicies</a> which
+ always makes a copy of the result of deferencing the underlying C++
+ iterator</td>
+ </tr>
+ </table>
+
+ <h4><a name="iterator-spec-synopsis"></a>Class Template iterator
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class Container
+ , class NextPolicies = <i>unspecified</i>&gt;
+ struct iterator : <a href="object.html#object-spec">object</a>
+ {
+ iterator();
+ };
+}}
+</pre>
+
+ <h4><a name="iterator-spec-constructors"></a>Class Template iterator
+ constructor</h4>
+<pre>
+iterator()
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b></dt>
+
+ <dd>
+ Initializes its base class with the result of:
+<pre>
+range&lt;NextPolicies&gt;(&amp;iterators&lt;Container&gt;::begin, &amp;iterators&lt;Container&gt;::end)
+</pre>
+ </dd>
+
+ <dt><b>Postconditions:</b> <code>this-&gt;get()</code> points to a
+ Python callable object which creates a Python iterator as described
+ above.</dt>
+
+ <dt><b>Rationale:</b> Provides an easy way to create iterators for the
+ common case where a C++ class being wrapped provides
+ <code>begin()</code> and <code>end()</code>.</dt>
+ </dl>
+ <!-- -->
+
+ <h3><a name="iterators-spec"></a>Class Template
+ <code>iterators</code></h3>
+
+ <p>A utility class template which provides a way to reliably call its
+ argument's <code>begin()</code> and <code>end()</code> member functions.
+ Note that there is no portable way to take the address of a member
+ function of a C++ standard library container, so
+ <code>iterators&lt;&gt;</code> can be particularly helpful when wrapping
+ them.</p>
+
+ <p>In the table below, <code><b>x</b></code> is an instance of
+ <code>C</code>.</p>
+
+ <table border="1" summary="iterator template parameters">
+ <tr>
+ <th>Required Valid Expression</th>
+
+ <th>Type</th>
+ </tr>
+
+ <tr>
+ <td><code>x.begin()</code></td>
+
+ <td>Convertible to <code>C::const_iterator</code> if <code>C</code>
+ is a <code>const</code> type; convertible to <code>C::iterator</code>
+ otherwise.</td>
+ </tr>
+
+ <tr>
+ <td><code>x.end()</code></td>
+
+ <td>Convertible to <code>C::const_iterator</code> if <code>C</code>
+ is a <code>const</code> type; convertible to <code>C::iterator</code>
+ otherwise.</td>
+ </tr>
+ </table>
+
+ <h4><a name="iterators-spec-synopsis"></a>Class Template iterators
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class C&gt;
+ struct iterators
+ {
+ typedef typename C::[const_]iterator iterator;
+ static iterator begin(C&amp; x);
+ static iterator end(C&amp; x);
+ };
+}}
+
+</pre>
+
+ <h4><a name="iterators-spec-types"></a>Class Template iterators nested
+ types</h4>
+ If C is a <code>const</code> type,
+<pre>
+typedef typename C::const_iterator iterator;
+</pre>
+ Otherwise:
+<pre>
+typedef typename C::iterator iterator;
+</pre>
+
+ <h4><a name="iterators-spec-statics"></a>Class Template iterators static
+ functions</h4>
+<pre>
+static iterator begin(C&amp;);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>x.begin()</code></dt>
+ </dl>
+<pre>
+static iterator end(C&amp;);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>x.end()</code></dt>
+ </dl>
+ <!-- -->
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name=
+"range-spec">template</a> &lt;class NextPolicies, class Target, class Accessor1, class Accessor2&gt;
+<a href=
+"object.html#object-spec">object</a> range(Accessor1 start, Accessor2 finish);
+
+template &lt;class NextPolicies, class Accessor1, class Accessor2&gt;
+<a href=
+"object.html#object-spec">object</a> range(Accessor1 start, Accessor2 finish);
+
+template &lt;class Accessor1, class Accessor2&gt;
+<a href=
+"object.html#object-spec">object</a> range(Accessor1 start, Accessor2 finish);
+</pre>
+
+ <dl class="range-semantics">
+ <dt><b>Requires:</b> <code>NextPolicies</code> is a
+ default-constructible model of <a href=
+ "CallPolicies.html#CallPolicies-concept">CallPolicies</a>.</dt>
+
+ <dt><b>Effects:</b></dt>
+
+ <dd>
+ <dl>
+ <dt>The first form creates a Python callable object which, when
+ invoked, converts its argument to a <code>Target</code> object
+ <code>x</code>, and creates a Python iterator which traverses
+ [<code><a href=
+ "../../../bind/bind.html">bind</a>(start,_1)(x)</code>,&nbsp;<code><a
+ href="../../../bind/bind.html">bind</a>(finish,_1)(x)</code>),
+ applying <code>NextPolicies</code> to the iterator's
+ <code>next()</code> function.</dt>
+
+ <dt>The second form is identical to the first, except that
+ <code>Target</code> is deduced from <code>Accessor1</code> as
+ follows:</dt>
+
+ <dd>
+ <ol>
+ <li>If <code>Accessor1</code> is a function type,
+ <code>Target</code> is the type of its first argument.</li>
+
+ <li>If <code>Accessor1</code> is a data member pointer of the
+ form <code>R&nbsp;(T::*)</code>, <code>Target</code> is
+ identical to <code>T</code>.</li>
+
+ <li>If <code>Accessor1</code> is a member function pointer of
+ the form
+ <code>R&nbsp;(T::*)(</code><i>arguments...</i><code>)</code>&nbsp;
+ <i>cv-opt</i>, where <i>cv-opt</i> is an optional
+ <code>cv-qualifier</code>, <code>Target</code> is identical to
+ <code>T</code>.</li>
+ </ol>
+ </dd>
+
+ <dt>The third form is identical to the second, except that
+ <code>NextPolicies</code> is an unspecified model of <a href=
+ "CallPolicies.html#CallPolicies-concept">CallPolicies</a> which
+ always makes a copy of the result of deferencing the underlying C++
+ iterator</dt>
+ </dl>
+ </dd>
+
+ <dt><b>Rationale:</b> The use of <code><a href=
+ "../../../bind/bind.html">boost::bind</a>()</code> allows C++ iterators
+ to be accessed through functions, member functions or data member
+ pointers. Customization of <code>NextPolicies</code> (e.g. using
+ <code><a href=
+ "return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a></code>)
+ is useful when it is expensive to copy sequence elements of a wrapped
+ class type. Customization of <code>Target</code> is useful when
+ <code>Accessor1</code> is a function object, or when a base class of
+ the intended target type would otherwise be deduced.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Examples</h2>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+
+#include &lt;vector&gt;
+
+using namespace boost::python;
+BOOST_PYTHON_MODULE(demo)
+{
+ class_&lt;std::vector&lt;double&gt; &gt;("dvec")
+ .def("__iter__", iterator&lt;std::vector&lt;double&gt; &gt;())
+ ;
+}
+</pre>
+ A more comprehensive example can be found in:
+
+ <dl>
+ <dt><code><a href=
+ "../../test/iterator.cpp">libs/python/test/iterator.cpp</a></code></dt>
+
+ <dt><code><a href=
+ "../../test/input_iterator.cpp">libs/python/test/input_iterator.cpp</a></code></dt>
+
+ <dt><code><a href=
+ "../../test/iterator.py">libs/python/test/input_iterator.py</a></code></dt>
+
+ </dl>
+<hr>
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/list.html b/libs/python/doc/v2/list.html
new file mode 100644
index 000000000..e347ae461
--- /dev/null
+++ b/libs/python/doc/v2/list.html
@@ -0,0 +1,142 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/list.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/list.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#list-spec">Class <code>list</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#list-spec-synopsis">Class <code>list</code>
+ synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
+ <a href=
+ "http://www.python.org/doc/current/lib/typesseq-mutable.html">list</a>
+ type.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="list-spec"></a>Class <code>list</code></h3>
+
+ <p>Exposes the <a href=
+ "http://www.python.org/doc/current/lib/typesseq-mutable.html">mapping
+ protocol</a> of Python's built-in <code>list</code> type. The semantics
+ of the constructors and member functions defined below can be fully
+ understood by reading the <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
+ definition. Since <code>list</code> is publicly derived from <code><a
+ href="object.html#object-spec">object</a></code>, the public object
+ interface applies to <code>list</code> instances as well.</p>
+
+ <h4><a name="list-spec-synopsis"></a>Class <code>list</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class list : public object
+ {
+ public:
+ list(); // new list
+
+ template &lt;class T&gt;
+ explicit list(T const&amp; sequence);
+
+ template &lt;class T&gt;
+ void append(T const&amp; x);
+
+ template &lt;class T&gt;
+ long count(T const&amp; value) const;
+
+ template &lt;class T&gt;
+ void extend(T const&amp; x);
+
+ template &lt;class T&gt;
+ long index(T const&amp; x) const;
+
+ template &lt;class T&gt;
+ void insert(object const&amp; index, T const&amp; x); // insert object before index
+
+ object pop(); // remove and return item at index (default last)
+ object pop(long index);
+ object pop(object const&amp; index);
+
+ template &lt;class T&gt;
+ void remove(T const&amp; value);
+
+ void reverse(); // reverse *IN PLACE*
+
+ void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -&gt; -1, 0, 1
+
+ template &lt;class T&gt;
+ void sort(T const&amp; value);
+ };
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+using namespace boost::python;
+
+// Return the number of zeroes in the list
+long zeroes(list l)
+{
+ return l.count(0);
+}
+</pre>
+
+ <p>Revised 1 October, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/long.html b/libs/python/doc/v2/long.html
new file mode 100644
index 000000000..08ceb3bd5
--- /dev/null
+++ b/libs/python/doc/v2/long.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/long.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/long.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#long_-spec">Class <code>long_</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#long_-spec-synopsis">Class <code>long_</code>
+ synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
+ <a href=
+ "http://www.python.org/doc/current/lib/typesnumeric.html">long</a>
+ integer type.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="long_-spec"></a>Class <code>long_</code></h3>
+
+ <p>Exposes the <a href=
+ "http://www.python.org/doc/current/lib/typesnumeric.html">numeric type
+ protocol</a> of Python's built-in <code>long</code> type. The semantics
+ of the constructors and member functions defined below can be fully
+ understood by reading the <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
+ definition. Since <code>long_</code> is publicly derived from <code><a
+ href="object.html#object-spec">object</a></code>, the public object
+ interface applies to <code>long_</code> instances as well.</p>
+
+ <h4><a name="long_-spec-synopsis"></a>Class <code>long_</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class long_ : public object
+ {
+ public:
+ long_(); // new long_
+
+ template &lt;class T&gt;
+ explicit long_(T const&amp; rhs);
+
+ template &lt;class T, class U&gt;
+ long_(T const&amp; rhs, U const&amp; base);
+ };
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+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);
+}
+</pre>
+
+ <p>Revised 1 October, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/lvalue_from_pytype.html b/libs/python/doc/v2/lvalue_from_pytype.html
new file mode 100644
index 000000000..d27c57d0c
--- /dev/null
+++ b/libs/python/doc/v2/lvalue_from_pytype.html
@@ -0,0 +1,301 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/lvalue_from_python.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/lvalue_from_pytype.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#lvalue_from_pytype-spec">Class Template
+ <code>lvalue_from_pytype</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#lvalue_from_pytype-spec-synopsis">Class Template
+ <code>lvalue_from_pytype</code> synopsis</a></dt>
+
+ <dt><a href="#lvalue_from_pytype-spec-ctors">Class Template
+ <code>lvalue_from_pytype</code> constructor</a></dt>
+ </dl>
+ </dd>
+ </dl>
+
+ <dl class="page-index">
+ <dt><a href="#extract_identity-spec">Class Template
+ <code>extract_identity</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#extract_identity-spec-synopsis">Class Template
+ <code>extract_identity</code> synopsis</a></dt>
+
+ <dt><a href="#extract_identity-spec-statics">Class Template
+ <code>extract_identity</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#extract_member-spec">Class Template
+ <code>extract_member</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#extract_member-spec-synopsis">Class Template
+ <code>extract_member</code> synopsis</a></dt>
+
+ <dt><a href="#extract_member-spec-statics">Class Template
+ <code>extract_member</code> static functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+ <code>&lt;boost/python/lvalue_from_pytype.hpp&gt;</code> 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.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="lvalue_from_pytype-spec"></a>Class template
+ <code>lvalue_from_pytype</code></h3>
+
+ <p>Class template <code>lvalue_from_pytype</code> 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:</p>
+
+ <table border="1" summary="lvalue_from_pytype template parameters">
+ <caption>
+ <b><code>lvalue_from_pytype</code> Requirements</b><br>
+ In the table below, <b><code>x</code></b> denotes an object of type
+ <code>PythonObject&amp;</code>
+ </caption>
+
+ <tr>
+ <th>Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Semantics</th>
+ </tr>
+
+ <tr>
+ <td><code>Extractor</code></td>
+
+ <td>a model of <a href=
+ "Extractor.html#Extractor-concept">Extractor</a> whose execute
+ function returns a reference type.</td>
+
+ <td>Extracts the lvalue from the Python object once its type has been
+ confirmed</td>
+ </tr>
+
+ <tr>
+ <td><code>python_type</code></td>
+
+ <td>A compile-time constant <code><a href=
+ "http://www.python.org/doc/2.2/ext/dnt-type-methods.html">PyTypeObject</a>*</code></td>
+
+ <td>The Python type of instances convertible by this converter.
+ Python subtypes are also convertible.</td>
+ </tr>
+ </table>
+
+ <h4><a name="lvalue_from_pytype-spec-synopsis"></a>Class template
+ <code>lvalue_from_pytype</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class Extractor, PyTypeObject const* python_type&gt;
+ struct lvalue_from_pytype
+ {
+ lvalue_from_pytype();
+ };
+}}
+</pre>
+
+ <h4><a name="lvalue_from_pytype-spec-ctors"></a>Class template
+ <code>lvalue_from_pytype</code> constructor</h4>
+<pre>
+lvalue_from_pytype();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Registers converters which can convert Python
+ objects of the given type to lvalues of the type returned by
+ <code>Extractor::execute</code>.</dt>
+ </dl>
+
+ <h3><a name="extract_identity-spec"></a>Class template
+ <code>extract_identity</code></h3>
+
+ <p><code>extract_identity</code> is a model of <a href=
+ "Extractor.html#Extractor-concept">Extractor</a> which can be used in the
+ common case where the C++ type to be extracted is the same as the Python
+ object type.</p>
+
+ <h4><a name="extract_identity-spec-synopsis"></a>Class template
+ <code>extract_identity</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class InstanceType&gt;
+ struct extract_identity
+ {
+ static InstanceType&amp; execute(InstanceType&amp; c);
+ };
+}}
+</pre>
+
+ <h4><a name="extract_identity-spec-statics"></a>Class template
+ <code>extract_identity</code> static functions</h4>
+<pre>
+InstanceType&amp; execute(InstanceType&amp; c);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>c</code></dt>
+ </dl>
+
+ <h3><a name="extract_member-spec"></a>Class template
+ <code>extract_member</code></h3>
+
+ <p><code>extract_member</code> is a model of <a href=
+ "Extractor.html#Extractor-concept">Extractor</a> 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.</p>
+
+ <h4><a name="extract_member-spec-synopsis"></a>Class template
+ <code>extract_member</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class InstanceType, class MemberType, MemberType (InstanceType::*member)&gt;
+ struct extract_member
+ {
+ static MemberType&amp; execute(InstanceType&amp; c);
+ };
+}}
+</pre>
+
+ <h4><a name="extract_member-spec-statics"></a>Class template
+ <code>extract_member</code> static functions</h4>
+<pre>
+static MemberType&amp; execute(InstanceType&amp; c);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>c.*member</code></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+ This example presumes that someone has implemented the standard <a href=
+ "http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
+ module</a> from the Python documentation, and we want to build a module
+ which manipulates <code>Noddy</code>s. Since
+ <code>noddy_NoddyObject</code> 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
+ <code>noddy_NoddyType</code>.
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/handle.hpp&gt;
+#include &lt;boost/python/borrowed.hpp&gt;
+#include &lt;boost/python/lvalue_from_pytype.hpp&gt;
+
+// definition lifted from the Python docs
+typedef struct {
+ PyObject_HEAD
+} noddy_NoddyObject;
+
+using namespace boost::python;
+static handle&lt;noddy_NoddyObject&gt; cache;
+
+bool is_cached(noddy_NoddyObject* x)
+{
+ return x == cache.get();
+}
+
+void set_cache(noddy_NoddyObject* x)
+{
+ cache = handle&lt;noddy_NoddyObject&gt;(borrowed(x));
+}
+
+BOOST_PYTHON_MODULE(noddy_cache)
+{
+ def("is_cached", is_cached);
+ def("set_cache", set_cache);
+
+ // register Noddy lvalue converter
+ lvalue_from_pytype&lt;extract_identity&lt;noddy_NoddyObject&gt;,&amp;noddy_NoddyType&gt;();
+}
+</pre>
+
+ <h3>Python code</h3>
+<pre>
+&gt;&gt;&gt; import noddy
+&gt;&gt;&gt; n = noddy.new_noddy()
+&gt;&gt;&gt; import noddy_cache
+&gt;&gt;&gt; noddy_cache.is_cached(n)
+0
+&gt;&gt;&gt; noddy_cache.set_cache(n)
+&gt;&gt;&gt; noddy_cache.is_cached(n)
+1
+&gt;&gt;&gt; noddy_cache.is_cached(noddy.new_noddy())
+0
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 20 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/make_function.html b/libs/python/doc/v2/make_function.html
new file mode 100644
index 000000000..d5a6cdb06
--- /dev/null
+++ b/libs/python/doc/v2/make_function.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/make_function.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/make_function.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#make_function-spec">make_function</a></dt>
+
+ <dt><a href="#make_constructor-spec">make_constructor</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code><a href="#make_function-spec">make_function</a>()</code> and
+ <code><a href="#make_constructor-spec">make_constructor</a>()</code> are
+ the functions used internally by <code><a href=
+ "def.html#def-spec">def</a>()</code> and <code>class_&lt;&gt;::<a href=
+ "class.html#class_-spec-modifiers">def</a>()</code> to produce Python
+ callable objects which wrap C++ functions and member functions.</p>
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name="make_function-spec">template &lt;class F&gt;</a>
+<a href="object.html#object-spec">object</a> make_function(F f)
+
+template &lt;class F, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies)
+
+template &lt;class F, class Policies, class KeywordsOrSignature&gt;
+<a href=
+"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, KeywordsOrSignature const&amp; ks)
+
+template &lt;class F, class Policies, class Keywords, class Signature&gt;
+<a href=
+"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; kw, Signature const&amp; sig)
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>F</code> is a function pointer or member
+ function pointer type. If <code>policies</code> are supplied, it must
+ be a model of <a href="CallPolicies.html">CallPolicies</a>. If
+ <code>kewords</code> are supplied, it must be the result of a <a href=
+ "args.html#keyword-expression"><em>keyword-expression</em></a>
+ specifying no more arguments than the <a href=
+ "definitions.html#arity">arity</a> of <code>f</code>.</dt>
+
+ <dt><b>Effects:</b> Creates a Python callable object which, when called
+ from Python, converts its arguments to C++ and calls <code>f</code>. If
+ <code>F</code> is a pointer-to-member-function type, the target
+ object of the function call (<code>*this</code>) will be taken
+ from the first Python argument, and subsequent Python arguments
+ will be used as the arguments
+ to <code>f</code>. <ul>
+<li> If <code>policies</code> are supplied, it
+ will be applied to the function as described <a href=
+ "CallPolicies.html">here</a>.
+<li>If <code>keywords</code> are
+ supplied, the keywords will be applied in order to the final
+ arguments of the resulting function.
+<li>If <code>Signature</code>
+ is supplied, it should be an instance of an <a
+ href="../../../mpl/doc/refmanual/front-extensible-sequence.html">MPL front-extensible
+ sequence</a> representing the function's return type followed by
+ its argument types. Pass a <code>Signature</code> when wrapping
+ function object types whose signatures can't be deduced, or when
+ you wish to override the types which will be passed to the
+ wrapped function.
+</ul></dt>
+
+ <dt><b>Returns:</b> An instance of <a href=
+ "object.html#object-spec">object</a> which holds the new Python
+ callable object.</dt>
+
+ <dt><b>Caveats:</b> An argument of pointer type may
+ be <code>0</code> if <code>None</code> is passed from Python.
+ An argument type which is a constant reference may refer to a
+ temporary which was created from the Python object for just the
+ duration of the call to the wrapped function, for example
+ a <code>std::vector</code> conjured up by the conversion process
+ from a Python list. Use a non-<code>const</code> reference
+ argument when a persistent lvalue is required.
+ </dl>
+
+<pre>
+<a name="make_constructor-spec">template &lt;class F&gt;</a>
+<a href="object.html#object-spec">object</a> make_constructor(F f)
+
+template &lt;class F, class Policies&gt;
+<a href=
+"object.html#object-spec">object</a> make_constructor(F f, Policies const&amp; policies)
+
+template &lt;class F, class Policies, class KeywordsOrSignature&gt;
+<a href=
+"object.html#object-spec">object</a> make_constructor(F f, Policies const&amp; policies, KeywordsOrSignature const&amp; ks)
+
+template &lt;class F, class Policies, class Keywords, class Signature&gt;
+<a href=
+"object.html#object-spec">object</a> make_constructor(F f, Policies const&amp; policies, Keywords const&amp; kw, Signature const&amp; sig)
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>F</code> is a
+ function pointer type. If <code>policies</code> are supplied, it must
+ be a model of <a href="CallPolicies.html">CallPolicies</a>. If
+ <code>kewords</code> are supplied, it must be the result of a <a href=
+ "args.html#keyword-expression"><em>keyword-expression</em></a>
+ specifying no more arguments than the <a href=
+ "definitions.html#arity">arity</a> of <code>f</code>.</dt>
+
+ <dt><b>Effects:</b> Creates a Python callable object which, when called
+ from Python, converts its arguments to C++ and calls <code>f</code>.</dt>
+
+ <dt><b>Returns:</b> An instance of <a href=
+ "object.html#object-spec">object</a> which holds the new Python
+ callable object.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <p>C++ function exposed below returns a callable object wrapping one of
+ two functions.</p>
+<pre>
+#include &lt;boost/python/make_function.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+
+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);
+}
+</pre>
+ It can be used this way in Python:
+<pre>
+&gt;&gt;&gt; from make_function_test import *
+&gt;&gt;&gt; f = choose_function(1)
+&gt;&gt;&gt; g = choose_function(0)
+&gt;&gt;&gt; f()
+'foo'
+&gt;&gt;&gt; g()
+'bar'
+</pre>
+
+ <p>
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/manage_new_object.html b/libs/python/doc/v2/manage_new_object.html
new file mode 100644
index 000000000..57efb4137
--- /dev/null
+++ b/libs/python/doc/v2/manage_new_object.html
@@ -0,0 +1,145 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/manage_new_object.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/manage_new_object.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#manage_new_object-spec">Class
+ <code>manage_new_object</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#manage_new_object-spec-synopsis">Class
+ <code>manage_new_object</code> synopsis</a></dt>
+
+ <dt><a href="#manage_new_object-spec-metafunctions">Class
+ <code>manage_new_object</code> metafunctions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="manage_new_object-spec"></a>Class
+ <code>manage_new_object</code></h3>
+
+ <p><code>manage_new_object</code> is a model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
+ which can be used to wrap C++ functions which return a pointer to an
+ object allocated with a <i>new-expression</i>, and expect the caller to
+ take responsibility for deleting that object.</p>
+
+ <h4><a name="manage_new_object-spec-synopsis"></a>Class
+ <code>manage_new_object</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct manage_new_object
+ {
+ template &lt;class T&gt; struct apply;
+ };
+}}
+</pre>
+
+ <h4><a name="manage_new_object-spec-metafunctions"></a>Class
+ <code>manage_new_object</code> metafunctions</h4>
+<pre>
+template &lt;class T&gt; struct apply
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Requires:</b> <code>T</code> is <code>U*</code> for some
+ <code>U</code>.</dt>
+
+ <dt><b>Returns:</b> <code>typedef <a href=
+ "to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>&lt;T&gt;
+ type;</code></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <p>In C++:</p>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/manage_new_object.hpp&gt;
+#include &lt;boost/python/return_value_policy.hpp&gt;
+
+
+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&lt;manage_new_object&gt;())
+ class_&lt;Foo&gt;("Foo")
+ .def("get_x", &amp;Foo::get_x)
+ ;
+}
+</pre>
+ In Python:
+<pre>
+&gt;&gt;&gt; from my_module import *
+&gt;&gt;&gt; f = make_foo(3) # create a Foo object
+&gt;&gt;&gt; f.get_x()
+3
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/module.html b/libs/python/doc/v2/module.html
new file mode 100644
index 000000000..353523cb6
--- /dev/null
+++ b/libs/python/doc/v2/module.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/module.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/module.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a>
+
+ <dt><a href="#macros">Macros</a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href=
+ "#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a>
+ </dl>
+
+ <dt><a href="#examples">Example(s)</a>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>This header provides the basic facilities needed to create a
+ Boost.Python extension module.
+
+ <h2><a name="macros"></a>Macros</h2>
+
+ <p><a name=
+ "BOOST_PYTHON_MODULE-spec"><code>BOOST_PYTHON_MODULE(name)</code></a>
+ is used to declare Python <a href=
+ "http://www.python.org/doc/2.2/ext/methodTable.html#SECTION003400000000000000000">
+ module initialization functions</a>. The <code>name</code> argument must
+ exactly match the name of the module to be initialized, and must conform to
+ Python's <a href=
+ "http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming
+ rules</a>. Where you would normally write
+<pre>
+extern &quot;C&quot; void init<i>name</i>()
+{
+ ...
+}
+</pre>
+ Boost.Python modules should be initialized with
+<pre>
+BOOST_PYTHON_MODULE(<i>name</i>)
+{
+ ...
+}
+</pre>
+
+This macro generates two functions in the scope where it is used:
+<code>extern&nbsp;&quot;C&quot;&nbsp;void&nbsp;init<i>name</i>()</code>,
+and <code>void&nbsp;init_module_<i>name</i>()</code>, whose body must
+follow the macro invocation. <code>init_<i>name</i></code> passes
+<code>init_module_<i>name</i></code> to <code><a
+href="errors.html#handle_exception-spec">handle_exception</a>()</code> so
+that any C++ exceptions generated are safely processeed. During the
+body of <code>init_<i>name</i></code>, the current <code><a
+href="scope.html#scope-spec">scope</a></code> refers to the module
+being initialized.
+
+ <h2><a name="examples"></a>Example(s)</h2>
+
+ <p>C++ module definition:
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+
+BOOST_PYTHON_MODULE(xxx)
+{
+ throw &quot;something bad happened&quot;
+}
+</pre>
+
+Interactive Python:
+<pre>
+&gt;&gt;&gt; import xxx
+Traceback (most recent call last):
+ File "<stdin>", line 1, in ?
+RuntimeError: Unidentifiable C++ Exception
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i> Distributed
+ under the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</p>
+
diff --git a/libs/python/doc/v2/numeric.html b/libs/python/doc/v2/numeric.html
new file mode 100644
index 000000000..eaa390af4
--- /dev/null
+++ b/libs/python/doc/v2/numeric.html
@@ -0,0 +1,276 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+
+<html>
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/numeric.hpp&gt;</title>
+</head>
+
+<body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/numeric.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#array-spec">Class <code>array</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#array-spec-synopsis">Class <code>array</code>
+ synopsis</a></dt>
+
+ <dt><a href="#array-spec-observers">Class <code>array</code>
+ observer functions</a></dt>
+
+ <dt><a href="#array-spec-statics">Class <code>array</code> static
+ functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id="introduction"></a>Introduction</h2>
+
+ <p>Exposes a <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
+ <a href=
+ "http://www.python.org/dev/doc/devel/lib/typesmapping.html">array</a>
+ type.</p>
+
+ <h2><a name="classes" id="classes"></a>Classes</h2>
+
+ <h3><a name="array-spec" id="array-spec"></a>Class <code>array</code></h3>
+
+ <p>Provides access to the array types of <a href=
+ "http://www.pfdubois.com/numpy/">Numerical Python</a>'s <a href=
+ "http://www.pfdubois.com/numpy/#Numeric">Numeric</a> and <a href=
+ "http://stsdas.stsci.edu/numarray/index.html">NumArray</a> modules. With
+ the exception of the functions documented <a href=
+ "#array-spec-observers">below</a>, the semantics of the constructors and
+ member functions defined below can be fully understood by reading the
+ <a href="ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
+ definition. Since <code>array</code> is publicly derived from
+ <code><a href="object.html#object-spec">object</a></code>, the public
+ object interface applies to <code>array</code> instances as well.</p>
+
+ <p><a name="default_search" id="default_search"></a>The default behavior is
+ to use <code>numarray.NDArray</code> as the associated Python type if the
+ <code>numarray</code> module is installed in the default location.
+ Otherwise it falls back to use <code>Numeric.ArrayType</code>. If neither
+ extension module is installed, overloads of wrapped C++ functions with
+ <code>numeric::array</code> parameters will never be matched, and other
+ attempted uses of <code>numeric::array</code> will <a href=
+ "definitions.html#raise">raise</a> an appropriate Python exception. The
+ associated Python type can be set manually using the <code><a href=
+ "#array-spec-statics">set_module_and_type</a>(...)</code> static
+ function.</p>
+
+ <h4><a name="array-spec-synopsis" id="array-spec-synopsis"></a>Class
+ <code>array</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace numeric
+{
+ class array : public object
+ {
+ public:
+ object astype();
+ template &lt;class Type&gt;
+ object astype(Type const&amp; type_);
+
+ template &lt;class Type&gt;
+ array new_(Type const&amp; type_) const;
+
+ template &lt;class Sequence&gt;
+ void resize(Sequence const&amp; x);
+ void resize(long x1);
+ void resize(long x1, long x2);
+ ...
+ void resize(long x1, long x2,...long x<i>n</i>);
+
+ template &lt;class Sequence&gt;
+ void setshape(Sequence const&amp; x);
+ void setshape(long x1);
+ void setshape(long x1, long x2);
+ ...
+ void setshape(long x1, long x2,...long x<i>n</i>);
+
+ template &lt;class Indices, class Values&gt;
+ void put(Indices const&amp; indices, Values const&amp; values);
+
+ template &lt;class Sequence&gt;
+ object take(Sequence const&amp; sequence, long axis = 0);
+
+ template &lt;class File&gt;
+ void tofile(File const&amp; f) const;
+
+ object factory();
+ template &lt;class Sequence&gt;
+ object factory(Sequence const&amp;);
+ template &lt;class Sequence, class Typecode&gt;
+ object factory(Sequence const&amp;, Typecode const&amp;, bool copy = true, bool savespace = false);
+ template &lt;class Sequence, class Typecode, class Type&gt;
+ object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;);
+ template &lt;class Sequence, class Typecode, class Type, class Shape&gt;
+ object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;, Shape const&amp;);
+
+ template &lt;class T1&gt;
+ explicit array(T1 const&amp; x1);
+ template &lt;class T1, class T2&gt;
+ explicit array(T1 const&amp; x1, T2 const&amp; x2);
+ ...
+ template &lt;class T1, class T2,...class T<i>n</i>&gt;
+ explicit array(T1 const&amp; x1, T2 const&amp; x2,...T<i>n</i> const&amp; xn);
+
+ static void set_module_and_type();
+ static void set_module_and_type(char const* package_path = 0, char const* type_name = 0);
+ static void get_module_name();
+
+ 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&amp; repeats, long axis=0);
+
+ void setflat(object const&amp; flat);
+
+ void swapaxes(long axis1, long axis2);
+
+ str tostring() const;
+
+ void transpose(object const&amp; axes = object());
+
+ object view() const;
+ };
+}}}
+</pre>
+
+ <h4><a name="array-spec-observers" id="array-spec-observers"></a>Class
+ <code>array</code> observer functions</h4>
+ <pre>
+object factory();
+template &lt;class Sequence&gt;
+object factory(Sequence const&amp;);
+template &lt;class Sequence, class Typecode&gt;
+object factory(Sequence const&amp;, Typecode const&amp;, bool copy = true, bool savespace = false);
+template &lt;class Sequence, class Typecode, class Type&gt;
+object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;);
+template &lt;class Sequence, class Typecode, class Type, class Shape&gt;
+object factory(Sequence const&amp;, Typecode const&amp;, bool copy, bool savespace, Type const&amp;, Shape const&amp;);
+</pre>These functions map to the underlying array type's <code>array()</code>
+function family. They are not called "<code>array</code>" because of the C++
+limitation that you can't define a member function with the same name as its
+enclosing class.
+ <pre>
+template &lt;class Type&gt;
+array new_(Type const&amp;) const;
+</pre>This function maps to the underlying array type's <code>new()</code>
+function. It is not called "<code>new</code>" because that is a keyword in
+C++.
+
+ <h4><a name="array-spec-statics" id="array-spec-statics"></a>Class
+ <code>array</code> static functions</h4>
+ <pre>
+static void set_module_and_type(char const* package_path, char const* type_name);
+static void set_module_and_type();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>package_path</code> and
+ <code>type_name</code>, if supplied, is an <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Effects:</b> The first form sets the package path of the module
+ that supplies the type named by <code>type_name</code> to
+ <code>package_path</code>. The second form restores the <a href=
+ "#default_search">default search behavior</a>. 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
+ <code>set_module_and_type</code>.</dt>
+ </dl>
+ <pre>
+static std::string get_module_name()
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Returns the name of the module containing the class
+ that will be held by new <code>numeric::array</code> instances.</dt>
+ </dl>
+
+ <h2><a name="examples" id="examples"></a>Example</h2>
+ <pre>
+#include &lt;boost/python/numeric.hpp&gt;
+#include &lt;boost/python/tuple.hpp&gt;
+
+// sets the first element in a 2d numeric array
+void set_first_element(numeric::array&amp; y, double value)
+{
+ y[make_tuple(0,0)] = value;
+}
+</pre>
+
+ <p>Revised 07 October, 2006</p>
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002-2006.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/object.html b/libs/python/doc/v2/object.html
new file mode 100644
index 000000000..8df8ef5f8
--- /dev/null
+++ b/libs/python/doc/v2/object.html
@@ -0,0 +1,1121 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/object.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/object.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#types">Types</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#slice_nil-spec">slice_nil</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#const_attribute_policies-spec">Class
+ <code>const_attribute_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#const_attribute_policies-spec-synopsis">Class
+ <code>const_attribute_policies</code> synopsis</a></dt>
+
+ <dt><a href="#const_attribute_policies-spec-statics">Class
+ <code>const_attribute_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#attribute_policies-spec">Class
+ <code>attribute_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#attribute_policies-spec-synopsis">Class
+ <code>attribute_policies</code> synopsis</a></dt>
+
+ <dt><a href="#attribute_policies-spec-statics">Class
+ <code>attribute_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#const_objattribute_policies-spec">Class
+ <code>const_objattribute_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#const_objattribute_policies-spec-synopsis">Class
+ <code>const_objattribute_policies</code> synopsis</a></dt>
+
+ <dt><a href="#const_objattribute_policies-spec-statics">Class
+ <code>const_objattribute_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#objattribute_policies-spec">Class
+ <code>objattribute_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#objattribute_policies-spec-synopsis">Class
+ <code>objattribute_policies</code> synopsis</a></dt>
+
+ <dt><a href="#objattribute_policies-spec-statics">Class
+ <code>objattribute_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#const_item_policies-spec">Class
+ <code>const_item_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#const_item_policies-spec-synopsis">Class
+ <code>const_item_policies</code> synopsis</a></dt>
+
+ <dt><a href="#const_item_policies-spec-statics">Class
+ <code>const_item_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#item_policies-spec">Class
+ <code>item_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#item_policies-spec-synopsis">Class
+ <code>item_policies</code> synopsis</a></dt>
+
+ <dt><a href="#item_policies-spec-statics">Class
+ <code>item_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#const_slice_policies-spec">Class
+ <code>const_slice_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#const_slice_policies-spec-synopsis">Class
+ <code>const_slice_policies</code> synopsis</a></dt>
+
+ <dt><a href="#const_slice_policies-spec-statics">Class
+ <code>const_slice_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#slice_policies-spec">Class
+ <code>slice_policies</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#slice_policies-spec-synopsis">Class
+ <code>slice_policies</code> synopsis</a></dt>
+
+ <dt><a href="#slice_policies-spec-statics">Class
+ <code>slice_policies</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#object_operators-spec">Class
+ <code>object_operators</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#object_operators-spec-synopsis">Class
+ <code>object_operators</code> synopsis</a></dt>
+
+ <dt><a href="#object_operators-spec-observers">Class
+ <code>object_operators</code> observer functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#object-spec">Class <code>object</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#object-spec-synopsis">Class <code>object</code>
+ synopsis</a></dt>
+
+ <dt><a href="#object-spec-ctors">Class <code>object</code>
+ constructors and destructor</a></dt>
+
+ <dt><a href="#object-spec-modifiers">Class template
+ <code>object</code> modifier functions</a></dt>
+
+ <dt><a href="#object-spec-observers">Class template
+ <code>object</code> observer functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#proxy-spec">Class template
+ <code>proxy</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#proxy-spec-synopsis">Class template
+ <code>proxy</code> synopsis</a></dt>
+
+ <dt><a href="#proxy-spec-modifiers">Class template
+ <code>proxy</code> modifier functions</a></dt>
+
+ <dt><a href="#proxy-spec-observers">Class template
+ <code>proxy</code> observer functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#del-spec">del</a></dt>
+
+ <dt><a href="#comparisons-spec">comparisons</a></dt>
+
+ <dt><a href="#binary-spec">binary operations</a></dt>
+
+ <dt><a href="#assignment-spec">assignment operations</a></dt>
+
+ </dl>
+
+ <dl class="page-index">
+ <dt><a href="#object_operators-spec">operators</a></dt>
+ </dl>
+
+ <dl class="page-index">
+ <dt><a href="#len-spec">len()</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes the generic Python object wrapper class <code>object</code>,
+ and related classes. In order to avoid some potenential problems with
+ argument-dependent lookup and the generalized operators defined on
+ <code>object</code>, all these facilities are defined in
+ <code>namespace&nbsp;boost::python::api</code>, and <code>object</code>
+ is imported into <code>namespace&nbsp;boost::python</code> with a
+ <i>using-declaration</i>.</p>
+
+ <h2><a name="types"></a>Types</h2>
+
+ <p><a name="slice_nil-spec"></a></p>
+<pre>
+class slice_nil;
+static const _ = slice_nil();
+</pre>
+ A type that can be used to get the effect of leaving out an index in a
+ Python slice expression:
+<pre>
+&gt;&gt;&gt; x[:-1]
+&gt;&gt;&gt; x[::-1]
+</pre>
+ C++ equivalent:
+<pre>
+x.slice(_,-1)
+x[slice(_,_,-1)]
+</pre>
+
+ <h2><a name="classes"></a>Classes</h2>
+ <!-- begin -->
+
+ <h3><a name="const_attribute_policies-spec"></a>Class
+ <code>const_attribute_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an attribute
+ access to a <code>const&nbsp;object</code>.</p>
+
+ <h4><a name="const_attribute_policies-spec-synopsis"></a>Class
+ <code>const_attribute_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct const_attribute_policies
+ {
+ typedef char const* key_type;
+ static object get(object const&amp; target, char const* key);
+ };
+}}}
+</pre>
+
+ <h4><a name="const_attribute_policies-spec-statics"></a>Class
+ <code>const_attribute_policies</code> static functions</h4>
+<pre>
+static object get(object const&amp; target, char const* key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>key</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Effects:</b> accesses the attribute of <code>target</code> named
+ by <code>key</code>.</dt>
+
+ <dt><b>Returns:</b> An <code>object</code> managing the result of the
+ attribute access.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+
+ <h3><a name="attribute_policies-spec"></a>Class
+ <code>attribute_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an attribute
+ access to a mutable <code>object</code>.</p>
+
+ <h4><a name="attribute_policies-spec-synopsis"></a>Class
+ <code>attribute_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct attribute_policies : const_attribute_policies
+ {
+ static object const&amp; set(object const&amp; target, char const* key, object const&amp; value);
+ static void del(object const&amp;target, char const* key);
+ };
+}}}
+</pre>
+
+ <h4><a name="attribute_policies-spec-statics"></a>Class
+ <code>attribute_policies</code> static functions</h4>
+<pre>
+static object const&amp; set(object const&amp; target, char const* key, object const&amp; value);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>key</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Effects:</b> sets the attribute of <code>target</code> named by
+ <code>key</code> to <code>value</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+<pre>
+static void del(object const&amp;target, char const* key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>key</code> is an <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Effects:</b> deletes the attribute of <code>target</code> named
+ by <code>key</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+ <!-- end -->
+ <!-- begin -->
+
+ <h3><a name="const_objattribute_policies-spec"></a>Class
+ <code>const_objattribute_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an attribute
+ access to a <code>const&nbsp;object</code> when the attribute name is
+ given as a <code>const&nbsp;object</code>.</p>
+
+ <h4><a name="const_objattribute_policies-spec-synopsis"></a>Class
+ <code>const_objattribute_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct const_objattribute_policies
+ {
+ typedef object const& key_type;
+ static object get(object const&amp; target, object const& key);
+ };
+}}}
+</pre>
+
+ <h4><a name="const_objattribute_policies-spec-statics"></a>Class
+ <code>const_objattribute_policies</code> static functions</h4>
+<pre>
+static object get(object const&amp; target, object const& key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>key</code> is an <code>object</code>
+ holding a string.</dt>
+
+ <dt><b>Effects:</b> accesses the attribute of <code>target</code> named
+ by <code>key</code>.</dt>
+
+ <dt><b>Returns:</b> An <code>object</code> managing the result of the
+ attribute access.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+
+ <h3><a name="objattribute_policies-spec"></a>Class
+ <code>objattribute_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an attribute
+ access to a mutable <code>object</code> when the attribute name is
+ given as a <code>const&nbsp;object</code>.</p>
+
+ <h4><a name="objattribute_policies-spec-synopsis"></a>Class
+ <code>objattribute_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct objattribute_policies : const_objattribute_policies
+ {
+ static object const&amp; set(object const&amp; target, object const& key, object const&amp; value);
+ static void del(object const&amp;target, object const& key);
+ };
+}}}
+</pre>
+
+ <h4><a name="objattribute_policies-spec-statics"></a>Class
+ <code>objattribute_policies</code> static functions</h4>
+<pre>
+static object const&amp; set(object const&amp; target, object const& key, object const&amp; value);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>key</code> is an <code>object</code>
+ holding a string.</dt>
+
+ <dt><b>Effects:</b> sets the attribute of <code>target</code> named by
+ <code>key</code> to <code>value</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+<pre>
+static void del(object const&amp;target, object const& key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>key</code> is an <code>object</code>
+ holding a string.</dt>
+
+ <dt><b>Effects:</b> deletes the attribute of <code>target</code> named
+ by <code>key</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+ <!-- end -->
+ <!-- begin -->
+
+ <h3><a name="const_item_policies-spec"></a>Class
+ <code>const_item_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an item access
+ (via the Python bracket operators <code>[]</code>) to a
+ <code>const&nbsp;object</code>.</p>
+
+ <h4><a name="const_item_policies-spec-synopsis"></a>Class
+ <code>const_item_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct const_item_policies
+ {
+ typedef object key_type;
+ static object get(object const&amp; target, object const&amp; key);
+ };
+}}}
+</pre>
+
+ <h4><a name="const_item_policies-spec-statics"></a>Class
+ <code>const_item_policies</code> static functions</h4>
+<pre>
+static object get(object const&amp; target, object const&amp; key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> accesses the item of <code>target</code> specified
+ by <code>key</code>.</dt>
+
+ <dt><b>Returns:</b> An <code>object</code> managing the result of the
+ item access.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+
+ <h3><a name="item_policies-spec"></a>Class
+ <code>item_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an item access
+ (via the Python bracket operators <code>[]</code>) to a mutable
+ <code>object</code>.</p>
+
+ <h4><a name="item_policies-spec-synopsis"></a>Class
+ <code>item_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct item_policies : const_item_policies
+ {
+ static object const&amp; set(object const&amp; target, object const&amp; key, object const&amp; value);
+ static void del(object const&amp; target, object const&amp; key);
+ };
+}}}
+</pre>
+
+ <h4><a name="item_policies-spec-statics"></a>Class
+ <code>item_policies</code> static functions</h4>
+<pre>
+static object const&amp; set(object const&amp; target, object const&amp; key, object const&amp; value);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> sets the item of <code>target</code> specified by
+ <code>key</code> to <code>value</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+<pre>
+static void del(object const&amp; target, object const&amp; key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> deletes the item of <code>target</code> specified
+ by <code>key</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+ <!-- end -->
+ <!-- begin -->
+
+ <h3><a name="const_slice_policies-spec"></a>Class
+ <code>const_slice_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an slice access
+ (via the Python slice notation
+ <code>[</code><i>x</i><code>:</code><i>y</i><code>]</code>) to a
+ <code>const&nbsp;object</code>.</p>
+
+ <h4><a name="const_slice_policies-spec-synopsis"></a>Class
+ <code>const_slice_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct const_slice_policies
+ {
+ typedef std::pair&lt;handle&lt;&gt;, handle&lt;&gt; &gt; key_type;
+ static object get(object const&amp; target, key_type const&amp; key);
+ };
+}}}
+</pre>
+
+ <h4><a name="const_slice_policies-spec-statics"></a>Class
+ <code>const_slice_policies</code> static functions</h4>
+<pre>
+static object get(object const&amp; target, key_type const&amp; key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> accesses the slice of <code>target</code> specified
+ by <code>key</code>.</dt>
+
+ <dt><b>Returns:</b> An <code>object</code> managing the result of the
+ slice access.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+
+ <h3><a name="slice_policies-spec"></a>Class
+ <code>slice_policies</code></h3>
+
+ <p>The policies which are used for proxies representing an slice access
+ to a mutable <code>object</code>.</p>
+
+ <h4><a name="slice_policies-spec-synopsis"></a>Class
+ <code>slice_policies</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ struct slice_policies : const_slice_policies
+ {
+ static object const&amp; set(object const&amp; target, key_type const&amp; key, object const&amp; value);
+ static void del(object const&amp; target, key_type const&amp; key);
+ };
+}}}
+</pre>
+
+ <h4><a name="slice_policies-spec-statics"></a>Class
+ <code>slice_policies</code> static functions</h4>
+<pre>
+static object const&amp; set(object const&amp; target, key_type const&amp; key, object const&amp; value);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> sets the slice of <code>target</code> specified by
+ <code>key</code> to <code>value</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+<pre>
+static void del(object const&amp; target, key_type const&amp; key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> deletes the slice of <code>target</code> specified
+ by <code>key</code>.</dt>
+
+ <dt><b>Throws:</b> <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code> if a
+ Python exception is raised.</dt>
+ </dl>
+ <!-- end -->
+
+ <h3><a name="object_operators-spec"></a>Class template
+ <code>object_operators&lt;U&gt;</code></h3>
+
+ <p>This is the base class of <code>object</code> and its
+ <code>proxy</code> template used to supply common interface: member
+ functions, and operators which must be defined within the class body. Its
+ template parameter <code>U</code> is expected to be a class derived from
+ <code>object_operators&lt;U&gt;</code>. In practice users should never
+ use this class directly, but it is documented here because it supplies
+ important interface to <code>object</code> and its proxies.</p>
+
+ <h4><a name="object_operators-spec-synopsis"></a>Class template
+ <code>object_operators</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ template &lt;class U&gt;
+ class object_operators
+ {
+ public:
+ // function call
+ //
+ object operator()() const;
+
+ template &lt;class A0&gt;
+ object operator()(A0 const&amp;) const;
+ template &lt;class A0, class A1&gt;
+ object operator()(A0 const&amp;, A1 const&amp;) const;
+ ...
+ template &lt;class A0, class A1,...class An&gt;
+ object operator()(A0 const&amp;, A1 const&amp;,...An const&amp;) const;
+
+ detail::args_proxy operator* () const;
+ object operator()(detail::args_proxy const &amp;args) const;
+ object operator()(detail::args_proxy const &amp;args,
+ detail::kwds_proxy const &amp;kwds) const;
+
+ // truth value testing
+ //
+ typedef unspecified bool_type;
+ operator bool_type() const;
+
+ // Attribute access
+ //
+ proxy&lt;const_object_attribute&gt; attr(char const*) const;
+ proxy&lt;object_attribute&gt; attr(char const*);
+ proxy&lt;const_object_objattribute&gt; attr(object const&) const;
+ proxy&lt;object_objattribute&gt; attr(object const&);
+
+ // item access
+ //
+ template &lt;class T&gt;
+ proxy&lt;const_object_item&gt; operator[](T const&amp; key) const;
+
+ template &lt;class T&gt;
+ proxy&lt;object_item&gt; operator[](T const&amp; key);
+
+ // slicing
+ //
+ template &lt;class T, class V&gt;
+ proxy&lt;const_object_slice&gt; slice(T const&amp; start, V const&amp; end) const
+
+ template &lt;class T, class V&gt;
+ proxy&lt;object_slice&gt; slice(T const&amp; start, V const&amp; end);
+ };
+}}}
+</pre>
+
+ <h4><a name="object_operators-spec-observers"></a>Class template
+ <code>object_operators</code> observer functions</h4>
+<pre>
+object operator()() const;
+template &lt;class A0&gt;
+object operator()(A0 const&amp;) const;
+template &lt;class A0, class A1&gt;
+object operator()(A0 const&amp;, A1 const&amp;) const;
+...
+template &lt;class A0, class A1,...class An&gt;
+object operator()(A0 const&amp; a1, A1 const&amp; a2,...An const&amp; aN) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ call&lt;object&gt;(object(*static_cast&lt;U*&gt;(this)).ptr(), a1,
+ a2,...aN)</dt>
+ </dl>
+
+<pre>
+object operator()(detail::args_proxy const &amp;args) const;
+</pre>
+<dl class="function-semantics">
+ <dt><b>Effects:</b>
+ call object with arguments given by the tuple <varname>args</varname></dt>
+</dl>
+<pre>
+object operator()(detail::args_proxy const &amp;args,
+ detail::kwds_proxy const &amp;kwds) const;
+</pre>
+<dl class="function-semantics">
+ <dt><b>Effects:</b>
+ call object with arguments given by the tuple <varname>args</varname>, and named
+ arguments given by the dictionary <varname>kwds</varname></dt>
+</dl>
+
+
+<pre>
+operator bool_type() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Tests truth value of <code>*this</code>.</dt>
+
+ <dt><b>Returns:</b>
+ call&lt;object&gt;(object(*static_cast&lt;U*&gt;(this)).ptr(), a1,
+ a2,...aN)</dt>
+ </dl>
+<pre>
+proxy&lt;const_object_attribute&gt; attr(char const* name) const;
+proxy&lt;object_attribute&gt; attr(char const* name);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> name is an <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Effects:</b> accesses the named attribute of
+ <code>*this</code>.</dt>
+
+ <dt><b>Returns:</b> a proxy object which binds
+ <code>object(*static_cast&lt;U*&gt;(this))</code> as its target, and
+ <code>name</code> as its key.</dt>
+ </dl>
+<pre>
+proxy&lt;const_object_objattribute&gt; attr(const object& name) const;
+proxy&lt;object_objattribute&gt; attr(const object& name);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> name is a <code>object</code> holding a string.</dt>
+
+ <dt><b>Effects:</b> accesses the named attribute of
+ <code>*this</code>.</dt>
+
+ <dt><b>Returns:</b> a proxy object which binds
+ <code>object(*static_cast&lt;U*&gt;(this))</code> as its target, and
+ <code>name</code> as its key.</dt>
+ </dl>
+<pre>
+template &lt;class T&gt;
+proxy&lt;const_object_item&gt; operator[](T const&amp; key) const;
+template &lt;class T&gt;
+proxy&lt;object_item&gt; operator[](T const&amp; key);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> accesses the item of <code>*this</code> indicated
+ by <code>key</code>.</dt>
+
+ <dt><b>Returns:</b> a proxy object which binds
+ <code>object(*static_cast&lt;U*&gt;(this))</code> as its target, and
+ <code>object(key)</code> as its key.</dt>
+ </dl>
+<pre>
+template &lt;class T, class V&gt;
+proxy&lt;const_object_slice&gt; slice(T const&amp; start; start, V const&amp; finish) const
+template &lt;class T, class V&gt;
+proxy&lt;object_slice&gt; slice(T const&amp; start; start, V const&amp; finish);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> accesses the slice of <code>*this</code> indicated
+ by <code>std::make_pair(object(start), object(finish))</code>.</dt>
+
+ <dt><b>Returns:</b> a proxy object which binds
+ <code>object(*static_cast&lt;U*&gt;(this))</code> as its target, and
+ <code>std::make_pair(object(start), object(finish))</code> as its
+ key.</dt>
+ </dl>
+ <!-- -->
+
+ <h3><a name="object-spec"></a>Class <code>object</code></h3>
+
+ <p>The intention is that <code>object</code> 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
+ <code>object</code>'s interface is provided by its base class
+ <code><a
+ href="#object_operators-spec">object_operators</a>&lt;object&gt;</code>,
+ and the <a href="#functions">free functions</a> defined in this
+ header.
+</p>
+
+ <h4><a name="object-spec-synopsis"></a>Class <code>object</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ class object : public object_operators&lt;object&gt;
+ {
+ public:
+ object();
+
+ object(object const&amp;);
+
+ template &lt;class T&gt;
+ explicit object(T const&amp; x);
+
+ ~object();
+
+ object&amp; operator=(object const&amp;);
+
+ PyObject* ptr() const;
+
+ bool is_none() const;
+ };
+}}}
+</pre>
+
+ <h4><a name="object-spec-ctors"></a>Class <code>object</code>
+ constructors and destructor</h4>
+<pre>
+object();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Constructs an object managing a reference to the
+ Python <code>None</code> object.</dt>
+
+ <dt><b>Throws:</b> nothing.</dt>
+ </dl>
+<pre>
+template &lt;class T&gt;
+explicit object(T const&amp; x);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> converts <code>x</code> to python and manages a
+ reference to it.</dt>
+
+ <dt><b>Throws:</b> <code>error_already_set</code> and sets a Python
+ <code>TypeError</code> exception if no such conversion is
+ possible.</dt>
+ </dl>
+<pre>
+~object();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> decrements the reference count of the
+ internally-held object.</dt>
+ </dl>
+
+ <h4><a name="object-spec-modifiers"></a>Class <code>object</code>
+ modifiers</h4>
+<pre>
+object&amp; operator=(object const&amp; rhs);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> increments the reference count of the object held
+ by <code>rhs</code> and decrements the reference count of the object
+ held by <code>*this</code>.</dt>
+ </dl>
+
+ <h4><a name="object-spec-observers"></a>Class <code>object</code>
+ observers</h4>
+<pre>
+PyObject* ptr() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> a pointer to the internally-held Python
+ object.</dt>
+ </dl>
+
+<pre>
+bool is_none() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> result of (ptr() == Py_None)</dt>
+ </dl>
+ <!-- -->
+
+ <h3><a name="proxy-spec"></a>Class template <code>proxy</code></h3>
+
+ <p>This template is instantiated with various Policies described in this
+ document in order to implement attribute, item, and slice access for
+ <code>object</code>. It stores an object of type
+ <code>Policies::key_type</code>.</p>
+
+ <h4><a name="proxy-spec-synopsis"></a>Class template <code>proxy</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace api
+{
+ template &lt;class Policies&gt;
+ class proxy : public object_operators&lt;proxy&lt;Policies&gt; &gt;
+ {
+ public:
+ operator object() const;
+
+ proxy const&amp; operator=(proxy const&amp;) const;
+ template &lt;class T&gt;
+ inline proxy const&amp; operator=(T const&amp; rhs) const;
+
+ void del() const;
+
+ template &lt;class R&gt;
+ proxy operator+=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator-=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator*=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator/=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator%=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator&lt;&lt;=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator&gt;&gt;=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator&amp;=(R const&amp; rhs);
+ template &lt;class R&gt;
+ proxy operator|=(R const&amp; rhs);
+ };
+}}}
+</pre>
+
+ <h4><a name="proxy-spec-observers"></a>Class template <code>proxy</code>
+ observer functions</h4>
+<pre>
+operator object() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> applies
+ <code>Policies::get(</code><i>target</i><code>,</code>&nbsp;<i>key</i>
+ <code>)</code> with the proxy's target and key objects.</dt>
+ </dl>
+
+ <h4><a name="proxy-spec-modifiers"></a>Class template <code>proxy</code>
+ modifier functions</h4>
+<pre>
+proxy const&amp; operator=(proxy const&amp; rhs) const;
+template &lt;class T&gt;
+inline proxy const&amp; operator=(T const&amp; rhs) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>Policies::set(</code><i>target</i><code>,</code>&nbsp;<i>key</i>
+ <code>,&nbsp;object(rhs))</code> with the proxy's target and key
+ objects.</dt>
+ </dl>
+<pre>
+template &lt;class R&gt;
+proxy operator+=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator-=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator*=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator/=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator%=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator&lt;&lt;=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator&gt;&gt;=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator&amp;=(R const&amp; rhs);
+template &lt;class R&gt;
+proxy operator|=(R const&amp; rhs);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> for a given operator@=,
+ <code>object(*this)&nbsp;@=&nbsp;rhs;</code></dt>
+ <dt><b>Returns:</b> <code>*this</code></dt>
+ </dl>
+<pre>
+void del() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>Policies::del(</code><i>target</i><code>,</code>&nbsp;<i>key</i>
+ <code>)</code> with the proxy's target and key objects.</dt>
+ </dl>
+ <!-- -->
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name="del-spec"></a>template &lt;class T&gt;
+void del(proxy&lt;T&gt; const&amp; x);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> x.del()</dt>
+ </dl>
+<pre>
+<a name="comparisons-spec"></a>
+template&lt;class L,class R&gt; object operator&gt;(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator&gt;=(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator&lt;(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator&lt;=(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator==(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator!=(L const&amp;l,R const&amp;r);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> returns the result of applying the operator to
+ <code>object(l)</code> and <code>object(r)</code>, respectively, in
+ Python.</dt>
+ </dl>
+<pre>
+<a name="binary-spec"></a>
+template&lt;class L,class R&gt; object operator+(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator-(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator*(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator/(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator%(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator&lt;&lt;(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator&gt;&gt;(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator&amp;(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator^(L const&amp;l,R const&amp;r);
+template&lt;class L,class R&gt; object operator|(L const&amp;l,R const&amp;r);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> returns the result of applying the operator to
+ <code>object(l)</code> and <code>object(r)</code>, respectively, in
+ Python.</dt>
+ </dl>
+<pre>
+<a name="assignment-spec"></a>
+template&lt;class R&gt; object&amp; operator+=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator-=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator*=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator/=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator%=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator&lt;&lt;=(object&amp;l,R const&amp;r)
+template&lt;class R&gt; object&amp; operator&gt;&gt;=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator&amp;=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator^=(object&amp;l,R const&amp;r);
+template&lt;class R&gt; object&amp; operator|=(object&amp;l,R const&amp;r);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> assigns to l the result of applying the
+ corresponding Python inplace operator to <code>l</code> and
+ <code>object(r)</code>, respectively.</dt>
+
+ <dt><b>Returns:</b> <code>l</code>.</dt>
+ </dl>
+
+<pre>
+inline long len(object const&amp; obj);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> PyObject_Length(obj.ptr()) </dt>
+ <dt><b>Returns:</b> len() of object.</dt>
+ </dl>
+
+<h2><a name="examples"></a>Example</h2>
+ Python code:
+<pre>
+def sum_items(seq):
+ result = 0
+ for x in seq:
+ result += x
+ return result
+</pre>
+ C++ version:
+<pre>
+object sum_items(object seq)
+{
+ object result = object(0);
+ for (int i = 0; i &lt; len(seq); ++i)
+ result += seq[i];
+ return result;
+}
+</pre>
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 15 March, 2010
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2008.</i></p>
+ </body>
+</html>
diff --git a/libs/python/doc/v2/opaque.html b/libs/python/doc/v2/opaque.html
new file mode 100644
index 000000000..fed1d446f
--- /dev/null
+++ b/libs/python/doc/v2/opaque.html
@@ -0,0 +1,138 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright 2003..2006 Haufe Mediengruppe. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/opaque_pointer_converter.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/opaque_pointer_converter.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#opaque-spec">Class template
+ <code>opaque&lt;Pointee&gt;</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#opaque-spec-synopsis">Class template
+ <code>opaque</code> synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#macros">Macros</a></dt>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">Macro
+ <code>BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</code></a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#see-also">See Also</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="opaque-spec"></a>Class template
+ <code>opaque&lt;P&gt;</code></h3>
+
+ <p><code>opaque&lt;&gt;</code> registers itself as a converter from
+ Python objects to pointers to undefined types and vice versa.</p>
+
+ <h4><a name="opaque-spec-synopsis"></a>Class template
+ <code>opaque</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template&lt;class Pointee&gt;
+ struct opaque
+ {
+ opaque();
+ };
+}}
+</pre>
+
+ <h4><a name="opaque-spec-constructor"></a>Class template
+ <code>opaque</code> constructor</h4>
+<pre>
+opaque();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <ul>
+ <li>Registers the instance as a
+ <a href="lvalue_from_pytype.html#lvalue_from_pytype-spec"> <code>lvalue_from_pytype</code></a>
+ converter from Python objects into opaque pointers.</p>
+ <p>The Python Objects created are named after the type pointed to
+ by the opaque pointer being wrapped.</p></li>
+ <li>Registers the instance as a
+ <a href="to_python_converter.html#to_python_converter-spec"> <code>to_python_converter</code></a>
+ from opaque pointers to Python objects.</p></li>
+ </ul>
+ <p>If there is already an instance registered by another module, this
+ instance doesn't try to register again in order to avoid warnings
+ about multiple registrations.</p>
+
+ <h4>Note</h4>
+ <p>Normally only a single instance of this class is created for every
+ Pointee.</p>
+ </dt>
+ </dl>
+
+ <h2><a name="macros"></a>Macros</h2>
+
+ <h3><a name="BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec"></a>
+ Macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)</h3>
+ <p>This macro must be used to define specializations of the
+ <a href="type_id.html#type_id-spec">type_id</a> function
+ which can't be instantiated for incomplete types.</p>
+ <h4>Note</h4>
+ <p>The macro must be invoked in every translation unit which uses the
+ opaque converter.</p>
+
+ <h2><a name="see-also"></a>See Also</h2>
+ <p>
+ <a href="return_opaque_pointer.html">return_opaque_pointer</a>
+ </p>
+
+ <p>Revised
+ 10 September, 2006
+ </p>
+
+ <p><i>&copy; Copyright 2003..2006 Haufe Mediengruppe. All Rights
+ Reserved.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/operators.html b/libs/python/doc/v2/operators.html
new file mode 100644
index 000000000..69740243f
--- /dev/null
+++ b/libs/python/doc/v2/operators.html
@@ -0,0 +1,921 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/operators.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/operators.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#self_t-spec">Class
+ <code>self_ns::self_t</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#self_t-spec-synopsis">Class <code>self_t</code>
+ synopsis</a></dt>
+
+ <dt><a href="#self_t-spec-inplace">Class <code>self_t</code>
+ inplace operators</a></dt>
+
+ <dt><a href="#self_t-spec-comparisons">Class
+ <code>self_t</code> comparison functions</a></dt>
+
+ <dt><a href="#self_t-spec-ops">Class <code>self_t</code>
+ non-member operations</a></dt>
+
+ <dt><a href="#self_t-spec-value-unary-ops">Class
+ <code>self_t</code> unary operations</a></dt>
+
+ <dt><a href="#self_t-spec-value-ops">Class
+ <code>self_t</code> value operations</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#other-spec">Class template
+ <code>other</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#other-spec-synopsis">Class <code>other</code>
+ synopsis</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#operator_-spec">Class template
+ <code>operator_</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#operator_-spec-synopsis">Class
+ <code>operator_</code> synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#objects">Objects</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#self-spec">self</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/operators.hpp&gt;</code> provides types and
+ functions for automatically generating Python <a href=
+ "http://www.python.org/doc/ref/specialnames.html">special methods</a>
+ from the corresponding C++ constructs. Most of these constructs are
+ operator expressions, hence the name. To use the facility, substitute the
+ <code><a href="#self-spec">self</a></code> object for an object of the
+ class type being wrapped in the expression to be exposed, and pass the
+ result to <a href=
+ "class.html#class_-spec-modifiers">class_&lt;&gt;::def()</a>. Much of
+ what is exposed in this header should be considered part of the
+ implementation, so is not documented in detail here.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="self_t-spec"></a>Class <code>self_ns::self_t</code></h3>
+
+ <p><code>self_ns::self_t</code> is the actual type of the <a href=
+ "#self-spec"><code>self</code></a> object. The library isolates
+ <code>self_t</code> in its own namespace, <code>self_ns</code>, 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 <code>self_t</code> directly.</p>
+
+ <h4><a name="self_t-spec-synopsis"></a>Class <code>self_ns::self_t</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace self_ns {
+{
+ <i>unspecified-type-declaration</i> self_t;
+
+ // inplace operators
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator+=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator-=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator*=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator/=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator%=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;&gt;=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;&lt;=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&amp;=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator^=(self_t, T);
+ template &lt;class T&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator|=(self_t, T);
+
+ // comparisons
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator==(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator!=(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;=(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;=(L const&amp;, R const&amp;);
+
+ // non-member operations
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator+(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator-(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator*(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator/(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator%(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;&gt;(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;&lt;(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&amp;(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator^(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator|(L const&amp;, R const&amp;);
+ template &lt;class L, class R&gt; <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; pow(L const&amp;, R const&amp;);
+
+ // unary operations
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator-(self_t);
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator+(self_t);
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator~(self_t);
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator!(self_t);
+
+ // value operations
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; int_(self_t);
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; long_(self_t);
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; float_(self_t);
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; complex_(self_t);
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; str(self_t);
+
+ <a href=
+"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; repr(self_t);
+
+}}};
+</pre>
+ The tables below describe the methods generated when the results of the
+ expressions described are passed as arguments to <a href=
+ "class.html#class_-spec-modifiers">class_&lt;&gt;::def()</a>.
+ <code><b>x</b></code> is an object of the class type being wrapped.
+
+ <h4><a name="self_t-spec-inplace"></a>Class <code>self_t</code> inplace
+ operators</h4>
+ In the table below, If <code><b>r</b></code> is an object of type
+ <code><a href="#other-spec">other</a>&lt;T&gt;</code>,
+ <code><b>y</b></code> is an object of type <code>T</code>; otherwise,
+ <code><b>y</b></code> is an object of the same type as
+ <code><b>r</b></code>.
+
+ <table border="1" summary="self_t inplace operators">
+ <tr>
+ <th>C++ Expression</th>
+
+ <th>Python Method Name</th>
+
+ <th>C++ Implementation</th>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;+=&nbsp;r</code></td>
+
+ <td><code>__iadd__</code></td>
+
+ <td><code>x&nbsp;+=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;-=&nbsp;r</code></td>
+
+ <td><code>__isub__</code></td>
+
+ <td><code>x&nbsp;-=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;*=&nbsp;r</code></td>
+
+ <td><code>__imul__</code></td>
+
+ <td><code>x&nbsp;*=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;/=&nbsp;r</code></td>
+
+ <td><code>__idiv__</code></td>
+
+ <td><code>x&nbsp;/=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;%=&nbsp;r</code></td>
+
+ <td><code>__imod__</code></td>
+
+ <td><code>x&nbsp;%=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&gt;&gt;=&nbsp;r</code></td>
+
+ <td><code>__irshift__</code></td>
+
+ <td><code>x&nbsp;&gt;&gt;=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&lt;&lt;=&nbsp;r</code></td>
+
+ <td><code>__ilshift__</code></td>
+
+ <td><code>x&nbsp;&lt;&lt;=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&amp;=&nbsp;r</code></td>
+
+ <td><code>__iand__</code></td>
+
+ <td><code>x&nbsp;&amp;=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;^=&nbsp;r</code></td>
+
+ <td><code>__ixor__</code></td>
+
+ <td><code>x&nbsp;^=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;|=&nbsp;r</code></td>
+
+ <td><code>__ior__</code></td>
+
+ <td><code>x&nbsp;|=&nbsp;y</code></td>
+ </tr>
+ </table>
+
+ <h4><a name="self_t-spec-comparisons"></a>Class <code>self_t</code>
+ comparison functions</h4>
+ In the tables below, if <code><b>r</b></code> is of type <code><a href=
+ "#self_t-spec">self_t</a></code>, <code><b>y</b></code> is an object of
+ the same type as <code>x</code>; <br>
+ if <code><b>l</b></code> or <code><b>r</b></code> is an object of type
+ <code><a href="#other-spec">other</a>&lt;T&gt;</code>,
+ <code><b>y</b></code> is an object of type <code>T</code>; <br>
+ otherwise, <code><b>y</b></code> is an object of the same type as
+ <code><b>l</b></code> or <code><b>r</b></code>.<br>
+ <code><b>l</b></code> is never of type <code><a href=
+ "#self_t-spec">self_t</a></code>.
+
+ <p>The column of <b>Python Expressions</b> illustrates the expressions
+ that will be supported in Python for objects convertible to the types of
+ <code>x</code> and <code>y</code>. The secondary operation arises due to
+ Python's <a href=
+ "http://www.python.org/doc/ref/customization.html#l2h-89">reflection
+ rules</a> for rich comparison operators, and are only used when the
+ corresponding operation is not defined as a method of the <code>y</code>
+ object.</p>
+
+ <table border="1" summary="self_t comparison functions">
+ <tr>
+ <th>C++ Expression</th>
+
+ <th>Python Method Name</th>
+
+ <th>C++ Implementation</th>
+
+ <th>Python Expressions<br>
+ (primary, secondary)</th>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;==&nbsp;r</code></td>
+
+ <td><code>__eq__</code></td>
+
+ <td><code>x&nbsp;==&nbsp;y</code></td>
+
+ <td><code>x&nbsp;==&nbsp;y, y&nbsp;==&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;==&nbsp;self</code></td>
+
+ <td><code>__eq__</code></td>
+
+ <td><code>y&nbsp;==&nbsp;x</code></td>
+
+ <td><code>y&nbsp;==&nbsp;x, x&nbsp;==&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;!=&nbsp;r</code></td>
+
+ <td><code>__ne__</code></td>
+
+ <td><code>x&nbsp;!=&nbsp;y</code></td>
+
+ <td><code>x&nbsp;!=&nbsp;y, y&nbsp;!=&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;!=&nbsp;self</code></td>
+
+ <td><code>__ne__</code></td>
+
+ <td><code>y&nbsp;!=&nbsp;x</code></td>
+
+ <td><code>y&nbsp;!=&nbsp;x, x&nbsp;!=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&lt;&nbsp;r</code></td>
+
+ <td><code>__lt__</code></td>
+
+ <td><code>x&nbsp;&lt;&nbsp;y</code></td>
+
+ <td><code>x&nbsp;&lt;&nbsp;y, y&nbsp;&gt;&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;&lt;&nbsp;self</code></td>
+
+ <td><code>__gt__</code></td>
+
+ <td><code>y&nbsp;&lt;&nbsp;x</code></td>
+
+ <td><code>y&nbsp;&gt;&nbsp;x, x&nbsp;&lt;&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&gt;&nbsp;r</code></td>
+
+ <td><code>__gt__</code></td>
+
+ <td><code>x&nbsp;&gt;&nbsp;y</code></td>
+
+ <td><code>x&nbsp;&gt;&nbsp;y, y&nbsp;&lt;&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;&gt;&nbsp;self</code></td>
+
+ <td><code>__lt__</code></td>
+
+ <td><code>y&nbsp;&gt;&nbsp;x</code></td>
+
+ <td><code>y&nbsp;&lt;&nbsp;x, x&nbsp;&gt;&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&lt;=&nbsp;r</code></td>
+
+ <td><code>__le__</code></td>
+
+ <td><code>x&nbsp;&lt;=&nbsp;y</code></td>
+
+ <td><code>x&nbsp;&lt;=&nbsp;y, y&nbsp;&gt;=&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;&lt;=&nbsp;self</code></td>
+
+ <td><code>__ge__</code></td>
+
+ <td><code>y&nbsp;&lt;=&nbsp;x</code></td>
+
+ <td><code>y&nbsp;&gt;=&nbsp;x, x&nbsp;&lt;=&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&gt;=&nbsp;r</code></td>
+
+ <td><code>__ge__</code></td>
+
+ <td><code>x&nbsp;&gt;=&nbsp;y</code></td>
+
+ <td><code>x&nbsp;&gt;=&nbsp;y, y&nbsp;&lt;=&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;&gt;=&nbsp;self</code></td>
+
+ <td><code>__le__</code></td>
+
+ <td><code>y&nbsp;&gt;=&nbsp;x</code></td>
+
+ <td><code>y&nbsp;&lt;=&nbsp;x, x&nbsp;&gt;=&nbsp;y</code></td>
+ </tr>
+ </table>
+
+ <h4><a name="self_t-spec-ops"></a>Class <code>self_t</code> non-member
+ operations</h4>
+ The operations whose names begin with "<code>__r</code>" below will only
+ be called if the left-hand operand does not already support the given
+ operation, as described <a href=
+ "http://www.python.org/doc/current/ref/numeric-types.html#l2h-152">here</a>.
+
+
+ <table border="1" summary="self_t non-member operations">
+ <tr>
+ <th>C++ Expression</th>
+
+ <th>Python Method Name</th>
+
+ <th>C++ Implementation</th>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;+&nbsp;r</code></td>
+
+ <td><code>__add__</code></td>
+
+ <td><code>x&nbsp;+&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;+&nbsp;self</code></td>
+
+ <td><code>__radd__</code></td>
+
+ <td><code>y&nbsp;+&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;-&nbsp;r</code></td>
+
+ <td><code>__sub__</code></td>
+
+ <td><code>x&nbsp;-&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;-&nbsp;self</code></td>
+
+ <td><code>__rsub__</code></td>
+
+ <td><code>y&nbsp;-&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;*&nbsp;r</code></td>
+
+ <td><code>__mul__</code></td>
+
+ <td><code>x&nbsp;*&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;*&nbsp;self</code></td>
+
+ <td><code>__rmul__</code></td>
+
+ <td><code>y&nbsp;*&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;/&nbsp;r</code></td>
+
+ <td><code>__div__</code></td>
+
+ <td><code>x&nbsp;/&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;/&nbsp;self</code></td>
+
+ <td><code>__rdiv__</code></td>
+
+ <td><code>y&nbsp;/&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;%&nbsp;r</code></td>
+
+ <td><code>__mod__</code></td>
+
+ <td><code>x&nbsp;%&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;%&nbsp;self</code></td>
+
+ <td><code>__rmod__</code></td>
+
+ <td><code>y&nbsp;%&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&gt;&gt;&nbsp;r</code></td>
+
+ <td><code>__rshift__</code></td>
+
+ <td><code>x&nbsp;&gt;&gt;&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;&gt;&gt;&nbsp;self</code></td>
+
+ <td><code>__rrshift__</code></td>
+
+ <td><code>y&nbsp;&gt;&gt;&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&lt;&lt;&nbsp;r</code></td>
+
+ <td><code>__lshift__</code></td>
+
+ <td><code>x&nbsp;&lt;&lt;&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;&lt;&lt;&nbsp;self</code></td>
+
+ <td><code>__rlshift__</code></td>
+
+ <td><code>y&nbsp;&lt;&lt;&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;&amp;&nbsp;r</code></td>
+
+ <td><code>__and__</code></td>
+
+ <td><code>x&nbsp;&amp;&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;&amp;&nbsp;self</code></td>
+
+ <td><code>__rand__</code></td>
+
+ <td><code>y&nbsp;&amp;&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;^&nbsp;r</code></td>
+
+ <td><code>__xor__</code></td>
+
+ <td><code>x&nbsp;^&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;^&nbsp;self</code></td>
+
+ <td><code>__rxor__</code></td>
+
+ <td><code>y&nbsp;^&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>self&nbsp;|&nbsp;r</code></td>
+
+ <td><code>__or__</code></td>
+
+ <td><code>x&nbsp;|&nbsp;y</code></td>
+ </tr>
+
+ <tr>
+ <td><code>l&nbsp;|&nbsp;self</code></td>
+
+ <td><code>__ror__</code></td>
+
+ <td><code>y&nbsp;|&nbsp;x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>pow(self,&nbsp;r)</code></td>
+
+ <td><code>__pow__</code></td>
+
+ <td><code>pow(x,&nbsp;y)</code></td>
+ </tr>
+
+ <tr>
+ <td><code>pow(l,&nbsp;self)</code></td>
+
+ <td><code>__rpow__</code></td>
+
+ <td><code>pow(y,&nbsp;x)</code></td>
+ </tr>
+ </table>
+
+ <h4><a name="self_t-spec-value-unary-ops"></a>Class <code>self_t</code> unary
+ operations</h4>
+
+ <table border="1" summary="self_t unary operations">
+ <tr>
+ <th>C++ Expression</th>
+
+ <th>Python Method Name</th>
+
+ <th>C++ Implementation</th>
+ </tr>
+
+ <tr>
+ <td><code>-self</code></td>
+
+ <td><code>__neg__</code></td>
+
+ <td><code>-x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>+self</code></td>
+
+ <td><code>__pos__</code></td>
+
+ <td><code>+x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>~self</code></td>
+
+ <td><code>__invert__</code></td>
+
+ <td><code>~x</code></td>
+ </tr>
+
+ <tr>
+ <td><code>not self</code><br><i>or</i><br><code>!self</code></td>
+
+ <td><code>__nonzero__</code></td>
+
+ <td><code>!!x</code></td>
+ </tr>
+ </table>
+
+ <h4><a name="self_t-spec-value-ops"></a>Class <code>self_t</code> value
+ operations</h4>
+
+ <table border="1" summary="self_t value operations">
+ <tr>
+ <th>C++ Expression</th>
+
+ <th>Python Method Name</th>
+
+ <th>C++ Implementation</th>
+ </tr>
+
+ <tr>
+ <td><code>int_(self)</code></td>
+
+ <td><code>__int__</code></td>
+
+ <td><code>long(x)</code></td>
+ </tr>
+
+ <tr>
+ <td><code>long_</code></td>
+
+ <td><code>__long__</code></td>
+
+ <td><code>PyLong_FromLong(x)</code></td>
+ </tr>
+
+ <tr>
+ <td><code>float_</code></td>
+
+ <td><code>__float__</code></td>
+
+ <td><code>double(x)</code></td>
+ </tr>
+
+ <tr>
+ <td><code>complex_</code></td>
+
+ <td><code>__complex__</code></td>
+
+ <td><code>std::complex&lt;double&gt;(x)</code></td>
+ </tr>
+
+ <tr>
+ <td><code>str</code></td>
+
+ <td><code>__str__</code></td>
+
+ <td><code><a href=
+ "../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</code></td>
+ </tr>
+
+ <tr>
+ <td><code>repr</code></td>
+
+ <td><code>__repr__</code></td>
+
+ <td><code><a href=
+ "../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</code></td>
+ </tr>
+ </table>
+
+ <h3><a name="other-spec"></a>Class Template <code>other</code></h3>
+
+ <p>Instances of <code>other&lt;T&gt;</code> can be used in operator
+ expressions with <a href="#self-spec">self</a>; the result is equivalent
+ to the same expression with a <code>T</code> object in place of
+ <code>other&lt;T&gt;</code>. Use <code>other&lt;T&gt;</code> to prevent
+ construction of a <code>T</code> object in case it is heavyweight, when
+ no constructor is available, or simply for clarity.</p>
+
+ <h4><a name="other-spec-synopsis"></a>Class Template other synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T&gt;
+ struct other
+ {
+ };
+}}
+</pre>
+ <!-- -->
+
+ <h3><a name="operator_-spec"></a>Class Template
+ <code>detail::operator_</code></h3>
+
+ <p>Instantiations of <code>detail::operator_&lt;&gt;</code> are used as
+ the return type of operator expressions involving <code><a href=
+ "#self-spec">self</a></code>. This should be considered an implementation
+ detail and is only documented here as a way of showing how the result of
+ <code>self</code>-expressions match calls to <a href=
+ "class.html#class_-spec-modifiers">class_&lt;&gt;::def()</a>.</p>
+
+ <h4><a name="operator_-spec-synopsis"></a>Class Template
+ <code>detail::operator_</code> synopsis</h4>
+<pre>
+namespace boost { namespace python { namespace detail
+{
+ template &lt;<i>unspecified</i>&gt;
+ struct operator_
+ {
+ };
+}}}
+</pre>
+
+ <h2><a name="objects"></a>Objects</h2>
+
+ <p><a name="self-spec"><code>self</code></a></p>
+<pre>
+namespace boost { namespace python
+{
+ using self_ns::self;
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/operators.hpp&gt;
+#include &lt;boost/operators.hpp&gt;
+
+struct number
+ : boost::<a href=
+"../../../utility/operators.htm#grpd_oprs">integer_arithmetic</a>&lt;number&gt;
+{
+ explicit number(long x_) : x(x_) {}
+ operator long() const { return x; }
+
+ template &lt;class T&gt;
+ number&amp; operator+=(T const&amp; rhs)
+ { x += rhs; return *this; }
+
+ template &lt;class T&gt;
+ number&amp; operator-=(T const&amp; rhs)
+ { x -= rhs; return *this; }
+
+ template &lt;class T&gt;
+ number&amp; operator*=(T const&amp; rhs)
+ { x *= rhs; return *this; }
+
+ template &lt;class T&gt;
+ number&amp; operator/=(T const&amp; rhs)
+ { x /= rhs; return *this; }
+
+ template &lt;class T&gt;
+ number&amp; operator%=(T const&amp; rhs)
+ { x %= rhs; return *this; }
+
+ long x;
+};
+
+using namespace boost::python;
+BOOST_PYTHON_MODULE(demo)
+{
+ class_&lt;number&gt;("number", init&lt;long&gt;())
+ // 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)
+ ;
+}
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 5 October, 2004
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/overloads.html b/libs/python/doc/v2/overloads.html
new file mode 100644
index 000000000..783e8e5db
--- /dev/null
+++ b/libs/python/doc/v2/overloads.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/overloads.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/overloads.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href=
+ "#overload-dispatch-expression"><i>overload-dispatch-expressions</i></a></dt>
+
+ <dt><a href= "#OverloadDispatcher-concept">OverloadDispatcher</a> concept</dt>
+
+ <dt><a href="#macros">Macros</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href=
+ "#BOOST_PYTHON_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_FUNCTION_OVERLOADS</a></dt>
+
+ <dt><a href=
+ "#BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>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</p>
+
+ <h2><a name=
+ "overload-dispatch-expression"></a><i>overload-dispatch-expressions</i></h2>
+
+ <p>
+ An <em>overload-dispatch-expression</em> is used to describe a
+ family of overloaded methods to be generated for an extension
+ class. It has the following properties:
+
+ <blockquote>
+ <dl class="properties">
+ <dt><b>docstring:</b> An <a href="definitions.html#ntbs">ntbs</a>
+ whose value will bound to the methods' <code>__doc__</code>
+ attribute</dt>
+
+ <dt><b>keywords:</b> A <a href=
+ "args.html#keyword-expression">keyword-expression</a> which
+ will be used to name (a trailing subsequence of) the arguments
+ to the generated methods.</dt>
+
+ <dt><b>call policies:</b> An instance of some type which models <a href=
+ "CallPolicies.html">CallPolicies</a>.</dt>
+
+ <dt><b>minimum <a href="definitions.html#arity">arity</a></b>
+ The minimum number of arguments to be accepted by a generated
+ method overload.</dt>
+
+ <dt><b>maximum <a href="definitions.html#arity">arity</a></b>
+ The maximum number of arguments to be accepted by a generated
+ method overload.</dt>
+ </dl>
+ </blockquote>
+
+ <h2><a name="OverloadDispatcher-concept"></a>OverloadDispatcher Concept</h2>
+
+ An OverloadDispatcher <code>X</code> is a class which has a
+ <em>minimum arity</em> and a <em>maximum arity</em>, and for which
+ the following following are valid <a
+ href="#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>s,
+ with the same minimum and maximum arity as the OverloadDispatcher.
+
+<pre>
+X()
+X(docstring)
+X(docstring, keywords)
+X(keywords, docstring)
+X()[policies]
+X(docstring)[policies]
+X(docstring, keywords)[policies]
+X(keywords, docstring)[policies]
+</pre>
+
+<ul>
+<li>If <code>policies</code> are supplied, it must be an instance of a
+type which models <a
+href="CallPolicies.html#CallPolicies-concept">CallPolicies</a>, and
+will be used as the result's call policies. Otherwise the result's
+call policies will be an instance of <a
+href="default_call_policies.html#default_call_policies-spec">default_call_policies</a>.
+
+<li>If <code>docstring</code> is supplied it must be an <a
+href="definitions.html#ntbs">ntbs</a>, and will be used as the result's docstring. Otherwise the result has an empty docstring.
+
+<li>If <code>keywords</code> is supplied it must be the result of a <a
+ href= "args.html#keyword-expression">keyword-expression</a>
+ whose length is no greater than <code>X</code>'s maximum
+ arity, and will be used as the result's keywords. Otherwise
+ the result's keywords will be empty.
+</ul>
+
+
+
+
+ <h2><a name="macros"></a>Macros</h2>
+
+ <h3><a name=
+ "BOOST_PYTHON_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_FUNCTION_OVERLOADS(name,&nbsp;func_id,&nbsp;min_args,&nbsp;max_args)</a></h3>
+ Expands to the definition of an OverloadDispatcher called
+ <code>name</code> in the current scope which can be used to
+ generate the following function invocation:
+<pre>
+func_id(a<small><i>1</i></small>, a<small><i>2</i></small>,...a<small><i>i</i></small>);
+</pre>
+
+ for all <code>min_args</code> &lt;= <i>i</i> &lt;= <code>max_args</code>.
+
+ <h3><a name=
+ "BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(name,&nbsp;member_name,&nbsp;min_args,&nbsp;max_args)</a></h3>
+
+ Expands to the definition of an OverloadDispatcher called
+ <code>name</code> in the current scope which can be used to
+ generate the following function invocation:
+<pre>
+x.member_name(a<small><i>1</i></small>, a<small><i>2</i></small>,...a<small><i>i</i></small>);
+</pre>
+
+ for all <code>min_args</code> &lt;= <i>i</i> &lt;=
+ <code>max_args</code>, where <code>x</code> is a reference to an
+ object of class type.
+
+ <h2><a name="examples"></a>Example(s)</h2>
+
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/args.hpp&gt;
+#include &lt;boost/python/tuple.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/overloads.hpp&gt;
+#include &lt;boost/python/return_internal_reference.hpp&gt;
+
+using namespace boost::python;
+
+tuple f(int x = 1, double y = 4.25, char const* z = &quot;wow&quot;)
+{
+ return make_tuple(x, y, z);
+}
+
+BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
+
+struct Y {};
+struct X
+{
+ Y&amp; f(int x, double y = 4.25, char const* z = &quot;wow&quot;)
+ {
+ return inner;
+ }
+ Y inner;
+};
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(f_member_overloads, f, 1, 3)
+
+BOOST_PYTHON_MODULE(args_ext)
+{
+ def(&quot;f&quot;, f,
+ f_overloads(
+ args(&quot;x&quot;, &quot;y&quot;, &quot;z&quot;), &quot;This is f's docstring&quot;
+ ));
+
+
+ class_&lt;Y&gt;(&quot;Y&quot;)
+ ;
+
+ class_&lt;X&gt;(&quot;X&quot;, &quot;This is X's docstring&quot;)
+ .def(&quot;f1&quot;, &amp;X::f,
+ f_member_overloads(
+ args(&quot;x&quot;, &quot;y&quot;, &quot;z&quot;), &quot;f's docstring&quot;
+ )[return_internal_reference&lt;&gt;()]
+ )
+ ;
+}
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 15 April, 2003
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/pickle.html b/libs/python/doc/v2/pickle.html
new file mode 100644
index 000000000..22e198d63
--- /dev/null
+++ b/libs/python/doc/v2/pickle.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Boost.Python Pickle Support</title>
+</head>
+
+<body>
+ <div>
+ <img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
+ "center" width="277" height="86" />
+ <hr />
+
+ <h1>Boost.Python Pickle Support</h1>Pickle is a Python module for object
+ serialization, also known as persistence, marshalling, or flattening.
+
+ <p>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.</p>
+
+ <p>The Boost Python Library supports the pickle module through the
+ interface as described in detail in the <a href=
+ "http://www.python.org/doc/current/lib/module-pickle.html">Python Library
+ Reference for pickle.</a> This interface involves the special methods
+ <tt>__getinitargs__</tt>, <tt>__getstate__</tt> and <tt>__setstate__</tt>
+ as described in the following. Note that Boost.Python is also fully
+ compatible with Python's cPickle module.</p>
+ <hr />
+
+ <h2>The Boost.Python Pickle Interface</h2>At the user level, the
+ Boost.Python pickle interface involves three special methods:
+
+ <dl>
+ <dt><strong><tt>__getinitargs__</tt></strong></dt>
+
+ <dd>
+ When an instance of a Boost.Python extension class is pickled, the
+ pickler tests if the instance has a <tt>__getinitargs__</tt> 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.
+
+ <p>If <tt>__getinitargs__</tt> is not defined, <tt>pickle.load</tt>
+ will call the constructor (<tt>__init__</tt>) without arguments;
+ i.e., the object must be default-constructible.</p>
+ </dd>
+
+ <dt><strong><tt>__getstate__</tt></strong></dt>
+
+ <dd>When an instance of a Boost.Python extension class is pickled, the
+ pickler tests if the instance has a <tt>__getstate__</tt> method. This
+ method should return a Python object representing the state of the
+ instance.</dd>
+
+ <dt><strong><tt>__setstate__</tt></strong></dt>
+
+ <dd>When an instance of a Boost.Python extension class is restored by
+ the unpickler (<tt>pickle.load</tt>), it is first constructed using the
+ result of <tt>__getinitargs__</tt> as arguments (see above).
+ Subsequently the unpickler tests if the new instance has a
+ <tt>__setstate__</tt> method. If so, this method is called with the
+ result of <tt>__getstate__</tt> (a Python object) as the argument.</dd>
+ </dl>The three special methods described above may be <tt>.def()</tt>'ed
+ individually by the user. However, Boost.Python provides an easy to use
+ high-level interface via the
+ <strong><tt>boost::python::pickle_suite</tt></strong> class that also
+ enforces consistency: <tt>__getstate__</tt> and <tt>__setstate__</tt>
+ must be defined as pairs. Use of this interface is demonstrated by the
+ following examples.
+ <hr />
+
+ <h2>Examples</h2>There are three files in <tt>boost/libs/python/test</tt>
+ that show how to provide pickle support.
+ <hr />
+
+ <h3><a href="../../test/pickle1.cpp"><tt>pickle1.cpp</tt></a></h3>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 <tt>__getinitargs__</tt>. This is done in the
+ following way:
+
+ <ul>
+ <li>1. Definition of the C++ pickle function:
+ <pre>
+ struct world_pickle_suite : boost::python::pickle_suite
+ {
+ static
+ boost::python::tuple
+ getinitargs(world const&amp; w)
+ {
+ return boost::python::make_tuple(w.get_country());
+ }
+ };
+</pre>
+ </li>
+
+ <li>2. Establishing the Python binding:
+ <pre>
+ class_&lt;world&gt;("world", args&lt;const std::string&amp;&gt;())
+ // ...
+ .def_pickle(world_pickle_suite())
+ // ...
+</pre>
+ </li>
+ </ul>
+ <hr />
+
+ <h3><a href="../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a></h3>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
+ <tt>__getstate__</tt>/<tt>__setstate__</tt> pair of pickle interface
+ methods:
+
+ <ul>
+ <li>1. Definition of the C++ pickle functions:
+ <pre>
+ struct world_pickle_suite : boost::python::pickle_suite
+ {
+ static
+ boost::python::tuple
+ getinitargs(const world&amp; w)
+ {
+ // ...
+ }
+
+ static
+ boost::python::tuple
+ getstate(const world&amp; w)
+ {
+ // ...
+ }
+
+ static
+ void
+ setstate(world&amp; w, boost::python::tuple state)
+ {
+ // ...
+ }
+ };
+</pre>
+ </li>
+
+ <li>2. Establishing the Python bindings for the entire suite:
+ <pre>
+ class_&lt;world&gt;("world", args&lt;const std::string&amp;&gt;())
+ // ...
+ .def_pickle(world_pickle_suite())
+ // ...
+</pre>
+ </li>
+ </ul>
+
+ <p>For simplicity, the <tt>__dict__</tt> is not included in the result of
+ <tt>__getstate__</tt>. This is not generally recommended, but a valid
+ approach if it is anticipated that the object's <tt>__dict__</tt> will
+ always be empty. Note that the safety guard described below will catch
+ the cases where this assumption is violated.</p>
+ <hr />
+
+ <h3><a href="../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a></h3>This
+ example is similar to <a href=
+ "../../test/pickle2.cpp"><tt>pickle2.cpp</tt></a>. However, the object's
+ <tt>__dict__</tt> is included in the result of <tt>__getstate__</tt>.
+ This requires a little more code but is unavoidable if the object's
+ <tt>__dict__</tt> is not always empty.
+ <hr />
+
+ <h2>Pitfall and Safety Guard</h2>The pickle protocol described above has
+ an important pitfall that the end user of a Boost.Python extension module
+ might not be aware of:
+
+ <p><strong><tt>__getstate__</tt> is defined and the instance's
+ <tt>__dict__</tt> is not empty.</strong></p>
+
+ <p>The author of a Boost.Python extension class might provide a
+ <tt>__getstate__</tt> method without considering the possibilities
+ that:</p>
+
+ <ul>
+ <li>his class is used in Python as a base class. Most likely the
+ <tt>__dict__</tt> of instances of the derived class needs to be pickled
+ in order to restore the instances correctly.</li>
+
+ <li>the user adds items to the instance's <tt>__dict__</tt> directly.
+ Again, the <tt>__dict__</tt> of the instance then needs to be
+ pickled.</li>
+ </ul>
+
+ <p>To alert the user to this highly unobvious problem, a safety guard is
+ provided. If <tt>__getstate__</tt> is defined and the instance's
+ <tt>__dict__</tt> is not empty, Boost.Python tests if the class has an
+ attribute <tt>__getstate_manages_dict__</tt>. An exception is raised if
+ this attribute is not defined:</p>
+ <pre>
+ RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
+</pre>To resolve this problem, it should first be established that the <tt>
+ __getstate__</tt> and <tt>__setstate__</tt> methods manage the
+ instances's <tt>__dict__</tt> 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 <a href=
+ "../../test/pickle3.cpp"><tt>pickle3.cpp</tt></a>):
+ <pre>
+ struct world_pickle_suite : boost::python::pickle_suite
+ {
+ // ...
+
+ static bool getstate_manages_dict() { return true; }
+ };
+</pre>Alternatively in Python:
+ <pre>
+ 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
+</pre>
+ <hr />
+
+ <h2>Practical Advice</h2>
+
+ <ul>
+ <li>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.</li>
+
+ <li>Avoid using <tt>__getstate__</tt> if the instance can also be
+ reconstructed by way of <tt>__getinitargs__</tt>. This automatically
+ avoids the pitfall described above.</li>
+
+ <li>If <tt>__getstate__</tt> is required, include the instance's
+ <tt>__dict__</tt> in the Python object that is returned.</li>
+ </ul>
+ <hr />
+
+ <h2>Light-weight alternative: pickle support implemented in Python</h2>
+
+ <h3><a href="../../test/pickle4.cpp"><tt>pickle4.cpp</tt></a></h3>The
+ <tt>pickle4.cpp</tt> example demonstrates an alternative technique for
+ implementing pickle support. First we direct Boost.Python via the
+ <tt>class_::enable_pickling()</tt> member function to define only the
+ basic attributes required for pickling:
+ <pre>
+ class_&lt;world&gt;("world", args&lt;const std::string&amp;&gt;())
+ // ...
+ .enable_pickling()
+ // ...
+</pre>This enables the standard Python pickle interface as described in the
+Python documentation. By "injecting" a <tt>__getinitargs__</tt> method into
+the definition of the wrapped class we make all instances pickleable:
+ <pre>
+ # import the wrapped world class
+ from pickle4_ext import world
+
+ # definition of __getinitargs__
+ def world_getinitargs(self):
+ return (self.get_country(),)
+
+ # now inject __getinitargs__ (Python is a dynamic language!)
+ world.__getinitargs__ = world_getinitargs
+</pre>See also the <a href=
+"../tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python">
+ tutorial section</a> on injecting additional methods from Python.
+ <hr />
+ © Copyright Ralf W. Grosse-Kunstleve 2001-2004. Distributed under the
+ Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ <p>Updated: Feb 2004.</p>
+ </div>
+</body>
+</html>
diff --git a/libs/python/doc/v2/platforms.html b/libs/python/doc/v2/platforms.html
new file mode 100644
index 000000000..ac984b43f
--- /dev/null
+++ b/libs/python/doc/v2/platforms.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - Known Working Platforms and Compilers</title>
+ </head>
+
+ <body link="#0000ff" vlink="#800080">
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Known Working Platforms and Compilers</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+ Please see
+ our <a
+ href="http://boost.sourceforge.net/regression-logs">regression
+ logs</a> for up-to-date information. Note that logs not marked
+ otherwise reflect the CVS state, not the condition of the release.
+
+ <p>
+ Earlier versions of <b>Boost.Python</b> have been successfully
+ tested on the following platforms and compilers.
+
+ <dl class="page-index">
+ <dt>Unix Platforms:</dt>
+
+ <dd>
+ <dl>
+ <dt>with Python <a href="http://www.python.org/2.2">2.2</a> and <a
+ href="http://www.python.org/2.2.2">2.2.2b1</a>:</dt>
+
+ <dd>
+ <dl>
+ <dt><a href="http://gcc.gnu.org">GCC</a> 2.95.3, 2.96, 3.0.4,
+ 3.1, and 3.2 on <a href="http://www.redhat.com">RedHat Linux 7.3</a>
+ for Intel x86</dt>
+
+ <dt>Tru64 CXX 6.5.1 on OSF v. 5.1 for Dec/Compaq
+ Alpha</dt>
+
+ <dt>
+ MIPSPro 7.3.1.2m on <a href=
+ "http://www.sgi.com/software/irix6.5/">IRIX 6.5</a> for SGI
+ mips</dt>
+
+ <dt><a href="http://gcc.gnu.org">GCC 3.1</a> on SunOS 5.8</dt>
+ </dl>
+ </dd>
+
+ <dt>with Python <a href=
+ "http://www.python.org/2.2.1">2.2.1</a></dt>
+
+ <dd>
+ <dl>
+ <dt>KCC 3.4d on OSF v. 5.1 for Dec/Compaq Alpha</dt>
+
+ <dt>KCC 3.4d</a> on AIX</dt>
+ </dl>
+ </dd>
+ </dl>
+ <br>
+ </dd>
+
+ <dt>Microsoft Windows XP Professional with Python <a href=
+ "http://www.python.org/2.2">2.2</a>, <a href=
+ "http://www.python.org/2.2.1">2.2.1</a>, and <a href=
+ "http://www.python.org/2.2.2">2.2.2b1</a>:</dt>
+
+ <dd>
+ <dl>
+ <dt><a href=
+ "http://msdn.microsoft.com/visualc/default.asp">Microsoft Visual
+ C++</a> 6, 7, and 7.1 beta</dt>
+
+ <dt><a href=
+ "http://msdn.microsoft.com/visualc/default.asp">Microsoft Visual
+ C++ 6</a> with <a href="http://www.stlport.org">STLPort
+ 4.5.3</a></dt>
+
+ <dt><a href=
+ "http://www.metrowerks.com/MW/Develop/Desktop/Windows/Professional/Default.htm">
+ Metrowerks CodeWarrior</a> 7.2, 8.0, 8.2 and 8.3 beta</dt>
+
+ <dt><a href=
+ "http://www.intel.com/software/products/compilers/c60/">Intel
+ C++</a> 5.0, 6.0, and 7.0 beta</dt>
+
+ <dt><a href=
+ "http://www.intel.com/software/products/compilers/c60/">Intel C++
+ 5.0</a> with <a href="http://www.stlport.org">STLPort
+ 4.5.3</a></dt>
+
+ <dt><a href="http://www.cygwin.com">Cygwin</a> <a href=
+ "http://gcc.gnu.org">GCC</a> 3.0.4 and 3.2</dt>
+
+ <dt><a href="http://www.mingw.org">MinGW-1.1</a> (<a href=
+ "http://gcc.gnu.org">GCC 2.95.3-5</a>)</dt>
+
+ <dt><a href="http://www.mingw.org">MinGW-2.0</a> (<a href=
+ "http://gcc.gnu.org">GCC 3.2</a>)</dt>
+ </dl>
+ </dd>
+ </dl>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/pointee.html b/libs/python/doc/v2/pointee.html
new file mode 100644
index 000000000..2dcec8c36
--- /dev/null
+++ b/libs/python/doc/v2/pointee.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/pointee.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/pointee.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a>
+
+ <dt><a href="#classes">Classes</a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#pointee-spec">Class Template<code>pointee</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#pointee-spec-synopsis">Class Template
+ <code>pointee</code> synopsis</a>
+ </dl>
+ </dl>
+
+ <dt><a href="#examples">Example</a>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/pointee.hpp&gt;</code> introduces a
+ traits <a
+ href="../../../mpl/doc/refmanual/metafunction.html">metafunction</a>
+ template <code>pointee&lt;T&gt;</code> that can be used to extract the &quot;pointed-to&quot; type from the type of a pointer or smart pointer.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="pointee-spec"></a>Class Template <code>pointee&lt;class T&gt;</code></h3>
+
+ <p><code>pointee&lt;T&gt;</code> is used by the <code><a
+ href="class.html#class_-spec">class_</a>&lt;...&gt;</code>
+ template to deduce the type being held when a pointer or smart
+ pointer type is used as its <code>HeldType</code> argument.
+
+ <h4><a name="pointee-spec-synopsis"></a>Class Template
+ <code>pointee</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T&gt; struct pointee
+ {
+ typedef T::element_type type;
+ };
+
+ // specialization for pointers
+ template &lt;T&gt; struct pointee&lt;T*&gt;
+ {
+ typedef T type;
+ };
+}
+</pre>
+
+
+ <h2><a name="examples"></a>Example</h2>
+
+Given a 3rd-party smart pointer type
+<code>smart_pointer&lt;T&gt;</code>, one might partially specialize
+<code>pointee&lt;smart_pointer&ltT&gt; &gt;</code> so that it can be
+used as the <code>HeldType</code> for a class wrapper:
+
+<pre>
+#include &lt;boost/python/pointee.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;third_party_lib.hpp&gt;
+
+namespace boost { namespace python
+{
+ template &lt;class T&gt; struct pointee&ltsmart_pointer&lt;T&gt; &gt;
+ {
+ typedef T type;
+ };
+}}
+
+BOOST_PYTHON_MODULE(pointee_demo)
+{
+ class_&lt;third_party_class, smart_pointer&lt;third_party_class&gt; &gt;(&quot;third_party_class&quot;)
+ .def(...)
+ ...
+ ;
+}
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i> Distributed
+ under the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</p>
+
+
diff --git a/libs/python/doc/v2/progress_reports.html b/libs/python/doc/v2/progress_reports.html
new file mode 100644
index 000000000..5a8b015a2
--- /dev/null
+++ b/libs/python/doc/v2/progress_reports.html
@@ -0,0 +1,47 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../boost.css">
+<title>Boost.Python - Progress Reports</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">Progress Reports</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+
+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.
+
+<dl class="page-index">
+ <dt><a href="feb2002.html">February 2002</a></dt>
+ <dt><a href="Mar2002.html">March 2002</a></dt>
+ <dt><a href="Apr2002.html">April 2002</a></dt>
+ <dt><a href="May2002.html">May 2002</a></dt>
+ <dt><a href="Jun2002.html">June 2002</a></dt>
+</dl>
+<hr>
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
+ 2002. </i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/ptr.html b/libs/python/doc/v2/ptr.html
new file mode 100644
index 000000000..4aca53915
--- /dev/null
+++ b/libs/python/doc/v2/ptr.html
@@ -0,0 +1,265 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/ptr.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/ptr.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a>
+
+ <dt><a href="#functions">Functions</a>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#ptr-spec">ptr</a>
+ </dl>
+
+ <dt><a href="#classes">Classes</a>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#pointer_wrapper-spec">Class template <code>pointer_wrapper</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#pointer_wrapper-spec-synopsis">Class template <code>pointer_wrapper</code> synopsis</a>
+
+ <dt><a href="#pointer_wrapper-spec-types">Class
+ <code>pointer_wrapper</code> types</a>
+
+ <dt><a href="#pointer_wrapper-spec-ctors">Class
+ <code>pointer_wrapper</code> constructors and destructor</a>
+
+ <dt><a href="#pointer_wrapper-spec-observers">Class
+ <code>pointer_wrapper</code> observer functions</a>
+
+ </dl>
+ </dl>
+
+ <dt><a href="#metafunctions">Metafunctions</a>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#is_pointer_wrapper-spec">Class template <code>is_pointer_wrapper</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#is_pointer_wrapper-spec-synopsis">Class template <code>is_pointer_wrapper</code> synopsis</a>
+ </dl>
+
+
+ <dt><a href="#unwrap_pointer-spec">Class template <code>unwrap_pointer</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#unwrap_pointer-spec-synopsis">Class template <code>unwrap_pointer</code> synopsis</a>
+ </dl>
+
+ </dl>
+
+
+ <dt><a href="#examples">Example(s)</a>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/ptr.hpp&gt;</code> defines the
+ <code>ptr()</code> 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 <code>p</code>,
+ the user can pass <code><a href="#ptr-spec">ptr</a>(p)</code> instead of passing
+ <code>p</code> directly. This interface is meant to mirror the use
+ of <a href="../../../bind/ref.html"><code>boost::ref()</code></a>,
+ which can be similarly used to prevent copying of referents.
+
+ <p><code>ptr(p)</code> returns an instance of <code><a
+ href="#pointer_wrapper-spec">pointer_wrapper&lt;&gt;</a></code>, which
+ can be detected using the <code><a
+ href="#is_pointer_wrapper-spec">is_pointer_wrapper&lt;&gt;</a></code>
+ metafunction; <code><a
+ href="#unwrap_pointer-spec">unwrap_pointer&lt;&gt;</a></code> is a
+ metafunction which extracts the original pointer type from a
+ <code>pointer_wrapper&lt;&gt;</code>. These classes can be thought
+ of as implementation details.
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+
+<a name="ptr-spec">template &lt;class T&gt;</a>
+pointer_wrapper&lt;T&gt; ptr(T x);
+</pre>
+
+ <dl class="ptr-semantics">
+ <dt><b>Requires:</b> <code>T</code> is a pointer type.
+
+ <dt><b>Returns:</b> <code><a href="#pointer_wrapper-spec">pointer_wrapper</a>&lt;T&gt;(x)</code>
+
+ <dt><b>Throws:</b> nothing.
+ </dl>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="pointer_wrapper-spec"></a>Class template <code>pointer_wrapper</code></h3>
+
+ <p>A &quot;type envelope&quot; which is returned by <a
+ href="#ptr-spec">ptr()</a>, used to indicate reference semantics
+ for pointers passed to Python callbacks.
+
+ <h4><a name="pointer_wrapper-spec-synopsis"></a>Class
+ <code>pointer_wrapper</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template&lt;class Ptr&gt; class pointer_wrapper
+ {
+ public:
+ typedef Ptr type;
+
+ explicit pointer_wrapper(Ptr x);
+ operator Ptr() const;
+ Ptr get() const;
+ };
+}}
+</pre>
+
+ <h4><a name="pointer_wrapper-spec-types"></a>Class template <code>pointer_wrapper</code> types</h4>
+<pre>
+typedef Ptr type;
+</pre>
+The type of the pointer being wrapped.
+
+ <h4><a name="pointer_wrapper-spec-ctors"></a>Class template <code>pointer_wrapper</code> constructors and
+ destructor</h4>
+<pre>
+explicit pointer_wrapper(Ptr x);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>Ptr</code> is a pointer type.
+
+ <dt><b>Effects:</b> Stores <code>x</code> in a the <code>pointer_wrapper&lt;&gt;</code>.
+ <dt><b>Throws:</b> nothing.
+ </dl>
+
+ <h4><a name="pointer_wrapper-spec-observers"></a>Class template <code>pointer_wrapper</code> observer
+ functions</h4>
+<pre>
+operator Ptr() const;
+Ptr get() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> a copy of the stored pointer.
+ <dt><b>Rationale:</b> <code>pointer_wrapper</code> 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.
+ </dl>
+
+ <h2><a name="metafunctions"></a>Metafunctions</h2>
+
+ <h3><a name="is_pointer_wrapper-spec"></a>Class template <code>is_pointer_wrapper</code></h3>
+
+ <p>A unary metafunction whose <code>value</code> is true iff its
+ argument is a <code>pointer_wrapper&lt;&gt;</code>.
+
+ <h4><a name="is_pointer_wrapper-spec-synopsis"></a>Class template <code>is_pointer_wrapper</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template&lt;class T&gt; class is_pointer_wrapper
+ {
+ static <i>unspecified</i> value = ...;
+ };
+}}
+</pre>
+
+
+ <dl class="metafunction-semantics">
+ <dt><b>Returns:</b> <code>true</code> iff <code>T</code> is a
+ specialization of
+<code>pointer_wrapper&lt;&gt;</code>.
+<dt><code>value</code> is an integral constant convertible to bool of
+unspecified type
+
+ </dl>
+
+<h3><a name="unwrap_pointer-spec"></a>Class template <code>unwrap_pointer</code></h3>
+
+A unary metafunction which extracts the wrapped pointer type from a
+specialization of <code>pointer_wrapper&lt;&gt;</code>.
+
+ <h4><a name="unwrap_pointer-spec-synopsis"></a>Class template <code>unwrap_pointer</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template&lt;class T&gt; class unwrap_pointer
+ {
+ typedef <i>unspecified</i> type;
+ };
+}}
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Returns:</b> <code>T::type</code> if <code>T</code> is a
+ specialization of
+<code>pointer_wrapper&lt;&gt;</code>, <code>T</code> otherwise
+ </dl>
+
+
+ <h2><a name="examples"></a>Example(s)</h2>
+
+This example illustrates the use of <code>ptr()</code> to prevent an
+object from being copied:
+<pre>
+#include &lt;boost/python/call.hpp&gt;
+#include &lt;boost/python/ptr.hpp&gt;
+
+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&lt;void&gt;(f, ptr(x));
+}
+...
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i> Distributed
+ under the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</p>
+
diff --git a/libs/python/doc/v2/python.html b/libs/python/doc/v2/python.html
new file mode 100644
index 000000000..9c4e27ec6
--- /dev/null
+++ b/libs/python/doc/v2/python.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>This is a convenience header which #includes all of the public
+ interface headers that are part of the Boost.Python library</p>
+<pre>
+# include &lt;args.hpp&gt;
+# include &lt;args_fwd.hpp&gt;
+# include &lt;back_reference.hpp&gt;
+# include &lt;bases.hpp&gt;
+# include &lt;borrowed.hpp&gt;
+# include &lt;call.hpp&gt;
+# include &lt;call_method.hpp&gt;
+# include &lt;class.hpp&gt;
+# include &lt;copy_const_reference.hpp&gt;
+# include &lt;copy_non_const_reference.hpp&gt;
+# include &lt;data_members.hpp&gt;
+# include &lt;def.hpp&gt;
+# include &lt;default_call_policies.hpp&gt;
+# include &lt;dict.hpp&gt;
+# include &lt;enum.hpp&gt;
+# include &lt;errors.hpp&gt;
+# include &lt;exception_translator.hpp&gt;
+# include &lt;extract.hpp&gt;
+# include &lt;handle.hpp&gt;
+# include &lt;has_back_reference.hpp&gt;
+# include &lt;implicit.hpp&gt;
+# include &lt;init.hpp&gt;
+# include &lt;instance_holder.hpp&gt;
+# include &lt;iterator.hpp&gt;
+# include &lt;list.hpp&gt;
+# include &lt;long.hpp&gt;
+# include &lt;lvalue_from_pytype.hpp&gt;
+# include &lt;make_function.hpp&gt;
+# include &lt;manage_new_object.hpp&gt;
+# include &lt;module.hpp&gt;
+# include &lt;numeric.hpp&gt;
+# include &lt;object.hpp&gt;
+# include &lt;object_protocol.hpp&gt;
+# include &lt;object_protocol_core.hpp&gt;
+# include &lt;operators.hpp&gt;
+# include &lt;other.hpp&gt;
+# include &lt;overloads.hpp&gt;
+# include &lt;pointee.hpp&gt;
+# include &lt;ptr.hpp&gt;
+# include &lt;reference_existing_object.hpp&gt;
+# include &lt;return_internal_reference.hpp&gt;
+# include &lt;return_value_policy.hpp&gt;
+# include &lt;scope.hpp&gt;
+# include &lt;self.hpp&gt;
+# include &lt;slice_nil.hpp&gt;
+# include &lt;str.hpp&gt;
+# include &lt;to_python_converter.hpp&gt;
+# include &lt;to_python_indirect.hpp&gt;
+# include &lt;to_python_value.hpp&gt;
+# include &lt;tuple.hpp&gt;
+# include &lt;type_id.hpp&gt;
+# include &lt;with_custodian_and_ward.hpp&gt;
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/pytype_function.html b/libs/python/doc/v2/pytype_function.html
new file mode 100644
index 000000000..fcc2a7f92
--- /dev/null
+++ b/libs/python/doc/v2/pytype_function.html
@@ -0,0 +1,370 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright Nikolay Mladenov 2007. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/doobject/pytype_function.hpp&gt;</title>
+</head>
+
+<body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href=
+ "../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/converter/pytype_function.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#wrap_pytype-spec">Class
+ <code>wrap_pytype</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#wrap_pytype-spec-synopsis">Class
+ <code>wrap_pytype</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#registered_pytype-spec">Class
+ <code>registered_pytype</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#registered_pytype-spec-synopsis">Class
+ <code>registered_pytype</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#expected_from_python_type-spec">Class
+ <code>expected_from_python_type</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#expected_from_python_type-spec-synopsis">Class
+ <code>expected_from_python_type</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_target_type-spec">Class
+ <code>to_python_target_type</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_target_type-spec-synopsis">Class
+ <code>to_python_target_type</code> synopsis</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id=
+ "introduction"></a>Introduction</h2>
+
+ <p>To support Pythonic signatures the converters should supply a <code>get_pytype</code> function
+ returning a pointer to the associated <code>PyTypeObject</code>. See for example
+ <a href="ResultConverter.html#ResultConverter-concept">ResultConverter</a> or
+ <a href="to_python_converter.html#to_python_converter-spec">to_python_converter</a>.
+ The classes in this header file are meant to be used when implmenting <code>get_pytype</code>.
+ There are also <code>_direct</code> versions of the templates of <code>class T</code> which
+ should be used with undecorated type parameter, expected to be in the conversion registry when the module loads.
+ </p>
+
+ <h2><a name="classes" id="classes"></a>Classes</h2>
+
+ <h3><a name="wrap_pytype-spec" id=
+ "wrap_pytype-spec"></a>Class
+ <code>wrap_pytype</code></h3>
+
+ <p>
+ This template generates a static <code>get_pytype</code> member returning the template parameter.
+ </p>
+
+ <h4><a name="wrap_pytype-spec-synopsis" id=
+ "wrap_pytype-spec-synopsis"></a>Class
+ <code>wrap_pytype</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; PyTypeObject const *pytype &gt;
+ class wrap_pytype
+ {
+ public:
+ static PyTypeObject const *get_pytype(){return pytype; }
+ };
+
+}}}
+</pre>
+
+
+ <h3><a name="registered_pytype-spec" id=
+ "registered_pytype-spec"></a>Class
+ <code>registered_pytype</code></h3>
+
+ <p>
+ This template should be used with template parameters which are (possibly decorated)
+ types exported to python using <a href="class.html"><code>class_</code></a>.
+ The generated a static <code>get_pytype</code> member
+ returns the corresponding python type.
+ </p>
+
+ <h4><a name="registered_pytype-spec-synopsis" id=
+ "registered_pytype-spec-synopsis"></a>Class
+ <code>registered_pytype</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; class T &gt;
+ class registered_pytype
+ {
+ public:
+ static PyTypeObject const *get_pytype();
+ };
+
+}}}
+</pre>
+
+
+ <h3><a name="expected_from_python_type-spec" id=
+ "expected_from_python_type-spec"></a>Class
+ <code>expected_from_python_type</code></h3>
+
+ <p>
+ This template generates a static <code>get_pytype</code> member which inspects the registered
+ <code>from_python</code> converters for the type <code>T</code> and returns a matching python type.
+ </p>
+
+ <h4><a name="expected_from_python_type-spec-synopsis" id=
+ "expected_from_python_type-spec-synopsis"></a>Class
+ <code>expected_from_python_type</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; class T &gt;
+ class expected_from_python_type
+ {
+ public:
+ static PyTypeObject const *get_pytype();
+ };
+
+}}}
+</pre>
+
+
+ <h3><a name="to_python_target_type-spec" id=
+ "to_python_target_type-spec"></a>Class
+ <code>to_python_target_type</code></h3>
+
+ <p>
+ This template generates a static <code>get_pytype</code> member returning the
+ python type to which T can be converted.
+ </p>
+
+ <h4><a name="to_python_target_type-spec-synopsis" id=
+ "to_python_target_type-spec-synopsis"></a>Class
+ <code>to_python_target_type</code> synopsis</h4>
+ <pre>
+namespace boost { namespace python { namespace converter{
+
+ template &lt; class T &gt;
+ class to_python_target_type
+ {
+ public:
+ static PyTypeObject const *get_pytype();
+ };
+
+}}}
+</pre>
+
+
+ <h2><a name="examples" id="examples"></a>Examples</h2>
+
+ This example presumes that someone has implemented the standard <a href=
+ "http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
+ module</a> from the Python documentation, and placed the corresponding
+ declarations in <code>"noddy.h"</code>. Because
+ <code>noddy_NoddyObject</code> is the ultimate trivial extension type,
+ the example is a bit contrived: it wraps a function for which all
+ information is contained in the <i>type</i> of its return value.
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/reference.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+#include "noddy.h"
+
+struct tag {};
+tag make_tag() { return tag(); }
+
+using namespace boost::python;
+
+struct tag_to_noddy
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
+: wrap_pytype<&amp;noddy_NoddyType> //inherits get_pytype from wrap_pytype
+#endif
+{
+ static PyObject* convert(tag const&amp; x)
+ {
+ return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
+ }
+};
+
+BOOST_PYTHON_MODULE(to_python_converter)
+{
+ def("make_tag", make_tag);
+ to_python_converter&lt;tag, tag_to_noddy
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
+ , true
+#endif
+ &gt;(); //"true" because tag_to_noddy has member get_pytype
+}
+</pre>
+
+
+<p>The following example registers to and from python converters using the templates
+<code>expected_from_python_type</code> and <code>to_pyhton_target_type</code>.
+</p>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/extract.hpp&gt;
+#include &lt;boost/python/to_python_converter.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+
+using namespace boost::python;
+
+struct A
+{
+};
+
+struct B
+{
+ A a;
+ B(const A& a_):a(a_){}
+};
+
+// Converter from A to python int
+struct BToPython
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //unnecessary overhead if py signatures are not supported
+ : converter::to_python_target_type&lt;A&gt; //inherits get_pytype
+#endif
+{
+ static PyObject* convert(const B& b)
+ {
+ return incref(object(b.a).ptr());
+ }
+};
+
+// Conversion from python int to A
+struct BFromPython
+{
+ BFromPython()
+ {
+ boost::python::converter::registry::push_back
+ ( &amp;convertible
+ , &amp;construct
+ , type_id&lt; B &gt;()
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
+ , &amp;converter::expected_from_python_type&lt;A&gt;::get_pytype//convertible to A can be converted to B
+#endif
+ );
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ extract&lt;const A&&gt; ex(obj_ptr);
+ if (!ex.check()) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ converter::rvalue_from_python_stage1_data* data)
+ {
+ void* storage = (
+ (converter::rvalue_from_python_storage&lt; B &gt;*)data)-&gt; storage.bytes;
+
+ extract&lt;const A&&gt; ex(obj_ptr);
+ new (storage) B(ex());
+ data->convertible = storage;
+ }
+};
+
+
+B func(const B& b) { return b ; }
+
+BOOST_PYTHON_MODULE(pytype_function_ext)
+{
+ to_python_converter&lt; B , BToPython
+#if defined BOOST_PYTHON_SUPPORTS_PY_SIGNATURES //invalid if py signatures are not supported
+ ,true
+#endif
+ &gt;(); //has get_pytype
+ BFromPython();
+
+ class_&lt;A&gt;("A") ;
+
+ def("func", &amp;func);
+
+}
+
+
+
+&gt;&gt;&gt; from pytype_function_ext import *
+&gt;&gt;&gt; print func.__doc__
+func( (A)arg1) -> A :
+ C++ signature:
+ struct B func(struct B)
+</pre>
+
+
+ <p><i>&copy; Copyright <a href="mailto:nickm at sitius dot com">Nikolay Mladenov</a> 2007.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/raw_function.html b/libs/python/doc/v2/raw_function.html
new file mode 100644
index 000000000..0ad4c37c2
--- /dev/null
+++ b/libs/python/doc/v2/raw_function.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/raw_function.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/raw_function.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#raw_function-spec">raw_function</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code><a href="#raw_function-spec">raw_function</a>(...)</code>
+ is used to convert a function taking a <a
+ href="tuple.html#tuple-spec">tuple</a> and a <a
+ href="dict.html#dict-spec">dict</a> into a Python callable object
+ which accepts a variable number of arguments and arbitrary keyword
+ arguments.
+
+ <h2><a name="functions"></a>Functions</h2>
+ <a name="raw_function-spec"></a>raw_function
+<pre>
+template &lt;class F&gt;
+object raw_function(F f, std::size_t min_args = 0);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>f(tuple(), dict())</code> is
+ well-formed.</dt>
+
+ <dt><b>Returns:</b> a <a href=
+ "http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">callable</a> object which requires at least <code>min_args</code> arguments. When called, the actual non-keyword arguments will be passed in a <a
+ href="tuple.html#tuple-spec">tuple</a> as the first argument to <code>f</code>, and the keyword arguments will be passed in a <a
+ href="dict.html#dict-spec">dict</a> as the second argument to <code>f</code>.
+
+ </dd>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+C++:
+<pre>
+#include &lt;boost/python/def.hpp&gt;
+#include &lt;boost/python/tuple.hpp&gt;
+#include &lt;boost/python/dict.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/raw_function.hpp&gt;
+
+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));
+}
+</pre>
+
+Python:
+<pre>
+&gt;&gt;&gt; from raw_test import *
+
+&gt;&gt;&gt; raw(3, 4, foo = 'bar', baz = 42)
+((3, 4), {'foo': 'bar', 'baz': 42})
+</pre>
+ <p>
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 7 March, 2003
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/reference.html b/libs/python/doc/v2/reference.html
new file mode 100644
index 000000000..5ebdad105
--- /dev/null
+++ b/libs/python/doc/v2/reference.html
@@ -0,0 +1,1192 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - Reference</title>
+
+ <style type="text/css">
+ p.c3 {font-style: italic}
+ h2.c2 {text-align: center}
+ h1.c1 {text-align: center}
+ </style>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "reference">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="http://www.boost.org"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 class="c2">Reference</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="Reference">
+ <dt><a href="#concepts">Concepts</a></dt>
+
+ <dt><a href="#high_level">High Level Components</a></dt>
+
+ <dt><a href="#object_wrappers">Object Wrappers</a></dt>
+
+ <dt><a href="#invocation">Function Invocation and Creation</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="#models_of_call_policies">Models of
+ CallPolicies</a></dt>
+
+ <dt><a href="#models_of_result_converter">Models of
+ ResultConverter</a></dt>
+
+ <dt><a href="#result_converter_generators">Models of
+ ResultConverterGenerator</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#type_conversion">To/From Python Type Conversion</a></dt>
+
+ <dt><a href="#embedding">Embedding</a></dt>
+
+ <dt><a href="#utility">Utility and Infrastructure</a></dt>
+
+ <dt><a href="#topics">Topics</a></dt>
+ </dl>
+ <hr>
+ <!-- xxxxx -->
+
+ <h2><a name="concepts">Concepts</a></h2>
+
+ <dl class="index">
+ <dt><a href=
+ "CallPolicies.html#CallPolicies-concept">CallPolicies</a></dt>
+
+ <dt><a href=
+ "Dereferenceable.html#Dereferenceable-concept">Dereferenceable</a></dt>
+
+ <dt><a href="Extractor.html#Extractor-concept">Extractor</a></dt>
+
+ <dt><a href=
+ "HolderGenerator.html#HolderGenerator-concept">HolderGenerator</a></dt>
+
+ <dt><a href=
+ "ResultConverter.html#ResultConverter-concept">ResultConverter</a></dt>
+
+ <dt><a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a></dt>
+
+ <dt><a href=
+ "ObjectWrapper.html#ObjectWrapper-concept">ObjectWrapper</a></dt>
+
+ <dt><a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a></dt>
+ </dl>
+
+ <h2><a name="high_level">High Level Components</a></h2>
+
+ <dl>
+ <dt><a href="class.html">class.hpp/class_fwd.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="class.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="class.html#class_-spec">class_</a></dt>
+
+ <dt><a href="class.html#bases-spec">bases</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="def.html">def.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="def.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="def.html#def-spec">def</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="def_visitor.html">def_visitor.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="def_visitor.html#classes">Classes</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="docstring_options.html">docstring_options.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="docstring_options.html#classes">Classes</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="enum.html">enum.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="enum.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="enum.html#enum_-spec">enum_</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="errors.html">errors.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="errors.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="errors.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "errors.html#handle_exception-spec">handle_exception</a></dt>
+
+ <dt><a href=
+ "errors.html#expect_non_null-spec">expect_non_null</a></dt>
+
+ <dt><a href=
+ "errors.html#throw_error_already_set-spec">throw_error_already_set</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "exception_translator.html">exception_translator.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "exception_translator.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "exception_translator.html#register_exception_translator-spec">register_exception_translator</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="init.html">init.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="init.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="init.html#init-spec">init</a></dt>
+
+ <dt><a href="init.html#optional-spec">optional</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="iterator.html">iterator.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="iterator.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="iterator.html#iterator-spec">iterator</a></dt>
+
+ <dt><a href="iterator.html#iterators-spec">iterators</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="iterator.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="iterator.html#range-spec">range</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="module.html">module.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="module.html#macros">Macros</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "module.html#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="operators.html">operators.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="operators.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="operators.html#self_t-spec">self_t</a></dt>
+
+ <dt><a href="operators.html#other-spec">other</a></dt>
+
+ <dt><a href="operators.html#operator_-spec">operator_</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="operators.html#objects">Objects</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="operators.html#self-spec">self</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="scope.html">scope.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="scope.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="scope.html#scope-spec">scope</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="stl_iterator.html">stl_iterator.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="stl_iterator.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="stl_iterator.html#stl_input_iterator-spec">stl_input_iterator</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="wrapper.html">wrapper.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="wrapper.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="wrapper.html#override-spec">override</a></dt>
+
+ <dt><a href="wrapper.html#wrapper-spec">wrapper</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+
+ <h2><a name="object_wrappers">Object Wrappers</a></h2>
+
+ <dl class="index">
+ <dt><a href="dict.html">dict.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="dict.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="dict.html#dict-spec">dict</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="list.html">list.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="list.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="list.html#list-spec">list</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="long.html">long.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="long.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="long.html#long_-spec">long_</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="numeric.html">numeric.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="numeric.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="numeric.html#array-spec">numeric::array</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="object.html">object.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="object.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="object.html#object-spec">object</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="str.html">str.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="str.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="str.html#str-spec">str</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="tuple.html">tuple.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="tuple.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="tuple.html#tuple-spec">tuple</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="tuple.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="tuple.html#make_tuple-spec">make_tuple</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="slice.html">slice.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="slice.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="slice.html#slice-spec">slice</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+
+ <h2><a name="invocation">Function Invocation and Creation</a></h2>
+
+ <dl class="index">
+ <dt><a href="args.html">args.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="args.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="args.html#args-spec">args</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="call.html">call.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="call.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="call.html#call-spec">call</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="call_method.html">call_method.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="call_method.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "call_method.html#call_method-spec">call_method</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="data_members.html">data_members.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="data_members.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "data_members.html#make_getter-spec">make_getter</a></dt>
+
+ <dt><a href=
+ "data_members.html#make_setter-spec">make_setter</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="make_function.html">make_function.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="make_function.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "make_function.html#make_function-spec">make_function</a></dt>
+
+ <dt><a href=
+ "make_function.html#make_constructor-spec">make_constructor</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="overloads.html">overloads.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="overloads.html#macros">macros</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_FUNCTION_OVERLOADS</a></dt>
+
+ <dt><a href=
+ "overloads.html#BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="ptr.html">ptr.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="ptr.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="ptr.html#ptr-spec">ptr</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="ptr.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "ptr.html#pointer_wrapper-spec">pointer_wrapper</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="ptr.html#metafunctions">MetaFunctions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "ptr.html#is_pointer_wrapper-spec">is_pointer_wrapper</a></dt>
+
+ <dt><a href=
+ "ptr.html#unwrap_pointer-spec">unwrap_pointer</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="raw_function.html">raw_function.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="raw_function.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href=
+ "raw_function.html#raw_function-spec">raw_function</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <a name="function_documentation"></a>
+
+ <h3>Function documentation</h3>
+
+ <dl class="index">
+ <dt><a href=
+ "function_doc_signature.html">function_doc_signature.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "function_doc_signature.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "function_doc_signature.html#function_doc_signature_generator-spec">function_doc_signature_generator</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html">pytype_function.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#wrap_pytype-spec">wrap_pytype</a></dt>
+
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#expected_from_python_type-spec">expected_from_python_type</a></dt>
+
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#to_python_target_type-spec">to_python_target_type</a></dt>
+
+ </dl>
+ <dl class="index">
+ <dt><a href=
+ "pytype_function.html#registered_pytype-spec">registered_pytype</a></dt>
+
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dd>
+ <a name="models_of_call_policies"></a>
+
+ <h3>Models of CallPolicies</h3>
+
+ <dl class="index">
+ <dt><a href=
+ "default_call_policies.html">default_call_policies.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "default_call_policies.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "default_call_policies.html#default_call_policies-spec">default_call_policies</a></dt>
+
+ <dt><a href=
+ "default_call_policies.html#default_result_converter-spec">default_result_converter</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="return_arg.html">return_arg.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="return_arg.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "return_arg.html#return_arg-spec">return_arg</a></dt>
+
+ <dt><a href=
+ "return_arg.html#return_self-spec">return_self</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "return_internal_reference.html">return_internal_reference.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "return_internal_reference.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "return_internal_reference.html#return_internal_reference-spec">
+ return_internal_reference</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "return_value_policy.html">return_value_policy.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="return_value_policy.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "return_value_policy.html#return_value_policy-spec">return_value_policy</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "with_custodian_and_ward.html">with_custodian_and_ward.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "with_custodian_and_ward.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "with_custodian_and_ward.html#with_custodian_and_ward-spec">
+ with_custodian_and_ward</a></dt>
+
+ <dt><a href=
+ "with_custodian_and_ward.html#with_custodian_and_ward_postcall-spec">
+ with_custodian_and_ward_postcall</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <a name="models_of_result_converter"></a>
+
+ <h3>Models of ResultConverter</h3>
+
+ <dl class="index">
+ <dt><a href=
+ "to_python_indirect.html">to_python_indirect.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="to_python_indirect.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="to_python_value.html">to_python_value.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="to_python_value.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "to_python_value.html#to_python_value-spec">to_python_value</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <a name="result_converter_generators"></a>
+
+ <h3>Models of ResultConverterGenerator</h3>
+
+ <dl class="index">
+ <dt><a href=
+ "copy_const_reference.html">copy_const_reference.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "copy_const_reference.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "copy_const_reference.html#copy_const_reference-spec">copy_const_reference</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "copy_non_const_reference.html">copy_non_const_reference.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "copy_non_const_reference.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "copy_non_const_reference.html#copy_non_const_reference-spec">
+ copy_non_const_reference</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="manage_new_object.html">manage_new_object.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="manage_new_object.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "manage_new_object.html#manage_new_object-spec">manage_new_object</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "reference_existing_object.html">reference_existing_object.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "reference_existing_object.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "reference_existing_object.html#reference_existing_object-spec">
+ reference_existing_object</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="return_by_value.html">return_by_value.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="return_by_value.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "return_by_value.html#return_by_value-spec">return_by_value</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "return_opaque_pointer.html">return_opaque_pointer.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "return_opaque_pointer.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "return_opaque_pointer.html#return_opaque_pointer-spec">return_opaque_pointer</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+
+ <h2><a name="type_conversion">To/From Python Type Conversion</a></h2>
+
+ <dl class="index">
+ <dt><a href="extract.html">extract.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="extract.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="extract.html#extract-spec">extract</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="implicit.html">implicit.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="implicit.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "implicit.html#implicitly_convertible-spec">implicitly_convertible</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="lvalue_from_pytype.html">lvalue_from_pytype.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="lvalue_from_pytype.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "lvalue_from_pytype.html#lvalue_from_pytype-spec">lvalue_from_pytype</a></dt>
+
+ <dt><a href=
+ "lvalue_from_pytype.html#extract_identity-spec">extract_identity</a></dt>
+
+ <dt><a href=
+ "lvalue_from_pytype.html#extract_member-spec">extract_member</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "opaque.html">opaque_pointer_converter.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "opaque.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "opaque.html#opaque-spec">opaque</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="opaque.html#macros">Macros</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "opaque.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
+ BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="to_python_converter.html">to_python_converter.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="to_python_converter.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "to_python_converter.html#to_python_converter-spec">to_python_converter</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href=
+ "register_ptr_to_python.html">register_ptr_to_python.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "register_ptr_to_python.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "register_ptr_to_python.html#register_ptr_to_python-spec">register_ptr_to_python</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+
+ <h2><a name="embedding">Embedding</a></h2>
+
+ <dl class="index">
+ <dt><a href="exec.html">exec.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="exec.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="exec.html#eval-spec">eval</a></dt>
+ <dt><a href="exec.html#exec-spec">exec</a></dt>
+ <dt><a href="exec.html#exec_file-spec">exec_file</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="import.html">import.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="import.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="import.html#import-spec">import</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+
+ <h2><a name="utility">Utility and Infrastructure</a></h2>
+
+ <dl>
+ <dt><a href="has_back_reference.html">has_back_reference.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="has_back_reference.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "has_back_reference.html#has_back_reference-spec">has_back_reference</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="instance_holder.html">instance_holder.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="instance_holder.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href=
+ "instance_holder.html#instance_holder-spec">instance_holder</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="pointee.html">pointee.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="pointee.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt>class template <a href=
+ "pointee.html#pointee-spec">pointee</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="python.html">&lt;boost/python.hpp&gt;</a></dt>
+
+ <dt><a href="handle.html">handle.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="handle.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="handle.html#handle-spec">handle</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="handle.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="handle.html#borrowed-spec">borrowed</a></dt>
+
+ <dt><a href="handle.html#allow_null-spec">allow_null</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="type_id.html">type_id.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="type_id.html#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="type_id.html#type_id-spec">type_id</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="type_id.html#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="type_id.html#type_info-spec">type_info</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="ssize_t.html">ssize_t.hpp</a></dt>
+
+ <dd>
+ <dl class="index">
+ <dt><a href="ssize_t.html#typedefs">Typedefs</a></dt>
+
+ <dt><a href="ssize_t.html#constants">Constants</a></dt>
+ </dl>
+ </dd>
+ </dl>
+
+ <h2><a name="topics">Topics</a></h2>
+
+ <dl>
+ <dt><a href="callbacks.html">Calling Python Functions and
+ Methods</a></dt>
+
+ <dt><a href="pickle.html">Pickle Support</a><br>
+ <a href="indexing.html">Indexing Support</a></dt>
+ </dl>
+ <hr>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 31 October, 2004
+<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p class="c3">&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002
+.</p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/reference_existing_object.html b/libs/python/doc/v2/reference_existing_object.html
new file mode 100644
index 000000000..12e228f50
--- /dev/null
+++ b/libs/python/doc/v2/reference_existing_object.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/reference_existing_object.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/reference_existing_object.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#reference_existing_object-spec">Class
+ <code>reference_existing_object</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#reference_existing_object-spec-synopsis">Class
+ <code>reference_existing_object</code> synopsis</a></dt>
+
+ <dt><a href=
+ "#reference_existing_object-spec-metafunctions">Class
+ <code>reference_existing_object</code> metafunctions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="reference_existing_object-spec"></a>Class
+ <code>reference_existing_object</code></h3>
+
+ <p><code>reference_existing_object</code> is a model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
+ 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 <font color=
+ "#ff0000"><b>highly dangerous</b></font> to use
+ <code>reference_existing_object</code> without additional lifetime
+ management from such models of <a href=
+ "CallPolicies.html">CallPolicies</a> as <a href=
+ "with_custodian_and_ward.html#with_custodian_and_ward-spec">with_custodian_and_ward</a>.
+ This class is used in the implementation of <a href=
+ "return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a>.</p>
+
+ <h4><a name="reference_existing_object-spec-synopsis"></a>Class
+ <code>reference_existing_object</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct reference_existing_object
+ {
+ template &lt;class T&gt; struct apply;
+ };
+}}
+</pre>
+
+ <h4><a name="reference_existing_object-spec-metafunctions"></a>Class
+ <code>reference_existing_object</code> metafunctions</h4>
+<pre>
+template &lt;class T&gt; struct apply
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Requires:</b> <code>T</code> is <code>U&amp;</code> or
+ <code>U*</code>for some <code>U</code>.</dt>
+
+ <dt><b>Returns:</b> <code>typedef <a href=
+ "to_python_indirect.html#to_python_indirect-spec">to_python_indirect</a>&lt;T,V&gt;
+ type</code>, where <code>V</code> is a class whose
+ static <code>execute</code> function constructs an instance
+ holder containing an <i>unowned</i>
+ <code>U*</code> pointing to the referent of the wrapped function's
+ return value.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <p>In C++:</p>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/reference_existing_object.hpp&gt;
+#include &lt;boost/python/return_value_policy.hpp&gt;
+#include &lt;utility&gt;
+
+// 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&amp; 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&lt;reference_existing_object&gt;());
+
+ class_&lt;Singleton&gt;("Singleton")
+ .def("exchange", &amp;Singleton::exchange)
+ ;
+}
+</pre>
+ In Python:
+<pre>
+&gt;&gt;&gt; import singleton
+&gt;&gt;&gt; s1 = singleton.get_it()
+&gt;&gt;&gt; s2 = singleton.get_it()
+&gt;&gt;&gt; id(s1) == id(s2) # s1 and s2 are not the same object
+0
+&gt;&gt;&gt; s1.exchange(42) # but they reference the same C++ Singleton
+0
+&gt;&gt;&gt; s2.exchange(99)
+42
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/register_ptr_to_python.html b/libs/python/doc/v2/register_ptr_to_python.html
new file mode 100644
index 000000000..5f660e18f
--- /dev/null
+++ b/libs/python/doc/v2/register_ptr_to_python.html
@@ -0,0 +1,162 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" type="text/css" href="../boost.css">
+<title>Boost.Python - &lt;register_ptr_to_python.hpp&gt;</title>
+</head>
+<body link="#0000ff" vlink="#800080">
+<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">Header &lt;register_ptr_to_python.hpp&gt;</h2>
+ </td>
+ </tr>
+</table>
+<hr>
+<h2>Contents</h2>
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ <dt><a href="#functions">Functions</a></dt>
+ <dl class="page-index">
+ <dt><a href="#register_ptr_to_python-spec">register_ptr_to_python</a></dt>
+ </dl>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+
+</dl>
+<hr>
+<h2><a name="introduction"></a>Introduction</h2>
+<p>
+ <code>&lt;boost/python/register_ptr_to_python.hpp&gt;</code>
+ supplies <code>register_ptr_to_python</code>, 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.
+</p>
+<p>
+ Note that in order to convert a Python <code>X</code> object to a
+ <code>smart_ptr&lt;X&gt;&amp;</code> (non-const reference), the embedded C++
+ object must be held by <code>smart_ptr&lt;X&gt;</code>, and that when wrapped
+ objects are created by calling the constructor from Python, how they are held
+ is determined by the <code>HeldType</code> parameter to
+ <code>class_&lt;...&gt;</code> instances.
+</p>
+
+<h2><a name="functions"></a>Functions</h2>
+<pre>
+<a name="register_ptr_to_python-spec">template &lt;class P&gt;
+void register_ptr_to_python()
+</pre>
+<dl class="function-semantics">
+ <dt><b>Requires:</b> <code>P</code> is <a href="Dereferenceable.html#Dereferenceable-concept">Dereferenceable</a>.
+ </dt>
+ <dt><b>Effects:</b> Allows conversions to-python of <code>P</code>
+ instances.
+ </dt>
+</dl>
+
+<h2><a name="examples"></a>Example(s)</h2>
+
+<h3>C++ Wrapper Code</h3>
+
+Here is an example of a module that contains a class <code>A</code> with
+virtual functions and some functions that work with
+<code>boost::shared_ptr&lt;A&gt;</code>.
+
+<pre>
+struct A
+{
+ virtual int f() { return 0; }
+};
+
+shared_ptr&lt;A&gt; New() { return shared_ptr&lt;A&gt;( new A() ); }
+
+int Ok( const shared_ptr&lt;A&gt;&amp; a ) { return a-&gt;f(); }
+
+int Fail( shared_ptr&lt;A&gt;&amp; a ) { return a-&gt;f(); }
+
+struct A_Wrapper: A
+{
+ A_Wrapper(PyObject* self_): self(self_) {}
+ int f() { return call_method&lt;int&gt;(self, "f"); }
+ int default_f() { return A::f(); }
+ PyObject* self;
+};
+
+BOOST_PYTHON_MODULE(register_ptr)
+{
+ class_&lt;A, A_Wrapper&gt;("A")
+ .def("f", &amp;A::f, &amp;A_Wrapper::default_f)
+ ;
+
+ def("New", &amp;New);
+ def("Ok", &amp;Call);
+ def("Fail", &amp;Fail);
+
+ register_ptr_to_python&lt; shared_ptr&lt;A&gt; &gt;();
+}
+</pre>
+
+<h3>Python Code</h3>
+
+<pre>
+&gt;&gt;&gt; from register_ptr import *
+&gt;&gt;&gt; a = A()
+&gt;&gt;&gt; Ok(a) # ok, passed as shared_ptr&lt;A&gt;
+0
+&gt;&gt;&gt; Fail(a) # passed as shared_ptr&lt;A&gt;&amp;, and was created in Python!
+Traceback (most recent call last):
+ File "&lt;stdin&gt;", line 1, in ?
+TypeError: bad argument type for built-in operation
+&gt;&gt;&gt;
+&gt;&gt;&gt; na = New() # now "na" is actually a shared_ptr&lt;A&gt;
+&gt;&gt;&gt; Ok(a)
+0
+&gt;&gt;&gt; Fail(a)
+0
+&gt;&gt;&gt;
+</pre>
+
+If <code>shared_ptr&lt;A&gt;</code> is registered as follows:
+
+<pre>
+ class_&lt;A, A_Wrapper, shared_ptr&lt;A&gt; &gt;("A")
+ .def("f", &amp;A::f, &amp;A_Wrapper::default_f)
+ ;
+</pre>
+
+There will be an error when trying to convert <code>shared_ptr&lt;A&gt;</code> to
+<code>shared_ptr&lt;A_Wrapper&gt;</code>:
+
+<pre>
+&gt;&gt;&gt; a = New()
+Traceback (most recent call last):
+File "&lt;stdin&gt;", line 1, in ?
+TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr&lt;struct A&gt;
+&gt;&gt;&gt;
+</pre>
+
+<p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 24 Jun, 2003
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+</p>
+<p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
+ 2002. </i></p>
+</body>
+</html>
+
+
diff --git a/libs/python/doc/v2/return_arg.html b/libs/python/doc/v2/return_arg.html
new file mode 100644
index 000000000..44cd58c24
--- /dev/null
+++ b/libs/python/doc/v2/return_arg.html
@@ -0,0 +1,224 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/return_arg.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/return_arg.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_arg-spec">Class Template
+ <code>return_arg</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_arg-spec-synopsis">Class Template
+ <code>return_arg</code> synopsis</a></dt>
+
+ <dt><a href="#return_arg-spec-statics">Class
+ <code>return_arg</code> static functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#return_self-spec">Class Template
+ <code>return_self</code></a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+ <code>return_arg</code> and <code>return_self</code> instantiations are
+ models of <a href="CallPolicies.html">CallPolicies</a> which return the
+ specified argument parameter (usually <code>*this</code>) of a wrapped
+ (member) function.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="return_arg-spec"></a>Class template
+ <code>return_arg</code></h3>
+
+ <table border="1" summary="return_arg template parameters">
+ <caption>
+ <b><code>return_arg</code> template parameters</b>
+ </caption>
+
+ <tr>
+ <th>Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Description</th>
+
+ <th>Default</th>
+ </tr>
+
+ <tr>
+ <td><code>arg_pos</code></td>
+
+ <td>A positive compile-time constant of type
+ <code>std::size_t</code>.</td>
+
+ <td>the position of the argument to be returned.</td>
+
+ <td>1</td>
+ </tr>
+
+ <tr>
+ <td><code>Base</code></td>
+
+ <td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
+
+ <td>Used for policy composition. Any <code>result_converter</code> it
+ supplies will be overridden by <code>return_arg</code>, but its
+ <code>precall</code> and <code>postcall</code> policies are composed
+ as described here <a href=
+ "CallPolicies.html#composition">CallPolicies</a>.</td>
+
+ <td><code><a href=
+ "default_call_policies.html#default_call_policies-spec">default_call_policies</a></code></td>
+ </tr>
+ </table>
+
+ <h4><a name="return_arg-spec-synopsis"></a>Class template
+ <code>return_arg</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;size_t arg_pos=1, class Base = default_call_policies&gt;
+ struct return_arg : Base
+ {
+ static PyObject* postcall(PyObject*, PyObject* result);
+ struct result_converter{ template &lt;class T&gt; struct apply; };
+ template &lt;class Sig&gt; struct extract_return_type : mpl::at_c&lt;Sig, arg_pos&gt;{};
+
+ };
+}}
+</pre>
+
+ <h4><a name="return_arg-spec-statics"></a>Class <code>return_arg</code>
+ static functions</h4>
+<pre>
+PyObject* postcall(PyObject* args, PyObject* result);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code><a href=
+ "http://www.python.org/doc/2.2/api/tupleObjects.html#l2h-476">PyTuple_Check</a>(args)
+ != 0</code> and <code>PyTuple_Size(args) != 0</code></dt>
+
+ <dt><b>Returns:</b> <code>PyTuple_GetItem(args,arg_pos-1)</code></dt>
+ </dl>
+
+ <h3><a name="return_self-spec"></a>Class template
+ <code>return_self</code></h3>
+
+ <h4>Class template <code>return_self</code> synopsis:</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class Base = default_call_policies&gt;
+ struct return_self
+ : return_arg&lt;1,Base&gt;
+ {};
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/return_arg.hpp&gt;
+
+struct Widget
+{
+ Widget() :sensitive_(true){}
+ bool get_sensitive() const { return sensitive_; }
+ void set_sensitive(bool s) { this-&gt;sensitive_ = s; }
+ private:
+ bool sensitive_;
+};
+
+struct Label : Widget
+{
+ Label() {}
+
+ std::string get_label() const { return label_; }
+ void set_label(const std::string &amp;l){ label_ = l; }
+
+ private:
+ std::string label_;
+};
+
+using namespace boost::python;
+BOOST_PYTHON_MODULE(return_self_ext)
+{
+ class_&lt;widget&gt;("Widget")
+ .def("sensitive", &amp;Widget::get_sensitive)
+ .def("sensitive", &amp;Widget::set_sensitive, return_self&lt;&gt;())
+ ;
+
+ class_&lt;Label, bases&lt;Widget&gt; &gt;("Label")
+ .def("label", &amp;Label::get_label)
+ .def("label", &amp;Label::set_label, return_self&lt;&gt;())
+ ;
+}
+
+
+</pre>
+
+ <h3>Python code</h3>
+<pre>
+&gt;&gt;&gt; from return_self_ext import *
+&gt;&gt;&gt; l1 = Label().label("foo").sensitive(false)
+&gt;&gt;&gt; l2 = Label().sensitive(false).label("foo")
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 19 July, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> and Nikolay
+ Mladenov 2003. </i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/return_by_value.html b/libs/python/doc/v2/return_by_value.html
new file mode 100644
index 000000000..12ca3c43f
--- /dev/null
+++ b/libs/python/doc/v2/return_by_value.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/return_by_value.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/return_by_value.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_by_value-spec">Class
+ <code>return_by_value</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_by_value-spec-synopsis">Class
+ <code>return_by_value</code> synopsis</a></dt>
+
+ <dt><a href="#return_by_value-spec-metafunctions">Class
+ <code>return_by_value</code> metafunctions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="return_by_value-spec"></a>Class
+ <code>return_by_value</code></h3>
+
+ <p><code>return_by_value</code> is a model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
+ 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.</p>
+
+ <h4><a name="return_by_value-spec-synopsis"></a>Class
+ <code>return_by_value</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct return_by_value
+ {
+ template &lt;class T&gt; struct apply;
+ };
+}}
+</pre>
+
+ <h4><a name="return_by_value-spec-metafunctions"></a>Class
+ <code>return_by_value</code> metafunctions</h4>
+<pre>
+template &lt;class T&gt; struct apply
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Returns:</b> <code>typedef <a href=
+ "to_python_value.html#to_python_value-spec">to_python_value</a>&lt;T&gt;
+ type;</code></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ Module Definition</h3>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/return_by_value.hpp&gt;
+#include &lt;boost/python/return_value_policy.hpp&gt;
+
+// classes to wrap
+struct Bar { };
+
+Bar global_bar;
+
+// functions to wrap:
+Bar b1();
+Bar&amp; b2();
+Bar const&amp; b3();
+
+// Wrapper code
+using namespace boost::python;
+template &lt;class R&gt;
+void def_void_function(char const* name, R (*f)())
+{
+ def(name, f, return_value_policy&lt;return_by_value&gt;());
+}
+
+BOOST_PYTHON_MODULE(my_module)
+{
+ class_&lt;Bar&gt;("Bar");
+ def_void_function("b1", b1);
+ def_void_function("b2", b2);
+ def_void_function("b3", b3);
+}
+</pre>
+
+ <h3>Python Code</h3>
+<pre>
+&gt;&gt;&gt; from my_module import *
+&gt;&gt;&gt; b = b1() # each of these calls
+&gt;&gt;&gt; b = b2() # creates a brand
+&gt;&gt;&gt; b = b3() # new Bar object
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/return_internal_reference.html b/libs/python/doc/v2/return_internal_reference.html
new file mode 100644
index 000000000..87c33f855
--- /dev/null
+++ b/libs/python/doc/v2/return_internal_reference.html
@@ -0,0 +1,230 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/return_internal_reference.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/return_internal_reference.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_internal_reference-spec">Class Template
+ <code>return_internal_reference</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_internal_reference-spec-synopsis">Class
+ Template <code>return_internal_reference</code>
+ synopsis</a></dt>
+
+ <dt><a href="#return_internal_reference-spec-statics">Class
+ <code>return_internal_reference</code> static
+ functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+ <code>return_internal_reference</code> instantiations are models of <a
+ href="CallPolicies.html">CallPolicies</a> 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 (<code>*this</code>) of a wrapped member function.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="return_internal_reference-spec"></a>Class template
+ <code>return_internal_reference</code></h3>
+
+ <table border="1" summary=
+ "return_internal_reference template parameters">
+ <caption>
+ <b><code>return_internal_reference</code> template parameters</b>
+ </caption>
+
+ <tr>
+ <th>Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Description</th>
+
+ <th>Default</th>
+ </tr>
+
+ <tr>
+ <td><code>owner_arg</code></td>
+
+ <td>A positive compile-time constant of type
+ <code>std::size_t</code>.</td>
+
+ <td>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 (<code>*this</code>). Note
+ that if the target Python object type doesn't support weak
+ references, a Python <code>TypeError</code> exception will be raised
+ when the function being wrapped is called.</td>
+
+ <td>1</td>
+ </tr>
+
+ <tr>
+ <td><code>Base</code></td>
+
+ <td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
+
+ <td>Used for policy composition. Any <code>result_converter</code> it
+ supplies will be overridden by
+ <code>return_internal_reference</code>, but its <code>precall</code>
+ and <code>postcall</code> policies are composed as described here <a
+ href="CallPolicies.html#composition">CallPolicies</a>.</td>
+
+ <td><code><a href=
+ "default_call_policies.html#default_call_policies-spec">default_call_policies</a></code></td>
+ </tr>
+ </table>
+
+ <h4><a name="return_internal_reference-spec-synopsis"></a>Class template
+ <code>return_internal_reference</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;std::size_t owner_arg = 1, class Base = default_call_policies&gt;
+ struct return_internal_reference : Base
+ {
+ static PyObject* postcall(PyObject*, PyObject* result);
+ typedef <a href=
+"reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a> result_converter;
+ };
+}}
+</pre>
+
+ <h4><a name="return_internal_reference-spec-statics"></a>Class
+ <code>return_internal_reference</code> static functions</h4>
+<pre>
+PyObject* postcall(PyObject* args, PyObject* result);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code><a href=
+ "http://www.python.org/doc/2.2/api/tupleObjects.html#l2h-476">PyTuple_Check</a>(args)
+ != 0</code></dt>
+
+ <dt><b>Returns:</b> <code><a href=
+ "with_custodian_and_ward.html#with_custodian_and_ward_postcall-spec-statics">
+ with_custodian_and_ward_postcall::postcall(args,
+ result)</a></code></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/return_internal_reference.hpp&gt;
+
+class Bar
+{
+ public:
+ Bar(int x) : x(x) {}
+ int get_x() const { return x; }
+ void set_x(int x) { this-&gt;x = x; }
+ private:
+ int x;
+};
+
+class Foo
+{
+ public:
+ Foo(int x) : b(x) {}
+
+ // Returns an internal reference
+ Bar const&amp; get_bar() const { return b; }
+
+ private:
+ Bar b;
+};
+
+using namespace boost::python;
+BOOST_PYTHON_MODULE(internal_refs)
+{
+ class_&lt;Bar&gt;("Bar", init&lt;int&gt;())
+ .def("get_x", &amp;Bar::get_x)
+ .def("set_x", &amp;Bar::set_x)
+ ;
+
+ class_&lt;Foo&gt;("Foo", init&lt;int&gt;())
+ .def("get_bar", &amp;Foo::get_bar
+ , return_internal_reference&lt;&gt;())
+ ;
+}
+</pre>
+
+ <h3>Python code</h3>
+<pre>
+&gt;&gt;&gt; from internal_refs import *
+&gt;&gt;&gt; f = Foo(3)
+&gt;&gt;&gt; b1 = f.get_bar()
+&gt;&gt;&gt; b2 = f.get_bar()
+&gt;&gt;&gt; b1.get_x()
+3
+&gt;&gt;&gt; b2.get_x()
+3
+&gt;&gt;&gt; b1.set_x(42)
+&gt;&gt;&gt; b2.get_x()
+42
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/return_opaque_pointer.html b/libs/python/doc/v2/return_opaque_pointer.html
new file mode 100644
index 000000000..52d8396e8
--- /dev/null
+++ b/libs/python/doc/v2/return_opaque_pointer.html
@@ -0,0 +1,192 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/return_opaque_pointer.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/return_opaque_pointer.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_opaque_pointer-spec">Class
+ <code>return_opaque_pointer</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_opaque_pointer-spec-synopsis">Class
+ <code>return_opaque_pointer</code> synopsis</a></dt>
+
+ <dt><a href="#return_opaque_pointer-spec-metafunctions">Class
+ <code>return_opaque_pointer</code> metafunctions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+
+ <dt><a href="#see-also">See Also</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="return_opaque_pointer-spec"></a>Class
+ <code>return_opaque_pointer</code></h3>
+
+ <p><code>return_opaque_pointer</code> is a model of
+ <a href="ResultConverter.html#ResultConverterGenerator-concept">
+ ResultConverterGenerator</a>
+ 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.</p>
+ <p>In addition to specifying the <code>return_opaque_pointer</code>
+ policy the <a href="opaque.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
+ <code>BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</code></a> macro must be
+ used to define specializations for the
+ <a href="type_id.html#type_id-spec">type_id</a> function
+ on the type pointed to by returned pointer.</p>
+
+ <h4><a name="return_opaque_pointer-spec-synopsis"></a>Class
+ <code>return_opaque_pointer</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ struct return_opaque_pointer
+ {
+ template &lt;class R&gt; struct apply;
+ };
+}}
+</pre>
+
+ <h4><a name="return_opaque_pointer-spec-metafunctions"></a>Class
+ <code>return_opaque_pointer</code> metafunctions</h4>
+<pre>
+template &lt;class R&gt; struct apply
+</pre>
+
+ <dl class="metafunction-semantics">
+ <dt><b>Returns:</b> <code>typedef
+ detail::opaque_conversion_holder&lt;R&gt;
+ type;</code></dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ Module Definition</h3>
+<pre>
+# include &lt;boost/python/return_opaque_pointer.hpp&gt;
+# include &lt;boost/python/def.hpp&gt;
+# include &lt;boost/python/module.hpp&gt;
+# include &lt;boost/python/return_value_policy.hpp&gt;
+
+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&lt;bpl::return_opaque_pointer&gt;());
+ bpl::def ("use", &::use);
+ bpl::def ("failuse", &::failuse);
+}
+</pre>
+
+ <h3>Python Code</h3>
+<pre>
+"""
+>>> 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])
+</pre>
+
+ <h2><a name="see-also"></a>See Also</h2>
+ <p>
+ <a href="opaque.html">
+ opaque</a>
+ </p>
+
+ <p>Revised
+ 28 January, 2003
+ </p>
+
+ <p><i>&copy; Copyright 2003 Haufe Mediengruppe. All Rights
+ Reserved.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/return_value_policy.html b/libs/python/doc/v2/return_value_policy.html
new file mode 100644
index 000000000..b02d4bc39
--- /dev/null
+++ b/libs/python/doc/v2/return_value_policy.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/return_value_policy.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/return_value_policy.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_value_policy-spec">Class Template
+ <code>return_value_policy</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#return_value_policy-spec-synopsis">Class Template
+ <code>return_value_policy</code> synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+ <code>return_value_policy</code> instantiations are simply models of <a
+ href="CallPolicies.html">CallPolicies</a> which are composed of a <a
+ href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
+ and optional <code>Base</code> <a href=
+ "CallPolicies.html">CallPolicies</a>.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="return_value_policy-spec"></a>Class template
+ <code>return_value_policy</code></h3>
+
+ <table border="1" summary="return_value_policy template parameters">
+ <caption>
+ <b><code>return_value_policy</code> template parameters</b>
+ </caption>
+
+ <tr>
+ <th>Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Default</th>
+ </tr>
+
+ <tr>
+ <td><a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a></td>
+
+ <td>A model of <a href=
+ "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code>Base</code></td>
+
+ <td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
+
+ <td><code><a href=
+ "default_call_policies.html#default_call_policies-spec">default_call_policies</a></code></td>
+ </tr>
+ </table>
+
+ <h4><a name="return_value_policy-spec-synopsis"></a>Class template
+ <code>return_value_policy</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class ResultConverterGenerator, class Base = default_call_policies&gt;
+ struct return_value_policy : Base
+ {
+ typedef ResultConverterGenerator result_converter;
+ };
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example</h2>
+
+ <h3>C++ Module Definition</h3>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/copy_const_reference.hpp&gt;
+#include &lt;boost/python/return_value_policy.hpp&gt;
+
+// classes to wrap
+struct Bar { int x; }
+
+struct Foo {
+ Foo(int x) : { b.x = x; }
+ Bar const&amp; get_bar() const { return b; }
+ private:
+ Bar b;
+};
+
+// Wrapper code
+using namespace boost::python;
+BOOST_PYTHON_MODULE(my_module)
+{
+ class_&lt;Bar&gt;("Bar");
+
+ class_&lt;Foo&gt;("Foo", init&lt;int&gt;())
+ .def("get_bar", &amp;Foo::get_bar
+ , return_value_policy&lt;copy_const_reference&gt;())
+ ;
+}
+</pre>
+
+ <h3>Python Code</h3>
+<pre>
+&gt;&gt;&gt; from my_module import *
+&gt;&gt;&gt; f = Foo(3) # create a Foo object
+&gt;&gt;&gt; b = f.get_bar() # make a copy of the internal Bar object
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/scope.html b/libs/python/doc/v2/scope.html
new file mode 100644
index 000000000..54ef67e3e
--- /dev/null
+++ b/libs/python/doc/v2/scope.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/scope.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/scope.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#scope-spec">Class <code>scope</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#scope-spec-synopsis">Class <code>scope</code>
+ synopsis</a></dt>
+
+ <dt><a href="#scope-spec-ctors">Class <code>scope</code>
+ constructors and destructor</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Defines facilities for querying and controlling the Python scope
+ (namespace) which will contain new wrapped classes and functions.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="scope-spec"></a>Class <code>scope</code></h3>
+
+ <p>The <code>scope</code> 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 <code>scope</code> object
+ binds it to the associated global Python object. Constructing a
+ <code>scope</code> object with an argument changes the associated
+ global Python object to the one held by the argument, until the
+ lifetime of the <code>scope</code> object ends, at which time the
+ associated global Python object reverts to what it was before the
+ <code>scope</code> object was constructed.</p>
+
+ <h4><a name="scope-spec-synopsis"></a>Class <code>scope</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class scope : public <a href=
+"object.html#object-spec">object</a>
+ {
+ public:
+ scope(scope const&amp;);
+ scope(object const&amp;);
+ scope();
+ ~scope()
+ private:
+ void operator=(scope const&amp;);
+ };
+}}
+</pre>
+
+ <h4><a name="scope-spec-ctors"></a>Class <code>scope</code> constructors
+ and destructor</h4>
+<pre>
+explicit scope(scope const&amp; x);
+explicit scope(object const&amp; x);
+</pre>
+ Stores a reference to the current associated scope object, and sets the
+ associated scope object to the one referred to by <code>x.ptr()</code>.
+ The <code>object</code> base class is initialized with <code>x</code>.
+<pre>
+scope();
+</pre>
+ Stores a reference to the current associated scope object. The
+ <code>object</code> base class is initialized with the current associated
+ scope object. Outside any module initialization function, the current
+ associated Python object is <code>None</code>.
+<pre>
+~scope()
+</pre>
+ Sets the current associated Python object to the stored object.
+
+ <h2><a name="examples"></a>Example</h2>
+ The following example shows how scope setting can be used to define
+ nested classes.
+
+ <p>C++ Module definition:</p>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/scope.hpp&gt;
+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_&lt;X&gt;("X")
+ .def("f", &amp;X::f)
+ ;
+
+ // Define a class Y in the current scope, X
+ class_&lt;X::Y&gt;("Y")
+ .def("g", &amp;X::Y::g)
+ ;
+}
+</pre>
+ Interactive Python:
+<pre>
+&gt;&gt;&gt; import nested
+&gt;&gt;&gt; nested.yes
+1
+&gt;&gt;&gt; y = nested.X.Y()
+&gt;&gt;&gt; y.g()
+42
+</pre>
+
+ <p>Revised 09 October, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/slice.html b/libs/python/doc/v2/slice.html
new file mode 100644
index 000000000..fb6b47c7e
--- /dev/null
+++ b/libs/python/doc/v2/slice.html
@@ -0,0 +1,246 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+ <meta name="generator"
+ content="HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+ <title>Boost.Python - &lt;boost/python/slice.hpp&gt;</title>
+</head>
+<body>
+<table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tbody>
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+ <h2 align="center">Header &lt;boost/python/slice.hpp&gt;</h2>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<hr>
+<h2>Contents</h2>
+<dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+ <dt><a href="#classes">Classes</a></dt>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#slice-spec">Class <code>slice</code></a></dt>
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#slice-spec-synopsis">Class <code>slice</code>
+synopsis</a></dt>
+ <dt><a href="#slice-spec-ctors">Class <code>slice</code>
+constructors</a></dt>
+ <dt><a href="#slice-spec-observers">Class <code>slice</code>
+observer functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ <dt><a href="#examples">Example(s)</a></dt>
+</dl>
+<hr>
+<h2><a name="introduction"></a>Introduction</h2>
+<p>Exposes a <a href="ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a>
+for the Python <a
+ href="http://www.python.org/doc/2.3.3/api/slice-objects.html">slice</a>
+type.</p>
+<h2><a name="classes"></a>Classes</h2>
+<h3><a name="slice-spec"></a>Class <code>slice</code></h3>
+<p>Exposes the extended slicing protocol by wrapping the built-in slice
+type. The semantics of the constructors and member functions defined
+below can be fully understood by reading the <a
+ href="ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
+definition. Since <code>slice</code> is publicly derived from <code><a
+ href="object.html#object-spec">object</a></code>, the public object
+interface applies to <code>slice</code> instances as well.<br>
+</p>
+<h4><a name="slice-spec-synopsis"></a>Class <code>slice</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class slice : public object
+ {
+ public:
+ slice(); // create an empty slice, equivalent to [::]
+
+ template &lt;typename Int1, typename Int2&gt;
+ slice(Int1 start, Int2 stop);
+
+ template &lt;typename Int1, typename Int2, typename Int3&gt;
+ slice(Int1 start, Int2 stop, Int3 step);
+
+ // Access the parameters this slice was created with.
+ object start();
+ object stop();
+ object step();
+
+ // The return type of slice::get_indices()
+ template &lt;typename RandomAccessIterator&gt;
+ struct range
+ {
+ RandomAccessIterator start;
+ RandomAccessIterator stop;
+ int step;
+ };
+
+ template &lt;typename RandomAccessIterator&gt;
+ range&lt;RandomAccessIterator&gt;
+ get_indices(
+ RandomAccessIterator const&amp; begin,
+ RandomAccessIterator const&amp; end);
+ };
+}}
+</pre>
+<h4><a name="slice-spec-ctors"></a>Class <code>slice</code>
+constructors<br>
+</h4>
+<pre>slice();<br></pre>
+<dl class="function-semantics">
+ <dt><b>Effects:</b> constructs a <code>slice</code> with default stop, start, and
+step values.&nbsp; Equivalent to the slice object created as part of the Python
+expression <code>base[::].</code></dt>
+ <dt><b>Throws:</b> nothing.</dt>
+</dl>
+<pre>
+template &lt;typename Int1, typename Int2&gt;
+slice(Int1 start, Int2 stop);
+</pre>
+<dl class="function-semantics">
+ <dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code>
+ are of type <code><a href="object.html#slice_nil-spec">slice_nil</a></code>
+ or convertible to type <code>object</code>.</dt>
+ <dt><b>Effects:</b> constructs a new slice with default step value
+and the provided start and stop values.&nbsp; Equivalent to the slice
+object
+created by the built-in Python function <code><a
+ href="http://www.python.org/doc/current/lib/built-in-funcs.html#12h-62">slice(start,stop)</a></code>,
+or as part of the Python expression <code>base[start:stop]</code>.</dt>
+ <dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
+exception if no conversion is possible from the arguments to type <code>object</code>.</dt>
+</dl>
+<pre>
+template &lt;typename Int1, typename Int2, typename Int3&gt;
+slice(Int1 start, Int2 stop, Int3 step);
+</pre>
+ <dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code> are <code>slice_nil</code> or convertible to type <code>object</code>.</dt>
+ <dt><b>Effects:</b> constructs a new slice with start stop and step
+values.&nbsp; Equivalent to the slice object created
+by the built-in Python function <code><a
+ href="http://www.python.org/doc/current/lib/built-in-funcs.html">slice(start,stop,step)</a></code>,
+or as part of the Python expression <code>base[start:stop:step]</code>.</dt>
+ <dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
+exception if no conversion is possible from the arguments to type
+object.</dt>
+<h4><a name="slice-spec-observers"></a>Class <code>slice</code>
+observer functions<br>
+</h4>
+<pre>
+object slice::start() const;
+object slice::stop() const;
+object slice::step() const;
+</pre>
+<dl class="function-semantics">
+ <dt><b>Effects:</b> None.</dt>
+ <dt><b>Throws:</b> nothing.</dt>
+ <dt><b>Returns:</b>the parameter that
+the slice was created with.&nbsp;If the parameter was omitted or
+slice_nil was used when the slice was created, than that parameter will
+be a reference to PyNone and compare equal to a default-constructed
+object.&nbsp; In principal, any object may be used when creating a
+slice object, but in practice they are usually integers.</dt>
+</dl>
+<br>
+<pre>
+template &lt;typename RandomAccessIterator&gt;
+slice::range&lt;RandomAccessIterator&gt;
+slice::get_indices(
+ RandomAccessIterator const&amp; begin,
+ RandomAccessIterator const&amp; end) const;
+</pre>
+<dl class="function-semantics">
+ <dt><b>Arguments:</b> A pair of STL-conforming Random Access
+Iterators that form a half-open range.</dt>
+ <dt><b>Effects:</b> Create a RandomAccessIterator pair that defines a
+fully-closed range within the [begin,end) range of its arguments.&nbsp;
+This function translates this slice's indices while accounting for the
+effects of any PyNone or negative indices, and non-singular step sizes.</dt>
+ <dt><b>Returns:</b> a slice::range
+that has been initialized with a non-zero value of step and a pair of
+RandomAccessIterators that point within the range of this functions
+arguments and define a closed interval.</dt>
+ <dt><b>Throws:</b> <a href="definitions.html#raise">Raises</a> a Python <code>TypeError</code> exception if any of this slice's arguments
+are neither references to <code>PyNone</code> nor convertible to <code>int</code>.&nbsp; Throws
+<code>std::invalid_argument</code> if the resulting range would be empty.&nbsp; You
+should always wrap calls to <code>slice::get_indices()</code>
+within <code>try { ...; } catch (std::invalid_argument) {}</code> to
+handle this case and take appropriate action.</dt>
+ <dt><b>Rationale</b>: closed-interval: If
+an open interval were used, then for step
+size other than 1, the required state for the end iterator would point
+beyond the one-past-the-end position or before the beginning of the
+specified range.<br>
+exceptions on empty slice: It is impossible to define a closed interval
+over an empty range, so some other form of error checking would have to
+be used to prevent undefined behavior.&nbsp;In the case where the
+exception is not caught, it will simply be translated to Python by the
+default exception handling mechanisms. </dt>
+</dl>
+<h2><a name="examples"></a><b>Examples</b></h2>
+<pre>
+using namespace boost::python;
+
+// Perform an extended slice of a Python list.
+// Warning: extended slicing was not supported for built-in types prior
+// to Python 2.3
+list odd_elements(list l)
+{
+ return l[slice(_,_,2)];
+}
+
+// Perform a multidimensional extended slice of a Numeric.array
+numeric::array even_columns(numeric::array arr)
+{
+ // select every other column, starting with the second, of a 2-D array.
+ // Equivalent to "return arr[:, 1::2]" in Python.
+ return arr[make_tuple( slice(), slice(1,_,2))];
+}
+
+// Perform a summation over a slice of a std::vector.
+double partial_sum(std::vector&lt;double&gt; const&amp; Foo, const slice index)
+{
+ slice::range&lt;std::vector&lt;double&gt;::const_iterator&gt; bounds;
+ try {
+ bounds = index.get_indices&lt;&gt;(Foo.begin(), Foo.end());
+ }
+ catch (std::invalid_argument) {
+ return 0.0;
+ }
+ double sum = 0.0;
+ while (bounds.start != bounds.stop) {
+ sum += *bounds.start;
+ std::advance( bounds.start, bounds.step);
+ }
+ sum += *bounds.start;
+ return sum;
+}
+</pre>
+<p>Revised 07 Febuary, 2004</p>
+<p><i>&copy; Copyright <a
+ href="mailto:jbrandmeyer@users.sourceforge.net">Jonathan Brandmeyer</a>,
+2004.&nbsp; Modification, copying and redistribution of this document
+is permitted under the terms and conditions of the Boost Software
+License, version 1.0.<br>
+</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/ssize_t.html b/libs/python/doc/v2/ssize_t.html
new file mode 100644
index 000000000..cb4398bb5
--- /dev/null
+++ b/libs/python/doc/v2/ssize_t.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+
+<html>
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org">
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/ssize_t.hpp&gt;</title>
+</head>
+
+<body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href=
+ "../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/ssize_t.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#typdefs">Typedef</a></dt>
+
+ <dt><a href="#macros">Constants</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction" id=
+ "introduction"></a>Introduction</h2>
+
+ <p>Python 2.5 introduces a new <tt>Py_ssize_t</tt> typedef and
+ two related macros (<a href=
+ "http://www.python.org/dev/peps/pep-0353/">PEP 353</a>). The
+ <tt>&lt;boost/python/ssize_t.hpp&gt;</tt> header imports these
+ definitions into the <tt>boost::python</tt> namespace as
+ <tt>ssize_t</tt>, <tt>ssize_t_max</tt>, and <tt>ssize_t_min</tt>.
+ Appropriate definitions are provided for backward compatibility
+ with previous Python versions.</p>
+
+ <h2><a name="typedefs" id="typedefs"></a>Typedefs</h2>Imports
+ <tt>Py_ssize_t</tt> into the <tt>boost::python</tt> namespace if
+ available, or provides an appropriate typedef for backward
+ compatibility:
+ <pre>
+#if PY_VERSION_HEX &gt;= 0x02050000
+typedef Py_ssize_t ssize_t;
+#else
+typedef int ssize_t;
+#endif
+</pre>
+
+ <h2><a name="constants" id="constants"></a>Constants</h2>Imports
+ <tt>PY_SSIZE_T_MAX</tt> and <tt>PY_SSIZE_T_MIN</tt> as constants
+ into the <tt>boost::python</tt> namespace if available, or
+ provides appropriate constants for backward compatibility:
+ <pre>
+#if PY_VERSION_HEX &gt;= 0x02050000
+ssize_t const ssize_t_max = PY_SSIZE_T_MAX;
+ssize_t const ssize_t_min = PY_SSIZE_T_MIN;
+#else
+ssize_t const ssize_t_max = INT_MAX;
+ssize_t const ssize_t_min = INT_MIN;
+#endif
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 25 September, 2006
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/ralf_w_grosse_kunstleve.htm">Ralf W.
+ Grosse-Kunstleve</a> 2006.</i></p>
+</body>
+</html>
diff --git a/libs/python/doc/v2/stl_iterator.html b/libs/python/doc/v2/stl_iterator.html
new file mode 100644
index 000000000..ef197b0f8
--- /dev/null
+++ b/libs/python/doc/v2/stl_iterator.html
@@ -0,0 +1,273 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+
+ <title>Boost.Python - &lt;boost/python/stl_iterator.hpp&gt;</title>
+ <meta name="generator" content=
+"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org" >
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+header >
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/stl_iterator.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#stl_input_iterator-spec">Class template
+ <code>stl_input_iterator</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#stl_input_iterator-spec-synopsis">Class
+ <code>stl_input_iterator</code> synopsis</a></dt>
+
+ <dt><a href="#stl_input_iterator-spec-constructors">Class template
+ <code>stl_input_iterator</code> constructors</a></dt>
+
+ <dt><a href="#stl_input_iterator-spec-modifiers">Class template
+ <code>stl_input_iterator</code> modifiers</a></dt>
+
+ <dt><a href="#stl_input_iterator-spec-observers">Class template
+ <code>stl_input_iterator</code> observers</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Examples</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/stl_iterator.hpp&gt;</code> provides types
+ for creating <a href="http://www.sgi.com/tech/stl/Iterators.html">C++
+ Iterators</a> from <a href="http://www.python.org/doc/current/lib/typeiter.html">
+ Python iterables</a>.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="stl_input_iterator-spec"></a>Class Template
+ <code>stl_input_iterator</code></h3>
+
+ <p>Instances of <code>stl_input_iterator&lt;T&gt;</code> hold a Python
+ iterator and adapt it for use with STL algorithms.
+ <code>stl_input_iterator&lt;T&gt;</code> satisfies the requirements for
+ an <a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.
+ </p>
+
+ <table border="1" summary="stl_input_iterator template parameters">
+ <tr>
+ <th>Template Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Semantics</th>
+
+ <th>Default</th>
+ </tr>
+
+ <tr>
+ <td><code>ValueType</code></td>
+
+ <td><code>ValueType</code> must be CopyConstructible.</td>
+
+ <td>Dereferencing an instance of <code>stl_input_iterator&lt;ValueType&gt;</code>
+ will return an rvalue of type <code>ValueType</code>.</td>
+
+ <td><i>None</i></td>
+ </tr>
+ </table>
+
+ <h4><a name="stl_input_iterator-spec-synopsis"></a>Class Template stl_input_iterator
+ synopsis</h4>
+
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class ValueType&gt;
+ struct stl_input_iterator
+ {
+ typedef std::ptrdiff_t difference_type;
+ typedef ValueType value_type;
+ typedef ValueType* pointer;
+ typedef ValueType reference;
+ typedef std::input_iterator_tag iterator_category;
+
+ stl_input_iterator();
+ stl_input_iterator(<a href="object.html#object-spec">object</a> const&amp; ob);
+
+ stl_input_iterator&amp; operator++();
+ stl_input_iterator operator++(int);
+
+ ValueType operator*() const;
+
+ friend bool operator==(stl_input_iterator const&amp; lhs, stl_input_iterator const&amp; rhs);
+ friend bool operator!=(stl_input_iterator const&amp; lhs, stl_input_iterator const&amp; rhs);
+ private:
+ <a href="object.html#object-spec">object</a> it; // For exposition only
+ <a href="object.html#object-spec">object</a> ob; // For exposition only
+ };
+}}
+</pre>
+
+ <h4>
+ <a name="stl_input_iterator-spec-constructors"></a>Class Template <code>stl_input_iterator</code>
+ constructors
+ </h4>
+
+<pre>
+stl_input_iterator()
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Creates a past-the-end input iterator, useful for signifying the end of a sequence.
+ </dt>
+ <dt><b>Postconditions:</b> <code>this</code> is past-the-end.</dt>
+ <dt><b>Throws:</b> Nothing.</dt>
+ </dl>
+
+<pre>
+stl_input_iterator(object const&amp; ob)
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Calls <code>ob.attr("__iter__")()</code> and stores the resulting Python iterator
+ object in <code>this-&gt;it</code>. Then, calls <code>this-&gt;it.attr("next")()</code> and
+ stores the result in <code>this-&gt;ob</code>. If the sequence is exhausted, sets
+ <code>this-&gt;ob</code> to <code>object()</code>.
+ </dt>
+
+ <dt><b>Postconditions:</b> <code>this</code> is a dereferenceable or past-the-end.</dt>
+ </dl>
+
+ <h4>
+ <a name="stl_input_iterator-spec-modifiers"></a>Class Template <code>stl_input_iterator</code>
+ modifiers
+ </h4>
+
+<pre>
+stl_input_iterator&amp; operator++()
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Calls <code>this-&gt;it.attr("next")()</code> and stores the result in
+ <code>this-&gt;ob</code>. If the sequence is exhausted, sets <code>this-&gt;ob</code>
+ to <code>object()</code>.
+ </dt>
+
+ <dt><b>Postconditions:</b> <code>this</code> is a dereferenceable or past-the-end.</dt>
+
+ <dt><b>Returns:</b> <code>*this</code>.</dt>
+ </dl>
+
+<pre>
+stl_input_iterator operator++(int)
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ <code>stl_input_iterator tmp = *this; ++*this; return tmp;</code>
+ </dt>
+
+ <dt><b>Postconditions:</b> <code>this</code> is a dereferenceable or past-the-end.</dt>
+ </dl>
+
+ <h4><a name="stl_input_iterator-spec-observers"></a>Class Template<code>stl_input_iterator</code>
+ observers</h4>
+
+<pre>
+ValueType operator*() const
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Returns the current element in the sequence.
+ </dt>
+ <dt><b>Returns:</b>
+ <code>extract&lt;ValueType&gt;(this-&gt;ob);</code>
+ </dt>
+ </dl>
+
+<pre>
+friend bool operator==(stl_input_iterator const&amp; lhs, stl_input_iterator const&amp; rhs)
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Returns true if both iterators are dereferenceable or if both iterators are past-the-end,
+ false otherwise.
+ </dt>
+ <dt><b>Returns:</b>
+ <code>(lhs.ob == object()) == (rhs.ob == object())</code>
+ </dt>
+ </dl>
+
+<pre>
+friend bool operator!=(stl_input_iterator const&amp; lhs, stl_input_iterator const&amp; rhs)
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b>
+ Returns false if both iterators are dereferenceable or if both iterators are past-the-end,
+ true otherwise.
+ </dt>
+ <dt><b>Returns:</b>
+ <code>!(lhs == rhs)</code>
+ </dt>
+ </dl>
+
+ <h2><a name="examples"></a>Examples</h2>
+<pre>
+#include &lt;boost/python/object.hpp&gt;
+#include &lt;boost/python/stl_iterator.hpp&gt;
+
+#include &lt;list&gt;
+
+using namespace boost::python;
+std::list&lt;int&gt; sequence_to_int_list(object const&amp; ob)
+{
+ stl_input_iterator&lt;int&gt; begin(ob), end;
+ return std::list&lt;int&gt;(begin, end);
+}
+</pre>
+
+<hr>
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->30
+October, 2005
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>© Copyright Eric Niebler 2005.</i></p>
+ </body>
+</html> \ No newline at end of file
diff --git a/libs/python/doc/v2/str.html b/libs/python/doc/v2/str.html
new file mode 100644
index 000000000..11810d841
--- /dev/null
+++ b/libs/python/doc/v2/str.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/str.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/str.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#str-spec">Class <code>str</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#str-spec-synopsis">Class <code>str</code>
+ synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
+ <a href=
+ "http://www.python.org/dev/doc/devel/lib/string-methods.html">str</a>
+ type.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="str-spec"></a>Class <code>str</code></h3>
+
+ <p>Exposes the <a href=
+ "http://www.python.org/dev/doc/devel/lib/string-methods.html">string
+ methods</a> of Python's built-in <code>str</code> type. The
+ semantics of the constructors and member functions defined below,
+ except for the two-argument constructors which construct str
+ objects from a range of characters, can be fully understood by
+ reading the <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
+ definition. Since <code>str</code> is publicly derived from
+ <code><a href="object.html#object-spec">object</a></code>, the
+ public object interface applies to <code>str</code> instances as
+ well.</p>
+
+ <h4><a name="str-spec-synopsis"></a>Class <code>str</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class str : public object
+ {
+ public:
+ str(); // new str
+
+ str(char const* s); // new str
+
+ str(char const* start, char const* finish); // new str
+ str(char const* start, std::size_t length); // new str
+
+ template &lt;class T&gt;
+ explicit str(T const&amp; other);
+
+ str capitalize() const;
+
+ template &lt;class T&gt;
+ str center(T const&amp; width) const;
+
+ template&lt;class T&gt;
+ long count(T const&amp; sub) const;
+ template&lt;class T1, class T2&gt;
+ long count(T1 const&amp; sub,T2 const&amp; start) const;
+ template&lt;class T1, class T2, class T3&gt;
+ long count(T1 const&amp; sub,T2 const&amp; start, T3 const&amp; end) const;
+
+ object decode() const;
+ template&lt;class T&gt;
+ object decode(T const&amp; encoding) const;
+ template&lt;class T1, class T2&gt;
+ object decode(T1 const&amp; encoding, T2 const&amp; errors) const;
+
+ object encode() const;
+ template &lt;class T&gt;
+ object encode(T const&amp; encoding) const;
+ template &lt;class T1, class T2&gt;
+ object encode(T1 const&amp; encoding, T2 const&amp; errors) const;
+
+ template &lt;class T&gt;
+ bool endswith(T const&amp; suffix) const;
+ template &lt;class T1, class T2&gt;
+ bool endswith(T1 const&amp; suffix, T2 const&amp; start) const;
+ template &lt;class T1, class T2, class T3&gt;
+ bool endswith(T1 const&amp; suffix, T2 const&amp; start, T3 const&amp; end) const;
+
+ str expandtabs() const;
+ template &lt;class T&gt;
+ str expandtabs(T const&amp; tabsize) const;
+
+ template &lt;class T&gt;
+ long find(T const&amp; sub) const;
+ template &lt;class T1, class T2&gt;
+ long find(T1 const&amp; sub, T2 const&amp; start) const;
+ template &lt;class T1, class T2, class T3&gt;
+ long find(T1 const&amp; sub, T2 const&amp; start, T3 const&amp; end) const;
+
+ template &lt;class T&gt;
+ long index(T const&amp; sub) const;
+ template &lt;class T1, class T2&gt;
+ long index(T1 const&amp; sub, T2 const&amp; start) const;
+ template &lt;class T1, class T2, class T3&gt;
+ long index(T1 const&amp; sub, T2 const&amp; start, T3 const&amp; end) const;
+
+ bool isalnum() const;
+ bool isalpha() const;
+ bool isdigit() const;
+ bool islower() const;
+ bool isspace() const;
+ bool istitle() const;
+ bool isupper() const;
+
+ template &lt;class T&gt;
+ str join(T const&amp; sequence) const;
+
+ template &lt;class T&gt;
+ str ljust(T const&amp; width) const;
+
+ str lower() const;
+ str lstrip() const;
+
+ template &lt;class T1, class T2&gt;
+ str replace(T1 const&amp; old, T2 const&amp; new_) const;
+ template &lt;class T1, class T2, class T3&gt;
+ str replace(T1 const&amp; old, T2 const&amp; new_, T3 const&amp; maxsplit) const;
+
+ template &lt;class T&gt;
+ long rfind(T const&amp; sub) const;
+ template &lt;class T1, class T2&gt;
+ long rfind(T1 const&amp; sub, T2 const&amp; start) const;
+ template &lt;class T1, class T2, class T3&gt;
+ long rfind(T1 const&amp; sub, T2 const&amp; start, T3 const&amp; end) const;
+
+ template &lt;class T&gt;
+ long rindex(T const&amp; sub) const;
+ template &lt;class T1, class T2&gt;
+ long rindex(T1 const&amp; sub, T2 const&amp; start) const;
+ template &lt;class T1, class T2, class T3&gt;
+ long rindex(T1 const&amp; sub, T2 const&amp; start, T3 const&amp; end) const;
+
+ template &lt;class T&gt;
+ str rjust(T const&amp; width) const;
+
+ str rstrip() const;
+
+ list split() const;
+ template &lt;class T&gt;
+ list split(T const&amp; sep) const;
+ template &lt;class T1, class T2&gt;
+ list split(T1 const&amp; sep, T2 const&amp; maxsplit) const;
+
+ list splitlines() const;
+ template &lt;class T&gt;
+ list splitlines(T const&amp; keepends) const;
+
+ template &lt;class T&gt;
+ bool startswith(T const&amp; prefix) const;
+ template &lt;class T1, class T2&gt;
+ bool startswidth(T1 const&amp; prefix, T2 const&amp; start) const;
+ template &lt;class T1, class T2, class T3&gt;
+ bool startswidth(T1 const&amp; prefix, T2 const&amp; start, T3 const&amp; end) const;
+
+ str strip() const;
+ str swapcase() const;
+ str title() const;
+
+ template &lt;class T&gt;
+ str translate(T const&amp; table) const;
+ template &lt;class T1, class T2&gt;
+ str translate(T1 const&amp; table, T2 const&amp; deletechars) const;
+
+ str upper() const;
+ };
+}}
+</pre>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+using namespace boost::python;
+str remove_angle_brackets(str x)
+{
+ return x.strip('&lt;').strip('&gt;');
+}
+</pre>
+
+ <p>Revised 3 October, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/to_python_converter.html b/libs/python/doc/v2/to_python_converter.html
new file mode 100644
index 000000000..81b61d252
--- /dev/null
+++ b/libs/python/doc/v2/to_python_converter.html
@@ -0,0 +1,227 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python -
+ &lt;boost/python/to_python_converter.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/to_python_converter.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_converter-spec">Class Template
+ <code>to_python_converter</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_converter-spec-synopsis">Class Template
+ <code>to_python_converter</code> synopsis</a></dt>
+
+ <dt><a href="#to_python_converter-spec-ctors">Class Template
+ <code>to_python_converter</code> constructor</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+ <code>to_python_converter</code> registers a conversion from objects of a
+ given C++ type into a Python object.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="to_python_converter-spec"></a>Class template
+ <code>to_python_converter</code></h3>
+ <code>to_python_converter</code> adds a wrapper around a static member
+ function of its second template parameter, handling low-level details
+ such as insertion into the converter registry.
+
+ <table border="1" summary="to_python_converter template parameters">
+ <caption>
+ <b><code>to_python_converter</code> template parameters</b><br>
+ In the table below, <b><code>x</code></b> denotes an object of type
+ <code>T</code>
+ </caption>
+
+ <tr>
+ <th>Parameter</th>
+
+ <th>Requirements</th>
+
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td><code>T</code></td>
+
+ <td>
+ </td>
+
+ <td>The C++ type of the source object in the conversion</td>
+ </tr>
+
+ <tr>
+ <td><code>Conversion</code></td>
+
+ <td>
+ <code>PyObject*&nbsp;p&nbsp;=&nbsp;Conversion::convert(x)</code>,<br>
+ if <code>p&nbsp;==&nbsp;0</code>, <code><a href=
+ "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>.</td>
+
+ <td>A class type whose static member function <code>convert</code>
+ does the real work of the conversion.</td>
+ </tr>
+ <tr>
+ <td><code>bool has_get_pytype = false</code></td>
+
+ <td>
+ <code>PyTypeObject const * p = Conversion::get_pytype() </code>.</td>
+
+ <td><b>Optional member</b> - if <code>Conversion</code> has <code>get_pytype</code> member supply
+ <code>true</code> for this parameters.
+ If present <code>get_pytype</code> is used to document the return type
+ of functions using this conversion. The <code>get_pytype</code> may be implemented
+ using the classes and functions
+ from <a href="pytype_function.html"><code>pytype_function.hpp</code></a>
+ <b>NOTE :</b> For backward compatibility this parameter may be passed after
+ checking if <code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code> is defined (see
+ <a href="pytype_function.html#examples">here</a>).
+ </td>
+ </tr>
+ </table>
+
+ <h4><a name="to_python_converter-spec-synopsis"></a>Class template
+ <code>to_python_converter</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T, class Conversion, bool convertion_has_get_pytype_member=false&gt;
+ struct to_python_converter
+ {
+ to_python_converter();
+ };
+}}
+</pre>
+
+ <h4><a name="to_python_converter-spec-ctors"></a>Class template
+ <code>to_python_converter</code> constructor</h4>
+<pre>
+to_python_converter();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Registers a to_python converter which uses
+ <code>Conversion::convert()</code> to do its work.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+ This example presumes that someone has implemented the standard <a href=
+ "http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example
+ module</a> from the Python documentation, and placed the corresponding
+ declarations in <code>"noddy.h"</code>. Because
+ <code>noddy_NoddyObject</code> is the ultimate trivial extension type,
+ the example is a bit contrived: it wraps a function for which all
+ information is contained in the <i>type</i> of its return value.
+
+ <h3>C++ module definition</h3>
+<pre>
+#include &lt;boost/python/reference.hpp&gt;
+#include &lt;boost/python/module.hpp&gt;
+#include "noddy.h"
+
+struct tag {};
+tag make_tag() { return tag(); }
+
+using namespace boost::python;
+
+struct tag_to_noddy
+{
+ static PyObject* convert(tag const&amp; x)
+ {
+ return PyObject_New(noddy_NoddyObject, &amp;noddy_NoddyType);
+ }
+ static PyTypeObject const* get_pytype()
+ {
+ return &amp;noddy_NoddyType;
+ }
+};
+
+BOOST_PYTHON_MODULE(to_python_converter)
+{
+ def("make_tag", make_tag);
+ to_python_converter&lt;tag, tag_to_noddy, true&gt;(); //"true" because tag_to_noddy has member get_pytype
+}
+</pre>
+
+ <h3>Python code</h3>
+<pre>
+&gt;&gt;&gt; import to_python_converter
+&gt;&gt;&gt; def always_none():
+... return None
+...
+&gt;&gt;&gt; def choose_function(x):
+... if (x % 2 != 0):
+... return to_python_converter.make_tag
+... else:
+... return always_none
+...
+&gt;&gt;&gt; a = [ choose_function(x) for x in range(5) ]
+&gt;&gt;&gt; b = [ f() for f in a ]
+&gt;&gt;&gt; type(b[0])
+&lt;type 'NoneType'&gt;
+&gt;&gt;&gt; type(b[1])
+&lt;type 'Noddy'&gt;
+&gt;&gt;&gt; type(b[2])
+&lt;type 'NoneType'&gt;
+&gt;&gt;&gt; type(b[3])
+&lt;type 'Noddy'&gt;
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 11 June, 2007
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/to_python_indirect.html b/libs/python/doc/v2/to_python_indirect.html
new file mode 100644
index 000000000..17e0a826c
--- /dev/null
+++ b/libs/python/doc/v2/to_python_indirect.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/to_python_indirect.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/to_python_indirect.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a>
+
+
+ <dt><a href="#classes">Classes</a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_indirect-spec">Class Template <code>to_python_indirect</code></a>
+
+ <dd>
+ <dl class="page-index">
+
+ <dt><a href="#to_python_indirect-spec-synopsis">Class Template
+ <code>to_python_indirect</code> synopsis</a>
+
+ <dt><a href="#to_python_indirect-spec-observers">Class Template
+ <code>to_python_indirect</code> observer functions</a>
+
+ <dt><a href="#to_python_indirect-spec-statics">Class Template
+ <code>to_python_indirect</code> static functions</a>
+ </dl>
+ </dl>
+
+ <dt><a href="#examples">Example</a>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <code>&lt;boost/python/to_python_indirect.hpp&gt;</code> supplies
+ a way to construct new Python objects that hold wrapped C++ class
+ instances via a pointer or smart pointer.
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="to_python_indirect-spec"></a>Class template <code>to_python_indirect</code></h3>
+ <p>Class template <code>to_python_indirect</code> converts objects
+of its first argument type to python as extension class instances, using the ownership policy provided by its 2nd argument.
+
+ <p>
+
+
+ <table border="1" summary="to_python_indirect template parameters">
+ <caption>
+ <b><code>to_python_indirect</code> Requirements</b><br>
+
+ In the table below, <b><code>x</code></b> denotes an object of
+ type <code>T</code>, <b><code>h</code></b> denotes an
+ object of type
+ <code>boost::python::objects::instance_holder*</code>, and
+ <b><code>p</code></b> denotes an object of type
+ <code>U*</code>.
+
+ </caption>
+ <tr>
+ <th>Parameter
+
+ <th>Requirements
+
+ <th>Description
+
+ <tr>
+ <td><code>T</code>
+
+ <td>Either <code>U</code>&nbsp;<i>cv</i><code>&amp;</code>
+ (where <i>cv</i> is any optional cv-qualification) or a <a
+ href="Dereferenceable.html">Dereferenceable</a> type such that
+ <code>*x</code> is convertible to <code>U const&amp;</code>, where
+ <code>U</code> is a class type.
+
+ <td>A type deferencing a C++ class exposed to Python using
+ class template <code><a
+ href="class.html#class_-spec">class_</a></code>.
+
+ <tr>
+ <td><code>MakeHolder</code>
+
+ <td>h = MakeHolder::execute(p);
+
+ <td>A class whose static <code>execute()</code> creates an
+ <code>instance_holder</code>.
+
+ </table>
+
+ Instantiations of <code>to_python_indirect</code> are models of <a
+ href="ResultConverter.html#ResultConverter-concept">ResultConverter</a>.
+
+
+ <h4><a name="to_python_indirect-spec-synopsis"></a>Class template <code>to_python_indirect</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T, class MakeHolder&gt;
+ struct to_python_indirect
+ {
+ static bool convertible();
+ PyObject* operator()(T ptr_or_reference) const;
+ private:
+ static PyTypeObject* type();
+ };
+}}
+</pre>
+
+ <h4><a name="to_python_indirect-spec-observers"></a>Class template <code>to_python_indirect</code> observers</h4>
+<pre>
+PyObject* operator()(T x) const;
+</pre>
+
+ <dl class="function-semantics">
+
+ <dt><b>Requires:</b> <code>x</code> refers to an object (if it
+ is a pointer type, it is non-null). <code>convertible() ==
+ true</code>.
+
+ <dt><b>Effects:</b> Creates an appropriately-typed Boost.Python
+ extension class instance, uses <code>MakeHolder</code> to create
+ an <code>instance_holder</code> from <code>x</code>, installs
+ the <code>instance_holder</code> in the new extension class
+ instance, and returns a pointer to it.
+
+ </dl>
+
+
+ <h4><a name="to_python_indirect-spec-statics"></a>Class template <code>to_python_indirect</code> statics</h4>
+<pre>
+bool convertible();
+</pre>
+
+ <dt><b>Effects:</b> Returns <code>true</code> iff any module has
+ registered a Python type corresponding to <code>U</code>.
+
+ <h2><a name="examples"></a>Example</h2>
+
+This example replicates the functionality of <a
+href="reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a>,
+but without some of the compile-time error checking.
+
+
+<pre>
+
+struct make_reference_holder
+{
+ typedef boost::python::objects::instance_holder* result_type;
+ template &lt;class T&gt;
+ static result_type execute(T* p)
+ {
+ return new boost::python::objects::pointer_holder&lt;T*, T&gt;(p);
+ }
+};
+
+struct reference_existing_object
+{
+ // metafunction returning the <a href="ResultConverter.html#ResultConverter-concept">ResultConverter</a>
+ template &lt;class T&gt;
+ struct apply
+ {
+ typedef boost::python::to_python_indirect&lt;T,make_reference_holder&gt; type;
+ };
+};
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i> Distributed
+ under the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</p>
+
diff --git a/libs/python/doc/v2/to_python_value.html b/libs/python/doc/v2/to_python_value.html
new file mode 100644
index 000000000..3ba0044d1
--- /dev/null
+++ b/libs/python/doc/v2/to_python_value.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/to_python_value.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header
+ &lt;boost/python/to_python_value.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#classes">Classes</a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_value-spec">Class
+ <code>to_python_value</code></a>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#to_python_value-spec-synopsis">Class template
+ <code>to_python_value</code> synopsis</a>
+
+ <dt><a href="#to_python_value-spec-observers">Class template
+ <code>to_python_value</code> observer functions</a>
+ </dl>
+ </dl>
+
+ </dl>
+ <hr>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="to_python_value-spec"></a>Class template
+ <code>to_python_value</code></h3>
+
+ <p><code>to_python_value</code> is a model of <a href=
+ "ResultConverter.html#ResultConverter-concept">ResultConverter</a>
+ which copies its argument into a new Python object.
+
+ <h4><a name="to_python_value-spec-synopsis"></a>Class
+ <code>to_python_value</code> synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ template &lt;class T&gt;
+ struct to_python_value
+ {
+ typedef typename <a href="../../../type_traits/index.html#transformations">add_reference</a>&lt;
+ typename <a href="../../../type_traits/index.html#transformations">add_const</a>&lt;T&gt;::type
+ &gt;::type argument_type;
+
+ static bool convertible();
+ PyObject* operator()(argument_type) const;
+ };
+}}
+</pre>
+
+ <h4><a name="to_python_value-spec-observers"></a>Class
+ <code>to_python_value</code> observers</h4>
+<pre>
+static bool convertible();
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>true</code> iff a converter has been registered which can convert <code>T</code> to python by-value.
+ </dl>
+
+<pre>
+PyObject* operator()(argument_type x) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>convertible()&nbsp;==&nbsp;true</code>
+ <dt><b>Effects:</b> converts <code>x</code> to python
+ <dt><b>Returns:</b> the resulting Python object iff a converter for <code>T</code> has been registered, <code>0</code> otherwise.
+ </dl>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i> Distributed under the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)</p>
+
diff --git a/libs/python/doc/v2/tuple.html b/libs/python/doc/v2/tuple.html
new file mode 100644
index 000000000..e90244f3e
--- /dev/null
+++ b/libs/python/doc/v2/tuple.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/tuple.hpp&gt;</title>
+ </head>
+
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+ </td>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;boost/python/tuple.hpp&gt;</h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#tuple-spec">Class <code>tuple</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#tuple-spec-synopsis">Class <code>tuple</code>
+ synopsis</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#make_tuple-spec"><code>make_tuple</code></a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>Exposes a <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
+ <a href=
+ "http://www.python.org/doc/current/tut/node7.html#SECTION007300000000000000000">
+ tuple</a> type.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="tuple-spec"></a>Class <code>tuple</code></h3>
+
+ <p>Exposes the interface of Python's built-in <code>tuple</code> type.
+ The semantics of the constructors and member functions defined below can
+ be fully understood by reading the <a href=
+ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
+ definition. Since <code>tuple</code> is publicly derived from <code><a
+ href="object.html#object-spec">object</a></code>, the public object
+ interface applies to <code>tuple</code> instances as well.</p>
+
+ <h4><a name="tuple-spec-synopsis"></a>Class <code>tuple</code>
+ synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class tuple : public object
+ {
+ // tuple() -&gt; an empty tuple
+ tuple();
+
+ // tuple(sequence) -&gt; tuple initialized from sequence's items
+ template &lt;class T&gt;
+ explicit tuple(T const&amp; sequence)
+ };
+}}
+</pre>
+
+ <h2><a name="functions"></a>Functions</h2>
+
+ <h3><a name="make_tuple-spec"></a><code>make_tuple</code></h3>
+<pre>
+namespace boost { namespace python
+{
+ tuple make_tuple();
+
+ template &lt;class A0&gt;
+ tuple make_tuple(A0 const&amp; a0);
+
+ template &lt;class A0, class A1&gt;
+ tuple make_tuple(A0 const&amp; a0, A1 const&amp; a1);
+ ...
+ template &lt;class A0, class A1,...class A<i>n</i>&gt;
+ tuple make_tuple(A0 const&amp; a0, A1 const&amp; a1,...A<i>n</i> const&amp; a<i>n</i>);
+}}
+</pre>
+ Constructs a new tuple object composed of <code>object(a0),
+ object(a0),...object(a<i>n</i>)</code>.
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+using namespace boost::python;
+tuple head_and_tail(object sequence)
+{
+ return make_tuple(sequence[0],sequence[-1]);
+}
+</pre>
+
+ <p>Revised 03 October, 2002</p>
+
+ <p><i>&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/type_id.html b/libs/python/doc/v2/type_id.html
new file mode 100644
index 000000000..570846741
--- /dev/null
+++ b/libs/python/doc/v2/type_id.html
@@ -0,0 +1,224 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content=
+ "text/html; charset=iso-8859-1">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;boost/python/type_id.hpp&gt;</title>
+
+ <style type="text/css">
+ p.c4 {font-style: italic}
+ span.c3 {color: #ff0000}
+ h2.c2 {text-align: center}
+ h1.c1 {text-align: center}
+</style>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width=
+ "277" alt="C++ Boost" src="../../../../boost.png" border=
+ "0"></a></h3>
+
+ <td valign="top">
+ <h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 class="c2">Header &lt;boost/python/type_id.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#type_info-spec">Class <code>type_info</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#type_info-spec-synopsis">Class
+ <code>type_info</code> synopsis</a></dt>
+
+ <dt><a href="#type_infospec-ctors">Class <code>type_info</code>
+ constructor</a></dt>
+
+ <dt><a href="#type_infospec-comparisons">Class
+ <code>type_info</code> comparison functions</a></dt>
+
+ <dt><a href="#type_infospec-observers">Class
+ <code>type_info</code> observer functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#functions">Functions</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#type_id-spec">type_id</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p><code>&lt;boost/python/type_id.hpp&gt;</code> provides types and
+ functions for runtime type identification like those of of
+ <code>&lt;typeinfo&gt;</code>. It exists mostly to work around certain
+ compiler bugs and platform-dependent interactions with shared
+ libraries.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="type_info-spec"></a>Class <code>type_info</code></h3>
+
+ <p><code>type_info</code> instances identify a type. As
+ <code>std::type_info</code> is specified to (but unlike its
+ implementation in some compilers), <code>boost::python::type_info</code>
+ never represents top-level references or cv-qualification (see section
+ 5.2.8 in the C++ standard). Unlike <code>std::type_info</code>,
+ <code>boost::python::type_info</code> instances are copyable, and
+ comparisons always work reliably across shared library boundaries.</p>
+
+ <h4><a name="type_info-spec-synopsis"></a>Class type_info synopsis</h4>
+<pre>
+namespace boost { namespace python
+{
+ class type_info : <a href=
+"../../../utility/operators.htm#totally_ordered1">totally_ordered</a>&lt;type_info&gt;
+ {
+ public:
+ // constructor
+ type_info(std::type_info const&amp; = typeid(void));
+
+ // comparisons
+ bool operator&lt;(type_info const&amp; rhs) const;
+ bool operator==(type_info const&amp; rhs) const;
+
+ // observers
+ char const* name() const;
+ };
+}}
+</pre>
+
+ <h4><a name="type_infospec-ctors">Class <code>type_info</code>
+ constructor</a></h4>
+<pre>
+type_info(std::type_info const&amp; = typeid(void));
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> constructs a <code>type_info</code> object which
+ identifies the same type as its argument.</dt>
+
+ <dt><b>Rationale:</b> Since it is occasionally necessary to make an
+ array of <code>type_info</code> objects a benign default argument is
+ supplied. <span class="c3"><b>Note:</b></span> this constructor does
+ <i>not</i> correct for non-conformance of compiler
+ <code>typeid()</code> implementations. See <code><a href=
+ "#type_id-spec">type_id</a></code>, below.</dt>
+ </dl>
+
+ <h4><a name="type_infospec-comparisons">Class <code>type_info</code>
+ comparisons</a></h4>
+<pre>
+bool operator&lt;(type_info const&amp; rhs) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> yields a total order over <code>type_info</code>
+ objects.</dt>
+ </dl>
+<pre>
+bool operator==(type_info const&amp; rhs) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>true</code> iff the two values describe the
+ same type.</dt>
+ </dl>
+
+ <dl class="function-semantics">
+ <dt><b>Note:</b> The use of <code><a href=
+ "../../../utility/operators.htm#totally_ordered1">totally_ordered</a>&lt;type_info&gt;</code>
+ as a private base class supplies operators <code>&lt;=</code>,
+ <code>&gt;=</code>, <code>&gt;</code>, and <code>!=</code></dt>
+ </dl>
+
+ <h4><a name="type_infospec-observers">Class <code>type_info</code>
+ observers</a></h4>
+<pre>
+char const* name() const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> The result of calling <code>name()</code> on the
+ argument used to construct the object.</dt>
+ </dl>
+
+ <h2><a name="functions"></a>Functions</h2>
+<pre>
+std::ostream&amp; operator&lt;&lt;(std::ostream&amp;s, type_info const&amp;x);
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> Writes a description of the type described by to
+ <code>x</code> into <code>s</code>.</dt>
+
+ <dt><b>Rationale:</b> Not every C++ implementation provides a truly
+ human-readable <code>type_info::name()</code> string, but for some we
+ may be able to decode the string and produce a reasonable
+ representation.</dt>
+ </dl>
+<pre>
+<a name="type_id-spec">template &lt;class T&gt; type_info type_id</a>()
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Returns:</b> <code>type_info(typeid(T))</code></dt>
+
+ <dt><b>Note:</b> On some non-conforming C++ implementations, the code
+ is not actually as simple as described above; the semantics are
+ adjusted to work <i>as-if</i> the C++ implementation were
+ conforming.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+ The following example, though silly, illustrates how the
+ <code>type_id</code> facility might be used
+<pre>
+#include &lt;boost/python/type_id.hpp&gt;
+
+// Returns true iff the user passes an int argument
+template &lt;class T&gt;
+bool is_int(T x)
+{
+ using boost::python::type_id;
+ return type_id&lt;T&gt;() == type_id&lt;int&gt;();
+}
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+
+ <p class="c4">&copy; Copyright <a href=
+ "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002. Distributed under the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)<
+
+ </body>
+</html>
+
diff --git a/libs/python/doc/v2/with_custodian_and_ward.html b/libs/python/doc/v2/with_custodian_and_ward.html
new file mode 100644
index 000000000..b8e2a498d
--- /dev/null
+++ b/libs/python/doc/v2/with_custodian_and_ward.html
@@ -0,0 +1,370 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+ <title>
+ Boost.Python - &lt;boost/python/with_custodian_and_ward.hpp&gt;
+ </title>
+ </head>
+ <body>
+ <table border="0" cellpadding="7" cellspacing="0" width="100%"
+ summary="header">
+ <tr>
+ <td valign="top" width="300">
+ <h3>
+ <a href="../../../../index.htm"><img height="86" width="277"
+ alt="C++ Boost" src="../../../../boost.png" border="0">
+ </a>
+ </h3>
+ </td>
+ <td valign="top">
+ <h1 align="center">
+ <a href="../index.html">Boost.Python</a>
+ </h1>
+ <h2 align="center">
+ Header &lt;boost/python/with_custodian_and_ward.hpp&gt;
+ </h2>
+ </td>
+ </tr>
+ </table>
+ <hr>
+ <h2>
+ Contents
+ </h2>
+ <dl class="page-index">
+ <dt>
+ <a href="#introduction">Introduction</a>
+ </dt>
+ <dt>
+ <a href="#classes">Classes</a>
+ </dt>
+ <dd>
+ <dl class="page-index">
+ <dt>
+ <a href="#with_custodian_and_ward-spec">Class Template
+ <code>with_custodian_and_ward</code></a>
+ </dt>
+ <dd>
+ <dl class="page-index">
+ <dt>
+ <a href="#with_custodian_and_ward-spec-synopsis">Class
+ Template <code>with_custodian_and_ward</code> synopsis</a>
+ </dt>
+ <dt>
+ <a href="#with_custodian_and_ward-spec-statics">Class
+ <code>with_custodian_and_ward</code> static functions</a>
+ </dt>
+ </dl>
+ </dd>
+ <dt>
+ <a href="#with_custodian_and_ward_postcall-spec">Class Template
+ <code>with_custodian_and_ward_postcall</code></a>
+ </dt>
+ <dd>
+ <dl class="page-index">
+ <dt>
+ <a href=
+ "#with_custodian_and_ward_postcall-spec-synopsis">Class
+ Template <code>with_custodian_and_ward_postcall</code>
+ synopsis</a>
+ </dt>
+ <dt>
+ <a href=
+ "#with_custodian_and_ward_postcall-spec-statics">Class
+ <code>with_custodian_and_ward_postcall</code> static
+ functions</a>
+ </dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+ <dt>
+ <a href="#examples">Example</a>
+ </dt>
+ </dl>
+ <hr>
+ <h2>
+ <a name="introduction">Introduction</a>
+ </h2>This header provides facilities for establishing a lifetime
+ dependency between two of a function's Python argument or result objects.
+ The <i>ward</i> object will not be destroyed until after the custodian as
+ long as the <i>custodian</i> object supports <a href=
+ "http://www.python.org/doc/current/lib/module-weakref.html">weak
+ references</a> (Boost.Python extension classes all support weak
+ references). If the <i>custodian</i> object does not support weak
+ references and is not <code>None</code>, an appropriate exception will be
+ thrown. The two class templates <code>with_custodian_and_ward</code> and
+ <code>with_custodian_and_ward_postcall</code> differ in the point at
+ which they take effect.
+ <p>
+ In order to reduce the chance of inadvertently creating dangling
+ pointers, the default is to do lifetime binding <i>before</i> the
+ underlying C++ object is invoked. However, before invocation the result
+ object is not available, so
+ <code>with_custodian_and_ward_postcall</code> is provided to bind
+ lifetimes after invocation. Also, if a C++ exception is thrown after
+ <code>with_custodian_and_ward&lt;&gt;::precall</code> 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 <code>with_custodian_and_ward_postcall</code> instead,
+ depending on the semantics of the function being wrapped.
+ </p>
+ <p>
+ Please note that this is <i>not</i> the appropriate tool to use when
+ wrapping functions which <b>transfer ownership</b> of a raw pointer
+ across the function-call boundary. Please see the <a href=
+ "faq.html#ownership">FAQ</a> if you want to do that.
+ </p>
+ <h2>
+ <a name="classes"></a>Classes
+ </h2>
+ <h3>
+ <a name="with_custodian_and_ward-spec"></a>Class template
+ <code>with_custodian_and_ward</code>
+ </h3>
+ <table border="1" summary="with_custodian_and_ward template parameters">
+ <caption>
+ <b><code>with_custodian_and_ward</code> template parameters</b>
+ </caption>
+ <tr>
+ <th>
+ Parameter
+ </th>
+ <th>
+ Requirements
+ </th>
+ <th>
+ Description
+ </th>
+ <th>
+ Default
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <code>custodian</code>
+ </td>
+ <td>
+ A positive compile-time constant of type <code>std::size_t</code>.
+ </td>
+ <td>
+ 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 (<code>*this</code>).
+ Note that if the target Python object type doesn't support weak
+ references, a Python <code>TypeError</code> exception will be
+ raised when the C++ object being wrapped is called.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>ward</code>
+ </td>
+ <td>
+ A positive compile-time constant of type <code>std::size_t</code>.
+ </td>
+ <td>
+ 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 (<code>*this</code>).
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>Base</code>
+ </td>
+ <td>
+ A model of <a href="CallPolicies.html">CallPolicies</a>
+ </td>
+ <td>
+ Used for <a href="CallPolicies.html#composition">policy
+ composition</a>.
+ </td>
+ <td>
+ <code><a href=
+ "default_call_policies.html#default_call_policies-spec">default_call_policies</a></code>
+ </td>
+ </tr>
+ </table>
+ <h4>
+ <a name="with_custodian_and_ward-spec-synopsis"></a>Class template
+ <code>with_custodian_and_ward</code> synopsis
+ </h4>
+ <pre>
+namespace boost { namespace python
+{
+ template &lt;std::size_t custodian, std::size_t ward, class Base = default_call_policies&gt;
+ struct with_custodian_and_ward : Base
+ {
+ static bool precall(PyObject* args);
+ };
+}}
+</pre>
+ <h4>
+ <a name="with_custodian_and_ward-spec-statics"></a>Class
+ <code>with_custodian_and_ward</code> static functions
+ </h4>
+ <pre>
+bool precall(PyObject* args);
+</pre>
+ <dl class="function-semantics">
+ <dt>
+ <b>Requires:</b> <code><a href=
+ "http://www.python.org/doc/2.2/api/tupleObjects.html#l2h-476">PyTuple_Check</a>(args)
+ != 0</code>
+ </dt>
+ <dt>
+ <b>Effects:</b> Makes the lifetime of the argument indicated by
+ <code>ward</code> dependent on the lifetime of the argument indicated
+ by <code>custodian</code>.
+ </dt>
+ <dt>
+ <b>Returns:</b> <code>false</code> and <code><a href=
+ "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>
+ upon failure, <code>true</code> otherwise.
+ </dt>
+ </dl><!-- xxxxxx -->
+ <h3>
+ <a name="with_custodian_and_ward_postcall-spec"></a>Class template
+ <code>with_custodian_and_ward_postcall</code>
+ </h3>
+ <table border="1" summary=
+ "with_custodian_and_ward_postcall template parameters">
+ <caption>
+ <b><code>with_custodian_and_ward_postcall</code> template
+ parameters</b>
+ </caption>
+ <tr>
+ <th>
+ Parameter
+ </th>
+ <th>
+ Requirements
+ </th>
+ <th>
+ Description
+ </th>
+ <th>
+ Default
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <code>custodian</code>
+ </td>
+ <td>
+ A compile-time constant of type <code>std::size_t</code>.
+ </td>
+ <td>
+ 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 (<code>*this</code>). Note that if
+ the target Python object type doesn't support weak references, a
+ Python <code>TypeError</code> exception will be raised when the C++
+ object being wrapped is called.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>ward</code>
+ </td>
+ <td>
+ A compile-time constant of type <code>std::size_t</code>.
+ </td>
+ <td>
+ 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 (<code>*this</code>).
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code>Base</code>
+ </td>
+ <td>
+ A model of <a href="CallPolicies.html">CallPolicies</a>
+ </td>
+ <td>
+ Used for <a href="CallPolicies.html#composition">policy
+ composition</a>.
+ </td>
+ <td>
+ <code><a href=
+ "default_call_policies.html#default_call_policies-spec">default_call_policies</a></code>
+ </td>
+ </tr>
+ </table>
+ <h4>
+ <a name="with_custodian_and_ward_postcall-spec-synopsis"></a>Class
+ template <code>with_custodian_and_ward_postcall</code> synopsis
+ </h4>
+ <pre>
+namespace boost { namespace python
+{
+ template &lt;std::size_t custodian, std::size_t ward, class Base = default_call_policies&gt;
+ struct with_custodian_and_ward_postcall : Base
+ {
+ static PyObject* postcall(PyObject* args, PyObject* result);
+ };
+}}
+</pre>
+ <h4>
+ <a name="with_custodian_and_ward_postcall-spec-statics"></a>Class
+ <code>with_custodian_and_ward_postcall</code> static functions
+ </h4>
+ <pre>
+PyObject* postcall(PyObject* args, PyObject* result);
+</pre>
+ <dl class="function-semantics">
+ <dt>
+ <b>Requires:</b> <code><a href=
+ "http://www.python.org/doc/2.2/api/tupleObjects.html#l2h-476">PyTuple_Check</a>(args)
+ != 0</code>, <code>result&nbsp;!=&nbsp;0</code>.
+ </dt>
+ <dt>
+ <b>Effects:</b> Makes the lifetime of the object indicated by
+ <code>ward</code> dependent on the lifetime of the object indicated
+ by <code>custodian</code>.
+ </dt>
+ <dt>
+ <b>Returns:</b> <code>0</code> and <code><a href=
+ "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>()&nbsp;!=&nbsp;0</code>
+ upon failure, <code>true</code> otherwise.
+ </dt>
+ </dl>
+ <h2>
+ <a name="examples"></a>Example
+ </h2>The following example shows how
+ <code>with_custodian_and_ward_postcall</code> is used by the library to
+ implement <code><a href=
+ "return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a></code>
+
+ <pre>
+template &lt;std::size_t owner_arg = 1, class Base = default_call_policies&gt;
+struct return_internal_reference
+ : with_custodian_and_ward_postcall&lt;0, owner_arg, Base&gt;
+{
+ typedef <a href=
+"reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a> result_converter;
+};
+</pre>
+ <p>
+ Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 13 November, 2002
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+ </p>
+ <p>
+ <i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2002. </i>
+ </p>
+ </body>
+</html>
diff --git a/libs/python/doc/v2/wrapper.html b/libs/python/doc/v2/wrapper.html
new file mode 100644
index 000000000..06239754a
--- /dev/null
+++ b/libs/python/doc/v2/wrapper.html
@@ -0,0 +1,238 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ <meta name="generator" content="HTML Tidy, see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link rel="stylesheet" type="text/css" href="../boost.css">
+
+ <title>Boost.Python - &lt;wrapper.hpp&gt;</title>
+
+ <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+ "header">
+ <tr>
+ <td valign="top" width="300">
+ <h3><a href="../../../../index.htm"><img height="86" width="277" alt=
+ "C++ Boost" src="../../../../boost.png" border="0"></a></h3>
+
+ <td valign="top">
+ <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
+
+ <h2 align="center">Header &lt;wrapper.hpp&gt;</h2>
+ </table>
+ <hr>
+
+ <h2>Contents</h2>
+
+ <dl class="page-index">
+ <dt><a href="#introduction">Introduction</a></dt>
+
+ <dt><a href="#classes">Classes</a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#override-spec">Class template
+ <code>override</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#override-spec-synopsis">Class
+ <code>override</code> synopsis</a></dt>
+
+ <dt><a href="#override-spec-observers">Class
+ <code>override</code> observer functions</a></dt>
+ </dl>
+ </dd>
+
+ <dt><a href="#wrapper-spec">Class template
+ <code>wrapper</code></a></dt>
+
+ <dd>
+ <dl class="page-index">
+ <dt><a href="#wrapper-spec-synopsis">Class <code>wrapper</code>
+ synopsis</a></dt>
+
+ <dt><a href="#wrapper-spec-observers">Class
+ <code>wrapper</code> observer functions</a></dt>
+ </dl>
+ </dd>
+ </dl>
+ </dd>
+
+ <dt><a href="#examples">Example(s)</a></dt>
+ </dl>
+ <hr>
+
+ <h2><a name="introduction"></a>Introduction</h2>
+
+ <p>To wrap a class <code>T</code> such that its virtual functions can be
+ "overridden in Python"&mdash;so that the corresponding method of a Python
+ derived class will be called when the virtual function is invoked from
+ C++&mdash;you must create a C++ wrapper class derived from ``T`` that
+ overrides those virtual functions so that they call into Python. This
+ header contains classes that can be used to make that job easier.</p>
+
+ <h2><a name="classes"></a>Classes</h2>
+
+ <h3><a name="override-spec"></a>Class <code>override</code></h3>
+
+ <p>Encapsulates a Python override of a C++ virtual function. An
+ <code>override</code> object either holds a callable Python object or
+ <code>None</code>.</p>
+
+ <h4><a name="override-spec-synopsis"></a>Class <code>override</code>
+ synopsis</h4>
+<pre>
+namespace boost
+{
+ class override : object
+ {
+ public:
+ <i>unspecified</i> operator() const;
+ template &lt;class A0&gt;
+ <i>unspecified</i> operator(A0) const;
+ template &lt;class A0, class A1&gt;
+ <i>unspecified</i> operator(A0, A1) const;
+ ...
+ template &lt;class A0, class A1, ...class A<i>n</i>&gt;
+ <i>unspecified</i> operator(A0, A1, ...A<i>n</i>) const;
+ };
+};
+</pre>
+
+ <h4><a name="override-spec-observers"></a>Class <code>override</code>
+ observer functions</h4>
+<pre>
+<i>unspecified</i> operator() const;
+template &lt;class A0&gt;
+<i>unspecified</i> operator(A0) const;
+template &lt;class A0, class A1&gt;
+<i>unspecified</i> operator(A0, A1) const;
+...
+template &lt;class A0, class A1, ...class A<i>n</i>&gt;
+<i>unspecified</i> operator(A0, A1, ...A<i>n</i>) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Effects:</b> If <code>*this</code> holds a callable Python
+ object, it is invoked with the specified arguments in the manner
+ specified <a href="callbacks.html">here</a>. Otherwise, throws <code><a
+ href="errors.html#error_already_set-spec">error_already_set</a></code>
+ .</dt>
+
+ <dt><b>Returns:</b> An object of unspecified type that holds the Python
+ result of the invocation and, when converted to a C++ type
+ <code>R</code>, attempts to convert that result object to
+ <code>R</code>. If that conversion fails, throws <code><a href=
+ "errors.html#error_already_set-spec">error_already_set</a></code>
+ .</dt>
+ </dl>
+
+ <h3><a name="wrapper-spec"></a>Class template <code>wrapper</code></h3>
+
+ <p>Deriving your wrapper class from both ``T`` <i>and</i>
+ ``wrapper&lt;T&gt; makes writing that derived class easier.</p>
+
+ <h4><a name="wrapper-spec-synopsis"></a>Class template
+ <code>wrapper</code> synopsis</h4>
+<pre>
+namespace boost
+{
+ class wrapper
+ {
+ protected:
+ override get_override(char const* name) const;
+ };
+};
+</pre>
+
+ <h4><a name="wrapper-spec-observers"></a>Class <code>wrapper</code>
+ observer functions</h4>
+<pre>
+override get_override(char const* name) const;
+</pre>
+
+ <dl class="function-semantics">
+ <dt><b>Requires:</b> <code>name</code> is a <a href=
+ "definitions.html#ntbs">ntbs</a>.</dt>
+
+ <dt><b>Returns:</b> If <code>*this</code> is the C++ base class
+ subobject of a Python derived class instance that overrides the named
+ function, returns an <code>override</code> object that delegates to the
+ Python override. Otherwise, returns an <code>override</code> object
+ that holds <code>None</code>.</dt>
+ </dl>
+
+ <h2><a name="examples"></a>Example</h2>
+<pre>
+#include &lt;boost/python/module.hpp&gt;
+#include &lt;boost/python/class.hpp&gt;
+#include &lt;boost/python/wrapper.hpp&gt;
+#include &lt;boost/python/call.hpp&gt;
+
+using namespace boost::python;
+
+// Class with one pure virtual function
+struct P
+{
+ virtual ~P(){}
+ virtual char const* f() = 0;
+ char const* g() { return "P::g()"; }
+};
+
+struct PCallback : P, wrapper&lt;P&gt;
+{
+ char const* f()
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, &lt;= 1300) // Workaround for vc6/vc7
+ return call&lt;char const*&gt;(this-&gt;get_override("f").ptr());
+#else
+ return this-&gt;get_override("f")();
+#endif
+ }
+};
+
+// Class with one non-pure virtual function
+struct A
+{
+ virtual ~A(){}
+ virtual char const* f() { return "A::f()"; }
+};
+
+struct ACallback : A, wrapper&lt;A&gt;
+{
+ char const* f()
+ {
+ if (override f = this-&gt;get_override("f"))
+#if BOOST_WORKAROUND(BOOST_MSVC, &lt;= 1300) // Workaround for vc6/vc7
+ return call&lt;char const*&gt;(f.ptr());
+#else
+ return f();
+#endif
+
+ return A::f();
+ }
+
+ char const* default_f() { return this-&gt;A::f(); }
+};
+
+BOOST_PYTHON_MODULE_INIT(polymorphism)
+{
+ class_&lt;PCallback,boost::noncopyable&gt;("P")
+ .def("f", pure_virtual(&amp;P::f))
+ ;
+
+ class_&lt;ACallback,boost::noncopyable&gt;("A")
+ .def("f", &amp;A::f, &amp;ACallback::default_f)
+ ;
+}
+</pre>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+ 31 October, 2004
+ <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
+
+
+ <p><i>&copy; Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
+ Abrahams</a> 2004</i> Distributed under the Boost Software License,
+ Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)</p>
+
diff --git a/libs/python/example/Jamroot b/libs/python/example/Jamroot
new file mode 100644
index 000000000..0d5ad9dcb
--- /dev/null
+++ b/libs/python/example/Jamroot
@@ -0,0 +1,40 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Specify the path to the Boost project. If you move this project,
+# adjust this path to refer to the Boost root directory.
+use-project boost
+ : ../../.. ;
+
+# Set up the project-wide requirements that everything uses the
+# boost_python library from the project whose global ID is
+# /boost/python.
+project
+ : requirements <library>/boost/python//boost_python ;
+
+# Declare the three extension modules. You can specify multiple
+# source files after the colon separated by spaces.
+python-extension getting_started1 : getting_started1.cpp ;
+python-extension getting_started2 : getting_started2.cpp ;
+python-extension std_pair_ext : std_pair.cpp ;
+
+# A little "rule" (function) to clean up the syntax of declaring tests
+# of these extension modules.
+local rule run-test ( test-name : sources + )
+{
+ import testing ;
+ testing.make-test run-pyd : $(sources) : : $(test-name) ;
+}
+
+# Declare test targets
+run-test test1 : getting_started1 test_getting_started1.py ;
+run-test test2 : getting_started2 test_getting_started2.py ;
+run-test test3 : std_pair_ext test_std_pair.py ;
+
+# A target that runs all the tests
+alias test : test1 test2 test3 ;
+
+# Only run tests when explicitly requested
+explicit test test1 test2 test3 ;
+
diff --git a/libs/python/example/README b/libs/python/example/README
new file mode 100644
index 000000000..29a94f67d
--- /dev/null
+++ b/libs/python/example/README
@@ -0,0 +1,16 @@
+.. Copyright David Abrahams 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+To get started with the Boost Python Library, use the examples
+getting_started1.cpp and getting_started2.cpp. Invoking
+
+ bjam --toolset=your-toolset test
+
+in this directory will build and run the examples. See
+http://www.boost.org/more/getting_started.html for details about the
+--toolset= option.
+
+If you move this example from its place in the Boost development tree
+you'll need to edit the two lines indicated in Jamroot and
+boost-build.jam.
diff --git a/libs/python/example/boost-build.jam b/libs/python/example/boost-build.jam
new file mode 100644
index 000000000..b7220e2c2
--- /dev/null
+++ b/libs/python/example/boost-build.jam
@@ -0,0 +1,7 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Edit this path to point at the tools/build/v2 subdirectory of your
+# Boost installation. Absolute paths work, too.
+boost-build ../../../tools/build/v2 ;
diff --git a/libs/python/example/getting_started1.cpp b/libs/python/example/getting_started1.cpp
new file mode 100644
index 000000000..09d681039
--- /dev/null
+++ b/libs/python/example/getting_started1.cpp
@@ -0,0 +1,25 @@
+// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <string>
+
+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; }
+}
+
+namespace python = boost::python;
+
+// Python requires an exported function called init<module-name> 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/libs/python/example/getting_started2.cpp b/libs/python/example/getting_started2.cpp
new file mode 100644
index 000000000..ee8af32e5
--- /dev/null
+++ b/libs/python/example/getting_started2.cpp
@@ -0,0 +1,41 @@
+// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <iostream>
+#include <string>
+
+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!";
+ }
+}
+
+BOOST_PYTHON_MODULE(getting_started2)
+{
+ using namespace boost::python;
+ class_<hello>("hello", init<std::string>())
+ // 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/libs/python/example/project.zip b/libs/python/example/project.zip
new file mode 100644
index 000000000..d863defdb
--- /dev/null
+++ b/libs/python/example/project.zip
Binary files differ
diff --git a/libs/python/example/quickstart/Jamroot b/libs/python/example/quickstart/Jamroot
new file mode 100644
index 000000000..569dae131
--- /dev/null
+++ b/libs/python/example/quickstart/Jamroot
@@ -0,0 +1,43 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Specify the path to the Boost project. If you move this project,
+# adjust the path to refer to the Boost root directory.
+use-project boost
+ : ../../../.. ;
+
+# Set up the project-wide requirements that everything uses the
+# boost_python library defined in the project whose global ID is
+# /boost/python.
+project boost-python-quickstart
+ : requirements <library>/boost/python//boost_python
+ ;
+
+# Make the definition of the python-extension rule available
+import python ;
+
+# Declare a Python extension called hello.
+python-extension extending : extending.cpp ;
+
+# Declare an executable called embedding that embeds Python
+exe embedding : embedding.cpp /python//python ;
+
+import testing ;
+
+# Declare a test of the extension module
+testing.make-test run-pyd : extending test_extending.py : : test_ext ;
+
+# Declare a test of the embedding application
+testing.run embedding
+ : # any ordinary arguments
+ : script.py # any arguments that should be treated as relative paths
+ : # requirements
+ : test_embed ; # name of test
+
+# Create a "test" target that runs all the tests
+alias test : test_ext test_embed ;
+
+# make sure the tests don't run by default
+explicit test_ext test_embed test ;
+
diff --git a/libs/python/example/quickstart/boost-build.jam b/libs/python/example/quickstart/boost-build.jam
new file mode 100644
index 000000000..a440ea9fe
--- /dev/null
+++ b/libs/python/example/quickstart/boost-build.jam
@@ -0,0 +1,7 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Edit this path to point at the tools/build/v2 subdirectory of your
+# Boost installation. Absolute paths work, too.
+boost-build ../../../../tools/build/v2 ;
diff --git a/libs/python/example/quickstart/embedding.cpp b/libs/python/example/quickstart/embedding.cpp
new file mode 100644
index 000000000..65bcd16a0
--- /dev/null
+++ b/libs/python/example/quickstart/embedding.cpp
@@ -0,0 +1,154 @@
+// Copyright Stefan Seefeld 2005.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+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() {}
+ virtual std::string hello() { return "Hello from C++!";}
+};
+
+// Familiar Boost.Python wrapper class for Base
+struct BaseWrap : Base, python::wrapper<Base>
+{
+ virtual std::string hello()
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ // workaround for VC++ 6.x or 7.0, see
+ // http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
+ return python::call<std::string>(this->get_override("hello").ptr());
+#else
+ return this->get_override("hello")();
+#endif
+ }
+};
+
+// Pack the Base class wrapper into a module
+BOOST_PYTHON_MODULE(embedded_hello)
+{
+ python::class_<BaseWrap, boost::noncopyable> base("Base");
+}
+
+
+void exec_test()
+{
+ std::cout << "registering extension module embedded_hello..." << std::endl;
+
+ // 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");
+
+ std::cout << "defining Python class derived from Base..." << std::endl;
+
+ // Retrieve the main module
+ python::object main = python::import("__main__");
+
+ // Retrieve the main module's namespace
+ python::object global(main.attr("__dict__"));
+
+ // Define the derived class in Python.
+ python::object result = python::exec(
+ "from embedded_hello import * \n"
+ "class PythonDerived(Base): \n"
+ " def hello(self): \n"
+ " return 'Hello from Python!' \n",
+ global, global);
+
+ python::object PythonDerived = global["PythonDerived"];
+
+ // Creating and using instances of the C++ class is as easy as always.
+ CppDerived cpp;
+ BOOST_TEST(cpp.hello() == "Hello from C++!");
+
+ std::cout << "testing derived class from C++..." << 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<Base&>(py_base) BOOST_EXTRACT_WORKAROUND;
+
+ // Make sure the right 'hello' method is called.
+ BOOST_TEST(py.hello() == "Hello from Python!");
+
+ std::cout << "success!" << std::endl;
+}
+
+void exec_file_test(std::string const &script)
+{
+ std::cout << "running file " << script << "..." << std::endl;
+
+ // Run a python script in an empty environment.
+ python::dict global;
+ python::object result = python::exec_file(script.c_str(), global, global);
+
+ // Extract an object the script stored in the global dictionary.
+ BOOST_TEST(python::extract<int>(global["number"]) == 42);
+
+ std::cout << "success!" << std::endl;
+}
+
+void exec_test_error()
+{
+ std::cout << "intentionally causing a python exception..." << std::endl;
+
+ // Execute a statement that raises a python exception.
+ python::dict global;
+ python::object result = python::exec("print unknown \n", global, global);
+
+ std::cout << "Oops! This statement should be skipped due to an exception" << std::endl;
+}
+
+int main(int argc, char **argv)
+{
+ BOOST_TEST(argc == 2);
+ std::string script = argv[1];
+ // Initialize the interpreter
+ Py_Initialize();
+
+ bool error_expected = false;
+
+ if (
+ python::handle_exception(exec_test)
+ || python::handle_exception(boost::bind(exec_file_test, script))
+ || (
+ (error_expected = true)
+ && python::handle_exception(exec_test_error)
+ )
+
+ )
+ {
+ if (PyErr_Occurred())
+ {
+ if (!error_expected)
+ BOOST_ERROR("Python Error detected");
+ PyErr_Print();
+ }
+ else
+ {
+ BOOST_ERROR("A C++ exception was thrown for which "
+ "there was no exception translator registered.");
+ }
+ }
+
+ // Boost.Python doesn't support Py_Finalize yet, so don't call it!
+ return boost::report_errors();
+}
diff --git a/libs/python/example/quickstart/extending.cpp b/libs/python/example/quickstart/extending.cpp
new file mode 100644
index 000000000..a539d3b4b
--- /dev/null
+++ b/libs/python/example/quickstart/extending.cpp
@@ -0,0 +1,41 @@
+// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <iostream>
+#include <string>
+
+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!";
+ }
+}
+
+BOOST_PYTHON_MODULE(extending)
+{
+ using namespace boost::python;
+ class_<hello>("hello", init<std::string>())
+ // 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/libs/python/example/quickstart/script.py b/libs/python/example/quickstart/script.py
new file mode 100644
index 000000000..5a8faf79f
--- /dev/null
+++ b/libs/python/example/quickstart/script.py
@@ -0,0 +1,6 @@
+# Copyright Stefan Seefeld 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+print 'Hello World !'
+number = 42
diff --git a/libs/python/example/quickstart/test_extending.py b/libs/python/example/quickstart/test_extending.py
new file mode 100644
index 000000000..14616f7c0
--- /dev/null
+++ b/libs/python/example/quickstart/test_extending.py
@@ -0,0 +1,36 @@
+# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Using the doctest module here to ensure that the results are as expected.
+r'''>>> from extending import *
+ >>> hi = hello('California')
+ >>> hi.greet()
+ 'Hello from California'
+ >>> invite(hi)
+ 'Hello from California! Please come soon!'
+ >>> hi.invite()
+ 'Hello from California! Please come soon!'
+
+ >>> class wordy(hello):
+ ... def greet(self):
+ ... return hello.greet(self) + ', where the weather is fine'
+ ...
+ >>> hi2 = wordy('Florida')
+ >>> hi2.greet()
+ 'Hello from Florida, where the weather is fine'
+ >>> invite(hi2)
+ 'Hello from Florida! Please come soon!'
+'''
+
+def run(args = None):
+ if args is not None:
+ import sys
+ sys.argv = args
+ import doctest, test_extending
+ return doctest.testmod(test_extending, verbose=True)
+
+if __name__ == '__main__':
+ import sys
+ sys.exit(run()[0])
+
diff --git a/libs/python/example/std_pair.cpp b/libs/python/example/std_pair.cpp
new file mode 100644
index 000000000..edf98dd65
--- /dev/null
+++ b/libs/python/example/std_pair.cpp
@@ -0,0 +1,49 @@
+// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/to_python_converter.hpp>
+
+namespace { // Avoid cluttering the global namespace.
+
+ // Converts a std::pair instance to a Python tuple.
+ template <typename T1, typename T2>
+ struct std_pair_to_tuple
+ {
+ static PyObject* convert(std::pair<T1, T2> const& p)
+ {
+ return boost::python::incref(
+ boost::python::make_tuple(p.first, p.second).ptr());
+ }
+ static PyTypeObject const *get_pytype () {return &PyTuple_Type; }
+ };
+
+ // Helper for convenience.
+ template <typename T1, typename T2>
+ struct std_pair_to_python_converter
+ {
+ std_pair_to_python_converter()
+ {
+ boost::python::to_python_converter<
+ std::pair<T1, T2>,
+ std_pair_to_tuple<T1, T2>,
+ true //std_pair_to_tuple has get_pytype
+ >();
+ }
+ };
+
+ // Example function returning a std::pair.
+ std::pair<int, int>
+ foo() { return std::pair<int, int>(3, 5); }
+
+} // namespace anonymous
+
+BOOST_PYTHON_MODULE(std_pair_ext)
+{
+ using namespace boost::python;
+ std_pair_to_python_converter<int, int>();
+ def("foo", foo);
+}
diff --git a/libs/python/example/test_getting_started1.py b/libs/python/example/test_getting_started1.py
new file mode 100644
index 000000000..32dc1f6eb
--- /dev/null
+++ b/libs/python/example/test_getting_started1.py
@@ -0,0 +1,21 @@
+# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+r'''>>> import getting_started1
+ >>> print getting_started1.greet()
+ hello, world
+ >>> number = 11
+ >>> print number, '*', number, '=', getting_started1.square(number)
+ 11 * 11 = 121
+'''
+
+def run(args = None):
+ if args is not None:
+ import sys
+ sys.argv = args
+ import doctest, test_getting_started1
+ return doctest.testmod(test_getting_started1)
+
+if __name__ == '__main__':
+ import sys
+ sys.exit(run()[0])
diff --git a/libs/python/example/test_getting_started2.py b/libs/python/example/test_getting_started2.py
new file mode 100644
index 000000000..ae86017b2
--- /dev/null
+++ b/libs/python/example/test_getting_started2.py
@@ -0,0 +1,34 @@
+# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+r'''>>> from getting_started2 import *
+ >>> hi = hello('California')
+ >>> hi.greet()
+ 'Hello from California'
+ >>> invite(hi)
+ 'Hello from California! Please come soon!'
+ >>> hi.invite()
+ 'Hello from California! Please come soon!'
+
+ >>> class wordy(hello):
+ ... def greet(self):
+ ... return hello.greet(self) + ', where the weather is fine'
+ ...
+ >>> hi2 = wordy('Florida')
+ >>> hi2.greet()
+ 'Hello from Florida, where the weather is fine'
+ >>> invite(hi2)
+ 'Hello from Florida! Please come soon!'
+'''
+
+def run(args = None):
+ if args is not None:
+ import sys
+ sys.argv = args
+ import doctest, test_getting_started2
+ return doctest.testmod(test_getting_started2)
+
+if __name__ == '__main__':
+ import sys
+ sys.exit(run()[0])
+
diff --git a/libs/python/example/test_std_pair.py b/libs/python/example/test_std_pair.py
new file mode 100644
index 000000000..64f239fea
--- /dev/null
+++ b/libs/python/example/test_std_pair.py
@@ -0,0 +1,6 @@
+# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+import std_pair_ext
+assert std_pair_ext.foo() == (3, 5)
+print "OK"
diff --git a/libs/python/example/tutorial/Jamroot b/libs/python/example/tutorial/Jamroot
new file mode 100644
index 000000000..1a70cb91a
--- /dev/null
+++ b/libs/python/example/tutorial/Jamroot
@@ -0,0 +1,48 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import python ;
+
+if ! [ python.configured ]
+{
+ ECHO "notice: no Python configured in user-config.jam" ;
+ ECHO "notice: will use default configuration" ;
+ using python ;
+}
+
+# Specify the path to the Boost project. If you move this project,
+# adjust this path to refer to the Boost root directory.
+use-project boost
+ : ../../../.. ;
+
+# Set up the project-wide requirements that everything uses the
+# boost_python library from the project whose global ID is
+# /boost/python.
+project
+ : requirements <library>/boost/python//boost_python ;
+
+# Declare the three extension modules. You can specify multiple
+# source files after the colon separated by spaces.
+python-extension hello_ext : hello.cpp ;
+
+# Put the extension and Boost.Python DLL in the current directory, so
+# that running script by hand works.
+install convenient_copy
+ : hello_ext
+ : <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
+ <location>.
+ ;
+
+# A little "rule" (function) to clean up the syntax of declaring tests
+# of these extension modules.
+local rule run-test ( test-name : sources + )
+{
+ import testing ;
+ testing.make-test run-pyd : $(sources) : : $(test-name) ;
+}
+
+# Declare test targets
+run-test hello : hello_ext hello.py ;
+
+
diff --git a/libs/python/example/tutorial/hello.cpp b/libs/python/example/tutorial/hello.cpp
new file mode 100644
index 000000000..d5114312b
--- /dev/null
+++ b/libs/python/example/tutorial/hello.cpp
@@ -0,0 +1,20 @@
+// Copyright Joel de Guzman 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+// Hello World Example from the tutorial
+// [Joel de Guzman 10/9/2002]
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+
+char const* greet()
+{
+ return "hello, world";
+}
+
+BOOST_PYTHON_MODULE(hello_ext)
+{
+ using namespace boost::python;
+ def("greet", greet);
+}
+
diff --git a/libs/python/example/tutorial/hello.py b/libs/python/example/tutorial/hello.py
new file mode 100755
index 000000000..d18b1c535
--- /dev/null
+++ b/libs/python/example/tutorial/hello.py
@@ -0,0 +1,7 @@
+# Copyright Joel de Guzman 2002-2007. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+# Hello World Example from the tutorial
+
+import hello_ext
+print hello_ext.greet()
diff --git a/libs/python/index.html b/libs/python/index.html
new file mode 100644
index 000000000..9c6acc885
--- /dev/null
+++ b/libs/python/index.html
@@ -0,0 +1,12 @@
+<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/index.html">
+</head>
+<body>
+Automatically loading index page... if nothing happens, please go to
+<a href="doc/index.html">doc/index.html</a>.
+</body>
+</html>
diff --git a/libs/python/pyste/NEWS b/libs/python/pyste/NEWS
new file mode 100644
index 000000000..31a5ceba2
--- /dev/null
+++ b/libs/python/pyste/NEWS
@@ -0,0 +1,212 @@
+.. Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+25 April 2005
+- Fixed bug where the code for wrappers of member functions were defined outside
+the pyste namespace. Reported by Dan Haffey.
+
+9 October 2004
+- Applied a patch by Christian Hudon that fixed an issue with files
+that had a tail and relative includes.
+
+18 July 2004
+- Applied a patch by Paul Bridger that solves some problems for wrapper
+methods.
+- Applied a patch by Baptiste Lepilleur that allows the user to inject
+code inside the class definition.
+- Applied another patch by Baptiste Lepilleur that inserts two new command-line
+options that helps with writing makefiles.
+
+27 May 2004
+Applied patch by Paul Bridger that solves a problem on windows regarding
+spaces on paths. Thanks Paul!
+
+Applied another patch that fixes the module name if pyste is run from
+another directory of where the .pyste file is located. Patch contributted
+by Paul Bridger.
+
+17 May 2004
+Applied a patch by Roman Yakovenko that makes the export of unnamed enums
+better. Thanks Roman!
+
+23 October 2003
+Fixed bug where a class would appear more than one in the generated code.
+
+6 October 2003
+Fixed bug reported by Niall Douglas (using his patch) about UniqueInt not
+appearing correctly with --multiple.
+
+Added precompiled header support on windows systems (using #pragma hdrstop).
+Suggested by Niall Douglas.
+
+Fixed a bug with -I directive and AllFromHeader. Reported by Scott Snyder.
+
+4 October 2003
+Added return_self, thanks for Niall Douglas for pointing out that it was
+missing.
+
+Added --file-list, where you can pass a file where the pyste files are listed
+one per line. Also suggested by Niall Douglas.
+
+Documentation has been finally updated, after a long wait. Please let me know
+if you spot any mistake!
+
+2 October 2003
+Scott Snyder found a typo in ClassExporter that prevented -= and *= operators
+from being exported. Thanks Scott!
+
+20 September 2003
+Added return_by_value in the list of policies supported. Thanks to Niall
+Douglas for the remainder.
+
+19 September 2003
+Better support for unnamed enums, plus they are by default exported to the
+parent's namespace. Normal enums can have the same behaviour using the function
+export_values on the Enum object. Feature requested by Niall Douglas.
+
+10 September 2003
+A new variable is accessible in the Pyste files: INTERFACE_FILE contains the
+full path of the pyste file.
+
+4 September 2003
+Now it is possible to override protected and private pure virtual functions
+in Python, as requested by Roman Yakovenko.
+
+23 August 2003
+Fixed bug where some Imports where not writing their include files.
+Now whenever the declarations change, the cache files are rebuilt
+automatically.
+
+19 August 2003
+Fixed a bug related to the generation of the bases<> template.
+
+17 August 2003
+Added support for insertion of user code in the generated code.
+
+16 August 2003
+Applied a patch by Gottfried Ganssauge that adds exception specifiers to
+wrapper functions and pointer declarations. Thanks a lot Gottfried!!
+
+Applied a patch by Prabhu Ramachandran that fixes ae problem with the
+pure virtual method generation. Thanks again Prabhu!
+
+10 August 2003
+Support for incremental generation of the code has been added. This changes
+how --multiple works; documentation of this new feature will follow. Thanks
+to Prabhu Ramachandran, that saw the need for this feature and discussed a
+solution.
+
+Automatically convert \ to / in Windows systems before passing the paths to
+gccxml.
+
+Fixed a bug reported by Prabhu Ramachandran, where in some classes the virtual
+methods were being definied incorrectly. Thanks a lot Prabhu!
+
+7 July 2003
+Applied 2 patches by Prabhu Ramachandran: a fix in the new --multiple method,
+and two new functions "hold_with_shared_ptr" and its counterpart for auto_ptr.
+Thanks a lot Prabhu!
+
+Fixed a bug where the macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID was being
+called multiple times for the same type.
+Thanks to Gottfried Ganßauge for reporting this!
+
+Fixed bug where using AllFromHeader didn't use bases<> when exporting
+hierarchies.
+
+Fixed the staticmethod bug.
+
+5 July 2003
+Changed how --multiple works: now it generates one cpp file for each pyste
+file, makeing easier to integrate Pyste with build systems.
+
+4 July 2003
+Applied patch that solved a bug in ClassExporter and added a distutils install
+script (install/setup.py), both contributed by Prabhu Ramachandran.
+Thanks Prabhu!
+
+2 July 2003
+Jim Wilson found a bug where types like "char**" were being interpreted as
+"char*". Thanks Jim!
+
+16 June 2003
+Thanks to discussions with David Abrahams and Roman Sulzhyk, some behaviours
+have changed:
+
+- If you export a derived class without exporting its base classes, the derived
+ class will explicitly export the bases's methods and attributes. Before, if
+ you were interested in the bases's methods, you had to export the base
+ classes too.
+
+- Added a new function, no_override. When a member function is specified as
+ "no_override", no virtual wrappers are generated for it, improving
+ performance and letting the code more clean.
+
+- There was a bug in which the policy of virtual member functions was being
+ ignored (patch by Roman Sulzhyk).
+
+Thanks again to Roman Sulzhyk for the patches and discussion in the c++-sig.
+
+4 June 2003
+Major improvements in memory usage.
+
+3 June 2003
+Appliced a patch from Giulio Eulisse that allows unnamed enumerations to be
+exported with an AllFromHeader construct. Thanks a lot Giulio!
+
+2 June 2003
+Added a new construct, add_method. See documentation.
+
+23 May 2003
+Support for global variables added.
+Various bug fixes.
+
+08 May 2003
+Fixed bug where in a certain cases the GCCXMLParser would end up with multiple
+declarations of the same class
+
+22 Apr 2003
+- Now shows a warning when the user tries to export a forward-declared class.
+ Forward-declared classes are ignored by the AllFromHeader construct.
+- Fixed a bug where classes, functions and enums where being exported, even if
+ excluded from a AllFromHeader construct.
+
+16 Apr 2003
+Added a more generic (but ugly) code to declare the smart pointer converters.
+
+07 Apr 2003
+- Removed the warnings about forward declarations: it was not accurate enough.
+ Another strategy must be thought of.
+- Fixed bug in the --multiple mode, where the order of the class instantiations
+ could end up wrong.
+- Lots of fixes in the documentation, pointed out by Dirk Gerrits. Thanks Dirk!
+- Fixed support for the return_opaque_pointer policy (the support macro was not
+ being declared).
+
+
+06 Apr 2003
+Support for the improved static data members support of Boost.Python.
+
+05 Apr 2003
+New option for generating the bindings: --multiple.
+
+02 Apr 2003
+Forward declarations are now detected and a warning is generated.
+
+24 Mar 2003
+Default policy for functions/methods that return const T& is now
+return_value_policy<copy_const_reference>().
+
+22 Mar 2003
+Exporting virtual methods of the base classes in the derived classes too.
+
+21 Mar 2003
+Added manual support for boost::shared_ptr and std::auto_ptr (see doc).
+
+19 Mar 2003
+Added support for int, double, float and long operators acting as expected in
+python.
+
+14 Mar 2003
+Fixed bug: Wrappers for protected and virtual methods were not being generated.
diff --git a/libs/python/pyste/README b/libs/python/pyste/README
new file mode 100644
index 000000000..c378f3916
--- /dev/null
+++ b/libs/python/pyste/README
@@ -0,0 +1,35 @@
+.. Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+Pyste - Python Semi-Automatic Exporter
+======================================
+
+Pyste is a Boost.Python code generator. The user specifies the classes and
+functions to be exported using a simple interface file, which following the
+Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to
+parse all the headers and extract the necessary information to automatically
+generate C++ code.
+
+The documentation can be found in the file index.html accompaning this README.
+
+Enjoy!
+Bruno da Silva de Oliveira (nicodemus@esss.com.br)
+
+Thanks
+======
+
+- David Abrahams, creator of Boost.Python, for tips on the syntax of the interface
+ file and support.
+- Marcelo Camelo, for design tips, support and inspiration for this project.
+ Also, the name was his idea. 8)
+- Brad King, creator of the excellent GCCXML (http://www.gccxml.org)
+- Fredrik Lundh, creator of the elementtree library (http://effbot.org)
+
+Bugs
+====
+
+Pyste is a young tool, so please help it to get better! Send bug reports to
+nicodemus@esss.com.br, accompaining the stack trace in case of exceptions.
+If possible, run pyste with --debug, and send the resulting xmls too (pyste
+will output a xml file with the same of each header it parsed).
diff --git a/libs/python/pyste/TODO b/libs/python/pyste/TODO
new file mode 100644
index 000000000..0b3c9024f
--- /dev/null
+++ b/libs/python/pyste/TODO
@@ -0,0 +1,18 @@
+.. Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+- Make Pyste accept already-generated xml files
+
+- throw() declaration in virtual wrapper's member functions
+
+- Allow protected methods to be overriden in Python
+
+- Expose programmability to the Pyste files (listing members of a class, for
+ instance)
+
+- Virtual operators
+
+- args() support
+
+- set policies to methods with the same name
diff --git a/libs/python/pyste/dist/create_build.py b/libs/python/pyste/dist/create_build.py
new file mode 100644
index 000000000..a68369951
--- /dev/null
+++ b/libs/python/pyste/dist/create_build.py
@@ -0,0 +1,55 @@
+# Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import os
+import sys
+import shutil
+import fnmatch
+from zipfile import ZipFile, ZIP_DEFLATED
+
+def findfiles(directory, mask):
+ def visit(files, dir, names):
+ for name in names:
+ if fnmatch.fnmatch(name, mask):
+ files.append(os.path.join(dir, name))
+ files = []
+ os.path.walk(directory, visit, files)
+ return files
+
+
+def main():
+ # test if PyXML is installed
+ try:
+ import _xmlplus.parsers.expat
+ pyxml = '--includes _xmlplus.parsers.expat'
+ except ImportError:
+ pyxml = ''
+ # create exe
+ status = os.system('python setup.py py2exe %s >& build.log' % pyxml)
+ if status != 0:
+ raise RuntimeError, 'Error creating EXE'
+
+ # create distribution
+ import pyste
+ version = pyste.__VERSION__
+ zip = ZipFile('pyste-%s.zip' % version, 'w', ZIP_DEFLATED)
+ # include the base files
+ dist_dir = 'dist/pyste'
+ for basefile in os.listdir(dist_dir):
+ zip.write(os.path.join(dist_dir, basefile), os.path.join('pyste', basefile))
+ # include documentation
+ for doc_file in findfiles('../doc', '*.*'):
+ dest_name = os.path.join('pyste/doc', doc_file[3:])
+ zip.write(doc_file, dest_name)
+ zip.write('../index.html', 'pyste/doc/index.html')
+ zip.close()
+ # cleanup
+ os.remove('build.log')
+ shutil.rmtree('build')
+ shutil.rmtree('dist')
+
+
+if __name__ == '__main__':
+ sys.path.append('../src')
+ main()
diff --git a/libs/python/pyste/dist/setup.py b/libs/python/pyste/dist/setup.py
new file mode 100644
index 000000000..fc7c74e21
--- /dev/null
+++ b/libs/python/pyste/dist/setup.py
@@ -0,0 +1,10 @@
+# Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+from distutils.core import setup
+import py2exe
+import sys
+
+sys.path.append('../src')
+setup(name='pyste', scripts=['../src/pyste.py'])
diff --git a/libs/python/pyste/doc/adding_new_methods.html b/libs/python/pyste/doc/adding_new_methods.html
new file mode 100644
index 000000000..afa772bcc
--- /dev/null
+++ b/libs/python/pyste/doc/adding_new_methods.html
@@ -0,0 +1,79 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Adding New Methods</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="global_variables.html">
+<link rel="next" href="inserting_code.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Adding New Methods</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="global_variables.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="inserting_code.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+Suppose that you want to add a function to a class, turning it into a member
+function:</p>
+<code><pre>
+ <span class=keyword>struct </span><span class=identifier>World
+ </span><span class=special>{
+ </span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
+ };
+
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>(</span><span class=identifier>World</span><span class=special>&amp; </span><span class=identifier>w</span><span class=special>)
+ {
+ </span><span class=keyword>return </span><span class=identifier>w</span><span class=special>.</span><span class=identifier>msg</span><span class=special>;
+ }
+</span></pre></code>
+<p>
+Here, we want to make <tt>greet</tt> work as a member function of the class <tt>World</tt>. We do
+that using the <tt>add_method</tt> construct:</p>
+<code><pre>
+ <span class=identifier>W </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>add_method</span><span class=special>(</span><span class=identifier>W</span><span class=special>, </span><span class=string>&quot;greet&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+Notice also that then you can rename it, set its policy, just like a regular
+member function:</p>
+<code><pre>
+ <span class=identifier>rename</span><span class=special>(</span><span class=identifier>W</span><span class=special>.</span><span class=identifier>greet</span><span class=special>, </span><span class=literal>'Greet'</span><span class=special>)
+</span></pre></code>
+<p>
+Now from Python:</p>
+<code><pre>
+ <span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>hello
+ </span><span class=special>&gt;&gt;&gt; </span><span class=identifier>w </span><span class=special>= </span><span class=identifier>hello</span><span class=special>.</span><span class=identifier>World</span><span class=special>()
+ &gt;&gt;&gt; </span><span class=identifier>w</span><span class=special>.</span><span class=identifier>set</span><span class=special>(</span><span class=literal>'Ni'</span><span class=special>)
+ &gt;&gt;&gt; </span><span class=identifier>w</span><span class=special>.</span><span class=identifier>greet</span><span class=special>()
+ </span><span class=literal>'Ni'
+ </span><span class=special>&gt;&gt;&gt; </span><span class=identifier>print </span><span class=literal>'Oh no! The knights who say Ni!'
+ </span><span class=identifier>Oh </span><span class=identifier>no</span><span class=special>! </span><span class=identifier>The </span><span class=identifier>knights </span><span class=identifier>who </span><span class=identifier>say </span><span class=identifier>Ni</span><span class=special>!
+</span></pre></code>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="global_variables.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="inserting_code.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/exporting_an_entire_header.html b/libs/python/pyste/doc/exporting_an_entire_header.html
new file mode 100644
index 000000000..db25325ca
--- /dev/null
+++ b/libs/python/pyste/doc/exporting_an_entire_header.html
@@ -0,0 +1,85 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Exporting An Entire Header</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="wrappers.html">
+<link rel="next" href="smart_pointers.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Exporting An Entire Header</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="wrappers.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="smart_pointers.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+Pyste also supports a mechanism to export all declarations found in a header
+file. Suppose again our file, <tt>hello.h</tt>:</p>
+<code><pre>
+ <span class=keyword>struct </span><span class=identifier>World
+ </span><span class=special>{
+ </span><span class=identifier>World</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>): </span><span class=identifier>msg</span><span class=special>(</span><span class=identifier>msg</span><span class=special>) {}
+ </span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
+ };
+
+ </span><span class=keyword>enum </span><span class=identifier>choice </span><span class=special>{ </span><span class=identifier>red</span><span class=special>, </span><span class=identifier>blue </span><span class=special>};
+
+ </span><span class=keyword>void </span><span class=identifier>show</span><span class=special>(</span><span class=identifier>choice </span><span class=identifier>c</span><span class=special>) { </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>&quot;value: &quot; </span><span class=special>&lt;&lt; (</span><span class=keyword>int</span><span class=special>)</span><span class=identifier>c </span><span class=special>&lt;&lt; </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>; }
+</span></pre></code>
+<p>
+You can just use the <tt>AllFromHeader</tt> construct:</p>
+<code><pre>
+ <span class=identifier>hello </span><span class=special>= </span><span class=identifier>AllFromHeader</span><span class=special>(</span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+this will export all the declarations found in <tt>hello.h</tt>, which is equivalent
+to write:</p>
+<code><pre>
+ <span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>Enum</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;show&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+Note that you can still use the functions <tt>rename</tt>, <tt>set_policy</tt>, <tt>exclude</tt>, etc. Just access
+the members of the header object like this:</p>
+<code><pre>
+ <span class=identifier>rename</span><span class=special>(</span><span class=identifier>hello</span><span class=special>.</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>greet</span><span class=special>, </span><span class=string>&quot;Greet&quot;</span><span class=special>)
+ </span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>hello</span><span class=special>.</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>set</span><span class=special>, </span><span class=string>&quot;Set&quot;</span><span class=special>)
+</span></pre></code>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="note_box">
+
+<img src="theme/note.gif"></img> <b>AllFromHeader is broken</b> in some cases. Until it is fixed,
+use at you own risk.
+ </td>
+ </tr>
+</table>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="wrappers.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="smart_pointers.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/global_variables.html b/libs/python/pyste/doc/global_variables.html
new file mode 100644
index 000000000..0efd2950b
--- /dev/null
+++ b/libs/python/pyste/doc/global_variables.html
@@ -0,0 +1,49 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Global Variables</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="smart_pointers.html">
+<link rel="next" href="adding_new_methods.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Global Variables</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="smart_pointers.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="adding_new_methods.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+To export global variables, use the <tt>Var</tt> construct:</p>
+<code><pre>
+ <span class=identifier>Var</span><span class=special>(</span><span class=string>&quot;myglobal&quot;</span><span class=special>, </span><span class=string>&quot;foo.h&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+Beware of non-const global variables: changes in Python won't reflect in C++!
+If you really must change them in Python, you will have to write some accessor
+functions, and export those.</p>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="smart_pointers.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="adding_new_methods.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/inserting_code.html b/libs/python/pyste/doc/inserting_code.html
new file mode 100644
index 000000000..97eb70f38
--- /dev/null
+++ b/libs/python/pyste/doc/inserting_code.html
@@ -0,0 +1,72 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Inserting Code</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="adding_new_methods.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Inserting Code</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="adding_new_methods.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
+ </tr>
+</table>
+<p>
+You can insert arbitrary code in the generated cpps, just use the functions
+<tt>declaration_code</tt> and <tt>module_code</tt>. This will insert the given string in the
+respective sections. Example:</p>
+<code><pre>
+ ##<span class=identifier>file </span><span class=identifier>A</span><span class=special>.</span><span class=identifier>pyste
+ </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;A&quot;</span><span class=special>, </span><span class=string>&quot;A.h&quot;</span><span class=special>)
+ </span><span class=identifier>declaration_code</span><span class=special>(</span><span class=string>&quot;/* declaration_code() comes here */\n&quot;</span><span class=special>)
+ </span><span class=identifier>module_code</span><span class=special>(</span><span class=string>&quot;/* module_code() comes here */\n&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+Will generate:</p>
+<code><pre>
+ <span class=comment>// Includes ====================================================================
+ </span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
+
+ // </span><span class=identifier>Using </span><span class=special>=======================================================================
+ </span><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>python</span><span class=special>;
+
+ // </span><span class=identifier>Declarations </span><span class=special>================================================================
+
+ /* </span><span class=identifier>declaration_code</span><span class=special>() </span><span class=identifier>comes </span><span class=identifier>here </span><span class=special>*/
+
+ // </span><span class=identifier>Module </span><span class=special>======================================================================
+ </span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>A</span><span class=special>)
+ {
+ </span><span class=identifier>class_</span><span class=special>&lt; </span><span class=identifier>A </span><span class=special>&gt;(</span><span class=string>&quot;A&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt; &gt;())
+ .</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special>&lt; </span><span class=keyword>const </span><span class=identifier>A</span><span class=special>&amp; &gt;())
+ ;
+
+ /* </span><span class=identifier>module_code</span><span class=special>() </span><span class=identifier>comes </span><span class=identifier>here </span><span class=special>*/
+ }
+</span></pre></code>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="adding_new_methods.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/introduction.html b/libs/python/pyste/doc/introduction.html
new file mode 100644
index 000000000..943884931
--- /dev/null
+++ b/libs/python/pyste/doc/introduction.html
@@ -0,0 +1,73 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Introduction</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="next" href="running_pyste.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Introduction</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
+ <td width="20"><a href="running_pyste.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<a name="what_is_pyste_"></a><h2>What is Pyste?</h2><p>
+Pyste is a <a href="../../index.html">
+Boost.Python</a> code generator. The user specifies the classes and
+functions to be exported using a simple <i>interface file</i>, which following the
+<a href="../../index.html">
+Boost.Python</a>'s philosophy, is simple Python code. Pyste then uses <a href="http://www.gccxml.org">
+GCCXML</a> to
+parse all the headers and extract the necessary information to automatically
+generate C++ code.</p>
+<a name="example"></a><h2>Example</h2><p>
+Let's borrow the class <tt>World</tt> from the <a href="../../doc/tutorial/doc/html/python/exposing.html">
+tutorial</a>: </p>
+<code><pre>
+ <span class=keyword>struct </span><span class=identifier>World
+ </span><span class=special>{
+ </span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
+ };
+</span></pre></code>
+<p>
+Here's the interface file for it, named <tt>world.pyste</tt>:</p>
+<code><pre>
+ <span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;world.h&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+and that's it!</p>
+<p>
+The next step is invoke Pyste in the command-line:</p>
+<code><pre>python pyste.py --module=hello world.pyste</pre></code><p>
+this will create a file &quot;<tt>hello.cpp</tt>&quot; in the directory where the command was
+run. </p>
+<p>
+Pyste supports the following features:</p>
+<ul><li>Functions</li><li>Classes</li><li>Class Templates</li><li>Virtual Methods</li><li>Overloading</li><li>Attributes </li><li>Enums (both &quot;free&quot; enums and class enums)</li><li>Nested Classes</li><li>Support for <tt>boost::shared_ptr</tt> and <tt>std::auto_ptr</tt></li><li>Global Variables</li></ul><table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
+ <td width="20"><a href="running_pyste.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/policies.html b/libs/python/pyste/doc/policies.html
new file mode 100644
index 000000000..3628093bd
--- /dev/null
+++ b/libs/python/pyste/doc/policies.html
@@ -0,0 +1,90 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Policies</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="renaming_and_excluding.html">
+<link rel="next" href="templates.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Policies</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="renaming_and_excluding.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="templates.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+Even thought Pyste can identify various elements in the C++ code, like virtual
+member functions, attributes, and so on, one thing that it can't do is to
+guess the semantics of functions that return pointers or references. In this
+case, the user must manually specify the policy. Policies are explained in the
+<a href="../../doc/tutorial/doc/html/python/functions.html#python.call_policies">
+tutorial</a>.</p>
+<p>
+The policies in Pyste are named exactly as in <a href="../../index.html">
+Boost.Python</a>, only the syntax is
+slightly different. For instance, this policy:</p>
+<code><pre>
+ <span class=identifier>return_internal_reference</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=identifier>with_custodian_and_ward</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>&gt; &gt;()
+</span></pre></code>
+<p>
+becomes in Pyste: </p>
+<code><pre>
+ <span class=identifier>return_internal_reference</span><span class=special>(</span><span class=number>1</span><span class=special>, </span><span class=identifier>with_custodian_and_ward</span><span class=special>(</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>))
+</span></pre></code>
+<p>
+The user can specify policies for functions and virtual member functions with
+the <tt>set_policy</tt> function:</p>
+<code><pre>
+ <span class=identifier>set_policy</span><span class=special>(</span><span class=identifier>f</span><span class=special>, </span><span class=identifier>return_internal_reference</span><span class=special>())
+ </span><span class=identifier>set_policy</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>return_value_policy</span><span class=special>(</span><span class=identifier>manage_new_object</span><span class=special>))
+</span></pre></code>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="note_box">
+
+<img src="theme/note.gif"></img> <b>What if a function or member function needs a policy and
+the user doesn't set one?</b><br><br> If a function needs a policy and one
+was not set, Pyste will issue a error. The user should then go in the
+interface file and set the policy for it, otherwise the generated cpp won't
+compile.
+ </td>
+ </tr>
+</table>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="note_box">
+
+<img src="theme/note.gif"></img>
+Note that for functions that return <tt>const T&amp;</tt>, the policy
+<tt>return_value_policy&lt;copy_const_reference&gt;()</tt> wil be used by default, because
+that's normally what you want. You can change it to something else if you need
+to, though.
+ </td>
+ </tr>
+</table>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="renaming_and_excluding.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="templates.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/pyste.txt b/libs/python/pyste/doc/pyste.txt
new file mode 100644
index 000000000..186a31cba
--- /dev/null
+++ b/libs/python/pyste/doc/pyste.txt
@@ -0,0 +1,664 @@
+[doc Pyste Documentation]
+
+[/ Copyright 2003 Bruno da Silva de Oliveira and Joel de Guzman.
+Distributed under the Boost Software License, Version 1.0. (See
+accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt) ]
+
+[def GCCXML [@http://www.gccxml.org GCCXML]]
+[def Boost.Python [@../../index.html Boost.Python]]
+
+[page Introduction]
+
+[h2 What is Pyste?]
+
+Pyste is a Boost.Python code generator. The user specifies the classes and
+functions to be exported using a simple ['interface file], which following the
+Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to
+parse all the headers and extract the necessary information to automatically
+generate C++ code.
+
+[h2 Example]
+
+Let's borrow the class [^World] from the [@../../doc/tutorial/doc/exposing_classes.html tutorial]:
+
+ struct World
+ {
+ void set(std::string msg) { this->msg = msg; }
+ std::string greet() { return msg; }
+ std::string msg;
+ };
+
+Here's the interface file for it, named [^world.pyste]:
+
+ Class("World", "world.h")
+
+and that's it!
+
+The next step is invoke Pyste in the command-line:
+
+[pre python pyste.py --module=hello world.pyste]
+
+this will create a file "[^hello.cpp]" in the directory where the command was
+run.
+
+Pyste supports the following features:
+
+* Functions
+* Classes
+* Class Templates
+* Virtual Methods
+* Overloading
+* Attributes
+* Enums (both "free" enums and class enums)
+* Nested Classes
+* Support for [^boost::shared_ptr] and [^std::auto_ptr]
+* Global Variables
+
+[page Running Pyste]
+
+To run Pyste, you will need:
+
+* Python 2.2, available at [@http://www.python.org python's website].
+* The great [@http://effbot.org elementtree] library, from Fredrik Lundh.
+* The excellent GCCXML, from Brad King.
+
+Installation for the tools is available in their respective webpages.
+
+[blurb
+[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so
+that Pyste can call it. How to do this varies from platform to platform.
+]
+
+[h2 Ok, now what?]
+
+Well, now let's fire it up:
+
+[pre
+'''
+>python pyste.py
+
+Pyste version 0.9.26
+
+Usage:
+ pyste [options] interface-files
+
+where options are:
+ --module=<name> The name of the module that will be generated;
+ defaults to the first interface filename, without
+ the extension.
+ -I <path> Add an include path
+ -D <symbol> Define symbol
+ --multiple Create various cpps, instead of only one
+ (useful during development)
+ --out=<name> Specify output filename (default: <module>.cpp)
+ in --multiple mode, this will be a directory
+ --no-using Do not declare "using namespace boost";
+ use explicit declarations instead
+ --pyste-ns=<name> Set the namespace where new types will be declared;
+ default is the empty namespace
+ --debug Writes the xml for each file parsed in the current
+ directory
+ --cache-dir=<dir> Directory for cache files (speeds up future runs)
+ --only-create-cache Recreates all caches (doesn't generate code).
+ --generate-main Generates the _main.cpp file (in multiple mode)
+ --file-list A file with one pyste file per line. Use as a
+ substitute for passing the files in the command
+ line.
+ -h, --help Print this help and exit
+ -v, --version Print version information
+
+'''
+]
+
+Options explained:
+
+The [^-I] and [^-D] are preprocessor flags, which are needed by GCCXML to parse
+the header files correctly and by Pyste to find the header files declared in the
+interface files.
+
+[^--out] names the output file (default: [^<module>.cpp]), or in multiple mode,
+names a output directory for the files (default: [^<module>]).
+
+[^--no-using] tells Pyste to don't declare "[^using namespace boost;]" in the
+generated cpp, using the namespace boost::python explicitly in all declarations.
+Use only if you're having a name conflict in one of the files.
+
+Use [^--pyste-ns] to change the namespace where new types are declared (for
+instance, the virtual wrappers). Use only if you are having any problems. By
+default, Pyste uses the empty namespace.
+
+[^--debug] will write in the current directory a xml file as outputted by GCCXML
+for each header parsed. Useful for bug reports.
+
+[^--file-list] names a file where each line points to a Pyste file. Use this instead
+to pass the pyste files if you have a lot of them and your shell has some command line
+size limit.
+
+The other options are explained below, in [@#multiple_mode [*Multiple Mode]] and
+[@#cache [*Cache]].
+
+[^-h, --help, -v, --version] are self-explaining, I believe. ;)
+
+So, the usage is simple enough:
+
+[pre >python pyste.py --module=mymodule file.pyste file2.pyste ...]
+
+will generate a file [^mymodule.cpp] in the same dir where the command was
+executed. Now you can compile the file using the same instructions of the
+[@../../doc/tutorial/doc/building_hello_world.html tutorial].
+
+[h2 Wait... how do I set those I and D flags?]
+
+Don't worry: normally GCCXML is already configured correctly for your plataform,
+so the search path to the standard libraries and the standard defines should
+already be set. You only have to set the paths to other libraries that your code
+needs, like Boost, for example.
+
+Plus, Pyste automatically uses the contents of the environment variable
+[^INCLUDE] if it exists. Visual C++ users should run the [^Vcvars32.bat] file,
+which for Visual C++ 6 is normally located at:
+
+ C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
+
+with that, you should have little trouble setting up the flags.
+
+[blurb [$theme/note.gif][*A note about Psyco][br][br]
+Although you don't have to install [@http://psyco.sourceforge.net/ Psyco] to
+use Pyste, if you do, Pyste will make use of it to speed up the wrapper
+generation. Speed ups of 30% can be achieved, so it's highly recommended.
+]
+
+
+[h2 Multiple Mode]
+
+The multiple mode is useful in large projects, where the presence of multiple
+classes in a single file makes the compilation unpractical (excessive memory
+usage, mostly).
+
+The solution is make Pyste generate multiple files, more specifically one cpp
+file for each Pyste file. This files will contain a function named after the
+file, for instance Export_MyPysteFile, which will contain all the code to export
+the classes, enums, etc. You can pass as much files as you want this way:
+
+[pre >python pyste.py --module=mymodule file1.pyste file2.pyste]
+
+This will create the files [^mymodule/file1.cpp] and [^mymodule/file2.cpp]. You
+can then later do:
+
+[pre >python pyste.py --module=mymodule file3.pyste]
+
+and [^mymodule/file3.cpp] will be generated.
+
+But compiling and linking this files won't be sufficient to generate your
+extension. You have to also generate a file named [^main.cpp]; call pyste with
+[*all] the Pyste files of your extension, and use the [^--generate-main] option:
+
+[pre >python pyste.py --module=mymodule --generate-main file1.pyste file2.pyste file3.pyste]
+
+Now compile and link all this files together and your extension is ready for
+use.
+
+[h2 Cache]
+
+Pyste now supports a form of cache, which is a way to speed up the code
+generation. Most of the time that Pyste takes to generate the code comes from
+having to execute GCCXML (since being a front-end to GCC, it has to compile the
+header files) and reading back the XML generated.
+
+When you use the [^--cache-dir=<dir>] option, Pyste will dump in the specified
+directory the generated XMLs to a file named after the Pyste file, with the
+extension [^.pystec]. The next time you run with this option, Pyste will use
+the cache, instead of calling GCCXML again:
+
+[pre >python pyste.py --module=mymodule --cache-dir=cache file1.pyste]
+
+Will generate [^file1.cpp] and [^cache/file1.pystec]. Next time you execute
+this command, the cache file will be used. Note that Pyste doesn't do any check
+to ensure that the cache is up to date, but you can configure your build system to do that for you.
+
+When you run Pyste with [^--only-create-cache], all the cache files will be
+created again, but no code will be generated.
+
+[page The Interface Files]
+
+The interface files are the heart of Pyste. The user creates one or more
+interface files declaring the classes and functions he wants to export, and then
+invokes Pyste passing the interface files to it. Pyste then generates a single
+cpp file with Boost.Python code, with all the classes and functions exported.
+
+Besides declaring the classes and functions, the user has a number of other
+options, like renaming e excluding classes and member functionis. Those are
+explained later on.
+
+[h2 Basics]
+
+Suppose we have a class and some functions that we want to expose to Python
+declared in the header [^hello.h]:
+
+ struct World
+ {
+ World(std::string msg): msg(msg) {}
+ void set(std::string msg) { this->msg = msg; }
+ std::string greet() { return msg; }
+ std::string msg;
+ };
+
+ enum choice { red, blue };
+
+ namespace test {
+
+ void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
+
+ }
+
+We create a file named [^hello.pyste] and create instances of the classes
+[^Function], [^Class] and [^Enum]:
+
+ Function("test::show", "hello.h")
+ Class("World", "hello.h")
+ Enum("choice", "hello.h")
+
+That will expose the class, the free function and the enum found in [^hello.h].
+
+[h2 Inheritance]
+
+Pyste automatically generates the correct code (specifying [^bases<>] in the
+[^class_] declaration) [*if] the Class() function that exports the base classes
+and their children are in the same Pyste file. If that's not the case, you have
+to indicate that there's a relationship between the Pyste files using the
+[^Import] function specifying the other Pyste file.
+
+Suppose we have two classes, [^A] and [^B], and A is a base class for B. We
+create two Pyste files:
+
+[^A.pyste]:
+
+ Class("A", "A.h")
+
+[^B.pyste]:
+
+ Import("A.pyste")
+ Class("B", "B.h")
+
+Note that we specify that [^B] needs to know about [^A] to be properly exported.
+
+[page:1 Renaming and Excluding]
+
+You can easily rename functions, classes, member functions, attributes, etc. Just use the
+function [^rename], like this:
+
+ World = Class("World", "hello.h")
+ rename(World, "IWorld")
+ show = Function("choice", "hello.h")
+ rename(show, "Show")
+
+You can rename member functions and attributes using this syntax:
+
+ rename(World.greet, "Greet")
+ rename(World.set, "Set")
+ choice = Enum("choice", "hello.h")
+ rename(choice.red, "Red")
+ rename(choice.blue, "Blue")
+
+You can exclude functions, classes, member functions, attributes, etc, in the same way,
+with the function [^exclude]:
+
+ exclude(World.greet)
+ exclude(World.msg)
+
+To access the operators of a class, access the member [^operator] like this
+(supposing that [^C] is a class being exported):
+
+ exclude(C.operator['+'])
+ exclude(C.operator['*'])
+ exclude(C.operator['<<'])
+
+The string inside the brackets is the same as the name of the operator in C++.[br]
+
+[h2 Virtual Member Functions]
+
+Pyste automatically generates wrappers for virtual member functions, but you may
+want to disable this behaviour (for performance reasons, for instance) if you do
+not plan to override the functions in Python. To do this, use the function
+[^final]:
+
+ C = Class('C', 'C.h')
+ final(C.foo) # C::foo is a virtual member function
+
+No virtual wrapper code will be generated for the virtual member function
+C::foo that way.
+
+[page:1 Policies]
+
+Even thought Pyste can identify various elements in the C++ code, like virtual
+member functions, attributes, and so on, one thing that it can't do is to
+guess the semantics of functions that return pointers or references. In this
+case, the user must manually specify the policy. Policies are explained in the
+[@../../doc/tutorial/doc/call_policies.html tutorial].
+
+The policies in Pyste are named exactly as in Boost.Python, only the syntax is
+slightly different. For instance, this policy:
+
+ return_internal_reference<1, with_custodian_and_ward<1, 2> >()
+
+becomes in Pyste:
+
+ return_internal_reference(1, with_custodian_and_ward(1, 2))
+
+The user can specify policies for functions and virtual member functions with
+the [^set_policy] function:
+
+ set_policy(f, return_internal_reference())
+ set_policy(C.foo, return_value_policy(manage_new_object))
+
+[blurb
+[$theme/note.gif] [*What if a function or member function needs a policy and
+the user doesn't set one?][br][br] If a function needs a policy and one
+was not set, Pyste will issue a error. The user should then go in the
+interface file and set the policy for it, otherwise the generated cpp won't
+compile.
+]
+
+[blurb
+[$theme/note.gif]
+Note that for functions that return [^const T&], the policy
+[^return_value_policy<copy_const_reference>()] wil be used by default, because
+that's normally what you want. You can change it to something else if you need
+to, though.
+]
+
+[page:1 Templates]
+
+Template classes can easily be exported too, but you can't export the template
+itself... you have to export instantiations of it! So, if you want to export a
+[^std::vector], you will have to export vectors of int, doubles, etc.
+
+Suppose we have this code:
+
+ template <class T>
+ struct Point
+ {
+ T x;
+ T y;
+ };
+
+And we want to export [^Point]s of int and double:
+
+ Point = Template("Point", "point.h")
+ Point("int")
+ Point("double")
+
+Pyste will assign default names for each instantiation. In this example, those
+would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to
+rename the instantiations:
+
+ Point("int", "IPoint") // renames the instantiation
+ double_inst = Point("double") // another way to do the same
+ rename(double_inst, "DPoint")
+
+Note that you can rename, exclude, set policies, etc, in the [^Template] object
+like you would do with a [^Function] or a [^Class]. This changes affect all
+[*future] instantiations:
+
+ Point = Template("Point", "point.h")
+ Point("float", "FPoint") // will have x and y as data members
+ rename(Point.x, "X")
+ rename(Point.y, "Y")
+ Point("int", "IPoint") // will have X and Y as data members
+ Point("double", "DPoint") // also will have X and Y as data member
+
+If you want to change a option of a particular instantiation, you can do so:
+
+ Point = Template("Point", "point.h")
+ Point("int", "IPoint")
+ d_inst = Point("double", "DPoint")
+ rename(d_inst.x, "X") // only DPoint is affect by this renames,
+ rename(d_inst.y, "Y") // IPoint stays intact
+
+[blurb [$theme/note.gif] [*What if my template accepts more than one type?]
+[br][br]
+When you want to instantiate a template with more than one type, you can pass
+either a string with the types separated by whitespace, or a list of strings
+'''("int double" or ["int", "double"]''' would both work).
+]
+
+[page:1 Wrappers]
+
+Suppose you have this function:
+
+ std::vector<std::string> names();
+
+But you don't want to [@../../doc/v2/faq.html#question2 to export std::vector<std::string>],
+you want this function to return a python list of strings. Boost.Python has
+excellent support for things like that:
+
+ list names_wrapper()
+ {
+ list result;
+ // call original function
+ vector<string> v = names();
+ // put all the strings inside the python list
+ vector<string>::iterator it;
+ for (it = v.begin(); it != v.end(); ++it){
+ result.append(*it);
+ }
+ return result;
+ }
+
+ BOOST_PYTHON_MODULE(test)
+ {
+ def("names", &names_wrapper);
+ }
+
+Nice heh? Pyste supports this mechanism too. You declare the [^names_wrapper]
+function in a header named "[^test_wrappers.h]" and in the interface file:
+
+ Include("test_wrappers.h")
+ names = Function("names", "test.h")
+ set_wrapper(names, "names_wrapper")
+
+You can optionally declare the function in the interface file itself:
+
+ names_wrapper = Wrapper("names_wrapper",
+ """
+ list names_wrapper()
+ {
+ // code to call name() and convert the vector to a list...
+ }
+ """)
+ names = Function("names", "test.h")
+ set_wrapper(names, names_wrapper)
+
+The same mechanism can be used with member functions too. Just remember that
+the first parameter of wrappers for member functions is a pointer to the
+class, as in:
+
+ struct C
+ {
+ std::vector<std::string> names();
+ }
+
+ list names_wrapper(C* c)
+ {
+ // same as before, calling c->names() and converting result to a list
+ }
+
+And then in the interface file:
+
+ C = Class("C", "test.h")
+ set_wrapper(C.names, "names_wrapper")
+
+[blurb
+[$theme/note.gif]Even though Boost.Python accepts either a pointer or a
+reference to the class in wrappers for member functions as the first parameter,
+Pyste expects them to be a [*pointer]. Doing otherwise will prevent your
+code to compile when you set a wrapper for a virtual member function.
+]
+
+[page:1 Exporting An Entire Header]
+
+Pyste also supports a mechanism to export all declarations found in a header
+file. Suppose again our file, [^hello.h]:
+
+ struct World
+ {
+ World(std::string msg): msg(msg) {}
+ void set(std::string msg) { this->msg = msg; }
+ std::string greet() { return msg; }
+ std::string msg;
+ };
+
+ enum choice { red, blue };
+
+ void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
+
+You can just use the [^AllFromHeader] construct:
+
+ hello = AllFromHeader("hello.h")
+
+this will export all the declarations found in [^hello.h], which is equivalent
+to write:
+
+ Class("World", "hello.h")
+ Enum("choice", "hello.h")
+ Function("show", "hello.h")
+
+Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access
+the members of the header object like this:
+
+ rename(hello.World.greet, "Greet")
+ exclude(hello.World.set, "Set")
+
+[blurb
+[$theme/note.gif] [*AllFromHeader is broken] in some cases. Until it is fixed,
+use at you own risk.
+]
+
+
+[page:1 Smart Pointers]
+
+Pyste for now has manual support for smart pointers. Suppose:
+
+ struct C
+ {
+ int value;
+ };
+
+ boost::shared_ptr<C> newC(int value)
+ {
+ boost::shared_ptr<C> c( new C() );
+ c->value = value;
+ return c;
+ }
+
+ void printC(boost::shared_ptr<C> c)
+ {
+ std::cout << c->value << std::endl;
+ }
+
+To make [^newC] and [^printC] work correctly, you have to tell Pyste that a
+convertor for [^boost::shared_ptr<C>] is needed.
+
+ C = Class('C', 'C.h')
+ use_shared_ptr(C)
+ Function('newC', 'C.h')
+ Function('printC', 'C.h')
+
+For [^std::auto_ptr]'s, use the function [^use_auto_ptr].
+
+This system is temporary, and in the future the converters will automatically be
+exported if needed, without the need to tell Pyste about them explicitly.
+
+[h2 Holders]
+
+If only the converter for the smart pointers is not enough and you need to
+specify the smart pointer as the holder for a class, use the functions
+[^hold_with_shared_ptr] and [^hold_with_auto_ptr]:
+
+ C = Class('C', 'C.h')
+ hold_with_shared_ptr(C)
+ Function('newC', 'C.h')
+ Function('printC', 'C.h')
+
+[page:1 Global Variables]
+
+To export global variables, use the [^Var] construct:
+
+ Var("myglobal", "foo.h")
+
+Beware of non-const global variables: changes in Python won't reflect in C++!
+If you really must change them in Python, you will have to write some accessor
+functions, and export those.
+
+
+[page:1 Adding New Methods]
+
+Suppose that you want to add a function to a class, turning it into a member
+function:
+
+ struct World
+ {
+ void set(std::string msg) { this->msg = msg; }
+ std::string msg;
+ };
+
+ std::string greet(World& w)
+ {
+ return w.msg;
+ }
+
+Here, we want to make [^greet] work as a member function of the class [^World]. We do
+that using the [^add_method] construct:
+
+ W = Class("World", "hello.h")
+ add_method(W, "greet")
+
+Notice also that then you can rename it, set its policy, just like a regular
+member function:
+
+ rename(W.greet, 'Greet')
+
+Now from Python:
+
+ >>> import hello
+ >>> w = hello.World()
+ >>> w.set('Ni')
+ >>> w.greet()
+ 'Ni'
+ >>> print 'Oh no! The knights who say Ni!'
+ Oh no! The knights who say Ni!
+
+
+[page:1 Inserting Code]
+
+You can insert arbitrary code in the generated cpps, just use the functions
+[^declaration_code] and [^module_code]. This will insert the given string in the
+respective sections. Example:
+
+ # file A.pyste
+ Class("A", "A.h")
+ declaration_code("/* declaration_code() comes here */\n")
+ module_code("/* module_code() comes here */\n")
+
+Will generate:
+
+ // Includes ====================================================================
+ #include <boost/python.hpp>
+
+ // Using =======================================================================
+ using namespace boost::python;
+
+ // Declarations ================================================================
+
+ /* declaration_code() comes here */
+
+ // Module ======================================================================
+ BOOST_PYTHON_MODULE(A)
+ {
+ class_< A >("A", init< >())
+ .def(init< const A& >())
+ ;
+
+ /* module_code() comes here */
+ }
diff --git a/libs/python/pyste/doc/renaming_and_excluding.html b/libs/python/pyste/doc/renaming_and_excluding.html
new file mode 100644
index 000000000..ce6654c4a
--- /dev/null
+++ b/libs/python/pyste/doc/renaming_and_excluding.html
@@ -0,0 +1,87 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Renaming and Excluding</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="the_interface_files.html">
+<link rel="next" href="policies.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Renaming and Excluding</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="the_interface_files.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+You can easily rename functions, classes, member functions, attributes, etc. Just use the
+function <tt>rename</tt>, like this:</p>
+<code><pre>
+ <span class=identifier>World </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>World</span><span class=special>, </span><span class=string>&quot;IWorld&quot;</span><span class=special>)
+ </span><span class=identifier>show </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>show</span><span class=special>, </span><span class=string>&quot;Show&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+You can rename member functions and attributes using this syntax:</p>
+<code><pre>
+ <span class=identifier>rename</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>greet</span><span class=special>, </span><span class=string>&quot;Greet&quot;</span><span class=special>)
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>set</span><span class=special>, </span><span class=string>&quot;Set&quot;</span><span class=special>)
+ </span><span class=identifier>choice </span><span class=special>= </span><span class=identifier>Enum</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>choice</span><span class=special>.</span><span class=identifier>red</span><span class=special>, </span><span class=string>&quot;Red&quot;</span><span class=special>)
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>choice</span><span class=special>.</span><span class=identifier>blue</span><span class=special>, </span><span class=string>&quot;Blue&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+You can exclude functions, classes, member functions, attributes, etc, in the same way,
+with the function <tt>exclude</tt>:</p>
+<code><pre>
+ <span class=identifier>exclude</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>greet</span><span class=special>)
+ </span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>World</span><span class=special>.</span><span class=identifier>msg</span><span class=special>)
+</span></pre></code>
+<p>
+To access the operators of a class, access the member <tt>operator</tt> like this
+(supposing that <tt>C</tt> is a class being exported):</p>
+<code><pre>
+ <span class=identifier>exclude</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=keyword>operator</span><span class=special>[</span><span class=literal>'+'</span><span class=special>])
+ </span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=keyword>operator</span><span class=special>[</span><span class=literal>'*'</span><span class=special>])
+ </span><span class=identifier>exclude</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=keyword>operator</span><span class=special>[</span><span class=literal>'&lt;&lt;'</span><span class=special>])
+</span></pre></code>
+<p>
+The string inside the brackets is the same as the name of the operator in C++.<br></p>
+<a name="virtual_member_functions"></a><h2>Virtual Member Functions</h2><p>
+Pyste automatically generates wrappers for virtual member functions, but you may
+want to disable this behaviour (for performance reasons, for instance) if you do
+not plan to override the functions in Python. To do this, use the function
+<tt>final</tt>:</p>
+<code><pre>
+ <span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=literal>'C'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
+ </span><span class=identifier>final</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=identifier>foo</span><span class=special>) </span>##<span class=identifier>C</span><span class=special>::</span><span class=identifier>foo </span><span class=identifier>is </span><span class=identifier>a </span><span class=keyword>virtual </span><span class=identifier>member </span><span class=identifier>function
+</span></pre></code>
+<p>
+No virtual wrapper code will be generated for the virtual member function
+C::foo that way.</p>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="the_interface_files.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/running_pyste.html b/libs/python/pyste/doc/running_pyste.html
new file mode 100644
index 000000000..9bd9a3aee
--- /dev/null
+++ b/libs/python/pyste/doc/running_pyste.html
@@ -0,0 +1,200 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Running Pyste</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="introduction.html">
+<link rel="next" href="the_interface_files.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Running Pyste</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="the_interface_files.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+To run Pyste, you will need:</p>
+<ul><li>Python 2.2, available at <a href="http://www.python.org">
+python's website</a>.</li><li>The great <a href="http://effbot.org">
+elementtree</a> library, from Fredrik Lundh.</li><li>The excellent <a href="http://www.gccxml.org">
+GCCXML</a>, from Brad King.</li></ul><p>
+Installation for the tools is available in their respective webpages.</p>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="note_box">
+
+<img src="theme/note.gif"></img> <a href="http://www.gccxml.org">
+GCCXML</a> must be accessible in the PATH environment variable, so
+that Pyste can call it. How to do this varies from platform to platform.
+ </td>
+ </tr>
+</table>
+<a name="ok__now_what_"></a><h2>Ok, now what?</h2><p>
+Well, now let's fire it up:</p>
+<code><pre>
+
+&gt;python pyste.py
+
+Pyste version 0.9.26
+
+Usage:
+ pyste [options] interface-files
+
+where options are:
+ --module=&lt;name&gt; The name of the module that will be generated;
+ defaults to the first interface filename, without
+ the extension.
+ -I &lt;path&gt; Add an include path
+ -D &lt;symbol&gt; Define symbol
+ --multiple Create various cpps, instead of only one
+ (useful during development)
+ --out=&lt;name&gt; Specify output filename (default: &lt;module&gt;.cpp)
+ in --multiple mode, this will be a directory
+ --no-using Do not declare &quot;using namespace boost&quot;;
+ use explicit declarations instead
+ --pyste-ns=&lt;name&gt; Set the namespace where new types will be declared;
+ default is the empty namespace
+ --debug Writes the xml for each file parsed in the current
+ directory
+ --cache-dir=&lt;dir&gt; Directory for cache files (speeds up future runs)
+ --only-create-cache Recreates all caches (doesn't generate code).
+ --generate-main Generates the _main.cpp file (in multiple mode)
+ --file-list A file with one pyste file per line. Use as a
+ substitute for passing the files in the command
+ line.
+ -h, --help Print this help and exit
+ -v, --version Print version information
+
+
+</pre></code><p>
+Options explained:</p>
+<p>
+The <tt>-I</tt> and <tt>-D</tt> are preprocessor flags, which are needed by <a href="http://www.gccxml.org">
+GCCXML</a> to parse
+the header files correctly and by Pyste to find the header files declared in the
+interface files.</p>
+<p>
+<tt>--out</tt> names the output file (default: <tt>&lt;module&gt;.cpp</tt>), or in multiple mode,
+names a output directory for the files (default: <tt>&lt;module&gt;</tt>).</p>
+<p>
+<tt>--no-using</tt> tells Pyste to don't declare &quot;<tt>using namespace boost;</tt>&quot; in the
+generated cpp, using the namespace boost::python explicitly in all declarations.
+Use only if you're having a name conflict in one of the files.</p>
+<p>
+Use <tt>--pyste-ns</tt> to change the namespace where new types are declared (for
+instance, the virtual wrappers). Use only if you are having any problems. By
+default, Pyste uses the empty namespace.</p>
+<p>
+<tt>--debug</tt> will write in the current directory a xml file as outputted by <a href="http://www.gccxml.org">
+GCCXML</a>
+for each header parsed. Useful for bug reports.</p>
+<p>
+<tt>--file-list</tt> names a file where each line points to a Pyste file. Use this instead
+to pass the pyste files if you have a lot of them and your shell has some command line
+size limit.</p>
+<p>
+The other options are explained below, in <a href="#multiple_mode">
+<b>Multiple Mode</b></a> and
+<a href="#cache">
+<b>Cache</b></a>.</p>
+<p>
+<tt>-h, --help, -v, --version</tt> are self-explaining, I believe. ;)</p>
+<p>
+So, the usage is simple enough:</p>
+<code><pre>&gt;python pyste.py --module=mymodule file.pyste file2.pyste ...</pre></code><p>
+will generate a file <tt>mymodule.cpp</tt> in the same dir where the command was
+executed. Now you can compile the file using the same instructions of the
+<a href="../../doc/tutorial/doc/html/python/hello.html">
+tutorial</a>. </p>
+<a name="wait____how_do_i_set_those_i_and_d_flags_"></a><h2>Wait... how do I set those I and D flags?</h2><p>
+Don't worry: normally <a href="http://www.gccxml.org">
+GCCXML</a> is already configured correctly for your plataform,
+so the search path to the standard libraries and the standard defines should
+already be set. You only have to set the paths to other libraries that your code
+needs, like Boost, for example.</p>
+<p>
+Plus, Pyste automatically uses the contents of the environment variable
+<tt>INCLUDE</tt> if it exists. Visual C++ users should run the <tt>Vcvars32.bat</tt> file,
+which for Visual C++ 6 is normally located at:</p>
+<code><pre>
+ <span class=identifier>C</span><span class=special>:\</span><span class=identifier>Program </span><span class=identifier>Files</span><span class=special>\</span><span class=identifier>Microsoft </span><span class=identifier>Visual </span><span class=identifier>Studio</span><span class=special>\</span><span class=identifier>VC98</span><span class=special>\</span><span class=identifier>bin</span><span class=special>\</span><span class=identifier>Vcvars32</span><span class=special>.</span><span class=identifier>bat
+</span></pre></code>
+<p>
+with that, you should have little trouble setting up the flags.</p>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="note_box">
+<img src="theme/note.gif"></img><b>A note about Psyco</b><br><br>
+Although you don't have to install <a href="http://psyco.sourceforge.net/">
+Psyco</a> to
+use Pyste, if you do, Pyste will make use of it to speed up the wrapper
+generation. Speed ups of 30% can be achieved, so it's highly recommended.
+ </td>
+ </tr>
+</table>
+<a name="multiple_mode"></a><h2>Multiple Mode</h2><p>
+The multiple mode is useful in large projects, where the presence of multiple
+classes in a single file makes the compilation unpractical (excessive memory
+usage, mostly). </p>
+<p>
+The solution is make Pyste generate multiple files, more specifically one cpp
+file for each Pyste file. This files will contain a function named after the
+file, for instance Export_MyPysteFile, which will contain all the code to export
+the classes, enums, etc. You can pass as much files as you want this way:</p>
+<code><pre>&gt;python pyste.py --module=mymodule file1.pyste file2.pyste</pre></code><p>
+This will create the files <tt>mymodule/file1.cpp</tt> and <tt>mymodule/file2.cpp</tt>. You
+can then later do:</p>
+<code><pre>&gt;python pyste.py --module=mymodule file3.pyste</pre></code><p>
+and <tt>mymodule/file3.cpp</tt> will be generated.</p>
+<p>
+But compiling and linking this files won't be sufficient to generate your
+extension. You have to also generate a file named <tt>main.cpp</tt>; call pyste with
+<b>all</b> the Pyste files of your extension, and use the <tt>--generate-main</tt> option:</p>
+<code><pre>&gt;python pyste.py --module=mymodule --generate-main file1.pyste file2.pyste file3.pyste</pre></code><p>
+Now compile and link all this files together and your extension is ready for
+use.</p>
+<a name="cache"></a><h2>Cache</h2><p>
+Pyste now supports a form of cache, which is a way to speed up the code
+generation. Most of the time that Pyste takes to generate the code comes from
+having to execute <a href="http://www.gccxml.org">
+GCCXML</a> (since being a front-end to GCC, it has to compile the
+header files) and reading back the XML generated. </p>
+<p>
+When you use the <tt>--cache-dir=&lt;dir&gt;</tt> option, Pyste will dump in the specified
+directory the generated XMLs to a file named after the Pyste file, with the
+extension <tt>.pystec</tt>. The next time you run with this option, Pyste will use
+the cache, instead of calling <a href="http://www.gccxml.org">
+GCCXML</a> again:</p>
+<code><pre>&gt;python pyste.py --module=mymodule --cache-dir=cache file1.pyste</pre></code><p>
+Will generate <tt>file1.cpp</tt> and <tt>cache/file1.pystec</tt>. Next time you execute
+this command, the cache file will be used. Note that Pyste doesn't do any check
+to ensure that the cache is up to date, but you can configure your build system to do that for you.</p>
+<p>
+When you run Pyste with <tt>--only-create-cache</tt>, all the cache files will be
+created again, but no code will be generated.</p>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="the_interface_files.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/smart_pointers.html b/libs/python/pyste/doc/smart_pointers.html
new file mode 100644
index 000000000..cddc96f2f
--- /dev/null
+++ b/libs/python/pyste/doc/smart_pointers.html
@@ -0,0 +1,84 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Smart Pointers</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="exporting_an_entire_header.html">
+<link rel="next" href="global_variables.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Smart Pointers</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="exporting_an_entire_header.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="global_variables.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+Pyste for now has manual support for smart pointers. Suppose:</p>
+<code><pre>
+ <span class=keyword>struct </span><span class=identifier>C
+ </span><span class=special>{
+ </span><span class=keyword>int </span><span class=identifier>value</span><span class=special>;
+ };
+
+ </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>shared_ptr</span><span class=special>&lt;</span><span class=identifier>C</span><span class=special>&gt; </span><span class=identifier>newC</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>value</span><span class=special>)
+ {
+ </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>shared_ptr</span><span class=special>&lt;</span><span class=identifier>C</span><span class=special>&gt; </span><span class=identifier>c</span><span class=special>( </span><span class=keyword>new </span><span class=identifier>C</span><span class=special>() );
+ </span><span class=identifier>c</span><span class=special>-&gt;</span><span class=identifier>value </span><span class=special>= </span><span class=identifier>value</span><span class=special>;
+ </span><span class=keyword>return </span><span class=identifier>c</span><span class=special>;
+ }
+
+ </span><span class=keyword>void </span><span class=identifier>printC</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>shared_ptr</span><span class=special>&lt;</span><span class=identifier>C</span><span class=special>&gt; </span><span class=identifier>c</span><span class=special>)
+ {
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>c</span><span class=special>-&gt;</span><span class=identifier>value </span><span class=special>&lt;&lt; </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;
+ }
+</span></pre></code>
+<p>
+To make <tt>newC</tt> and <tt>printC</tt> work correctly, you have to tell Pyste that a
+convertor for <tt>boost::shared_ptr&lt;C&gt;</tt> is needed.</p>
+<code><pre>
+ <span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=literal>'C'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
+ </span><span class=identifier>use_shared_ptr</span><span class=special>(</span><span class=identifier>C</span><span class=special>)
+ </span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'newC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
+ </span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'printC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
+</span></pre></code>
+<p>
+For <tt>std::auto_ptr</tt>'s, use the function <tt>use_auto_ptr</tt>.</p>
+<p>
+This system is temporary, and in the future the converters will automatically be
+exported if needed, without the need to tell Pyste about them explicitly.</p>
+<a name="holders"></a><h2>Holders</h2><p>
+If only the converter for the smart pointers is not enough and you need to
+specify the smart pointer as the holder for a class, use the functions
+<tt>hold_with_shared_ptr</tt> and <tt>hold_with_auto_ptr</tt>:</p>
+<code><pre>
+ <span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=literal>'C'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
+ </span><span class=identifier>hold_with_shared_ptr</span><span class=special>(</span><span class=identifier>C</span><span class=special>)
+ </span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'newC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
+ </span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'printC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
+</span></pre></code>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="exporting_an_entire_header.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="global_variables.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/templates.html b/libs/python/pyste/doc/templates.html
new file mode 100644
index 000000000..a1c1cfefb
--- /dev/null
+++ b/libs/python/pyste/doc/templates.html
@@ -0,0 +1,102 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Templates</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="policies.html">
+<link rel="next" href="wrappers.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Templates</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="wrappers.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+Template classes can easily be exported too, but you can't export the template
+itself... you have to export instantiations of it! So, if you want to export a
+<tt>std::vector</tt>, you will have to export vectors of int, doubles, etc.</p>
+<p>
+Suppose we have this code:</p>
+<code><pre>
+ <span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>class </span><span class=identifier>T</span><span class=special>&gt;
+ </span><span class=keyword>struct </span><span class=identifier>Point
+ </span><span class=special>{
+ </span><span class=identifier>T </span><span class=identifier>x</span><span class=special>;
+ </span><span class=identifier>T </span><span class=identifier>y</span><span class=special>;
+ };
+</span></pre></code>
+<p>
+And we want to export <tt>Point</tt>s of int and double:</p>
+<code><pre>
+ <span class=identifier>Point </span><span class=special>= </span><span class=identifier>Template</span><span class=special>(</span><span class=string>&quot;Point&quot;</span><span class=special>, </span><span class=string>&quot;point.h&quot;</span><span class=special>)
+ </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>)
+ </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+Pyste will assign default names for each instantiation. In this example, those
+would be &quot;<tt>Point_int</tt>&quot; and &quot;<tt>Point_double</tt>&quot;, but most of the time users will want to
+rename the instantiations:</p>
+<code><pre>
+ <span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>, </span><span class=string>&quot;IPoint&quot;</span><span class=special>) // </span><span class=identifier>renames </span><span class=identifier>the </span><span class=identifier>instantiation
+ </span><span class=identifier>double_inst </span><span class=special>= </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>) // </span><span class=identifier>another </span><span class=identifier>way </span><span class=identifier>to </span><span class=keyword>do </span><span class=identifier>the </span><span class=identifier>same
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>double_inst</span><span class=special>, </span><span class=string>&quot;DPoint&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+Note that you can rename, exclude, set policies, etc, in the <tt>Template</tt> object
+like you would do with a <tt>Function</tt> or a <tt>Class</tt>. This changes affect all
+<b>future</b> instantiations:</p>
+<code><pre>
+ <span class=identifier>Point </span><span class=special>= </span><span class=identifier>Template</span><span class=special>(</span><span class=string>&quot;Point&quot;</span><span class=special>, </span><span class=string>&quot;point.h&quot;</span><span class=special>)
+ </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;float&quot;</span><span class=special>, </span><span class=string>&quot;FPoint&quot;</span><span class=special>) // </span><span class=identifier>will </span><span class=identifier>have </span><span class=identifier>x </span><span class=keyword>and </span><span class=identifier>y </span><span class=identifier>as </span><span class=identifier>data </span><span class=identifier>members
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>Point</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=string>&quot;X&quot;</span><span class=special>)
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>Point</span><span class=special>.</span><span class=identifier>y</span><span class=special>, </span><span class=string>&quot;Y&quot;</span><span class=special>)
+ </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>, </span><span class=string>&quot;IPoint&quot;</span><span class=special>) // </span><span class=identifier>will </span><span class=identifier>have </span><span class=identifier>X </span><span class=keyword>and </span><span class=identifier>Y </span><span class=identifier>as </span><span class=identifier>data </span><span class=identifier>members
+ </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>, </span><span class=string>&quot;DPoint&quot;</span><span class=special>) // </span><span class=identifier>also </span><span class=identifier>will </span><span class=identifier>have </span><span class=identifier>X </span><span class=keyword>and </span><span class=identifier>Y </span><span class=identifier>as </span><span class=identifier>data </span><span class=identifier>member
+</span></pre></code>
+<p>
+If you want to change a option of a particular instantiation, you can do so:</p>
+<code><pre>
+ <span class=identifier>Point </span><span class=special>= </span><span class=identifier>Template</span><span class=special>(</span><span class=string>&quot;Point&quot;</span><span class=special>, </span><span class=string>&quot;point.h&quot;</span><span class=special>)
+ </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;int&quot;</span><span class=special>, </span><span class=string>&quot;IPoint&quot;</span><span class=special>)
+ </span><span class=identifier>d_inst </span><span class=special>= </span><span class=identifier>Point</span><span class=special>(</span><span class=string>&quot;double&quot;</span><span class=special>, </span><span class=string>&quot;DPoint&quot;</span><span class=special>)
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>d_inst</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=string>&quot;X&quot;</span><span class=special>) // </span><span class=identifier>only </span><span class=identifier>DPoint </span><span class=identifier>is </span><span class=identifier>affect </span><span class=identifier>by </span><span class=keyword>this </span><span class=identifier>renames</span><span class=special>,
+ </span><span class=identifier>rename</span><span class=special>(</span><span class=identifier>d_inst</span><span class=special>.</span><span class=identifier>y</span><span class=special>, </span><span class=string>&quot;Y&quot;</span><span class=special>) // </span><span class=identifier>IPoint </span><span class=identifier>stays </span><span class=identifier>intact
+</span></pre></code>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="note_box">
+<img src="theme/note.gif"></img> <b>What if my template accepts more than one type?</b>
+<br><br>
+When you want to instantiate a template with more than one type, you can pass
+either a string with the types separated by whitespace, or a list of strings
+(&quot;int double&quot; or [&quot;int&quot;, &quot;double&quot;] would both work).
+ </td>
+ </tr>
+</table>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="wrappers.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/the_interface_files.html b/libs/python/pyste/doc/the_interface_files.html
new file mode 100644
index 000000000..9c0200432
--- /dev/null
+++ b/libs/python/pyste/doc/the_interface_files.html
@@ -0,0 +1,102 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>The Interface Files</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="running_pyste.html">
+<link rel="next" href="renaming_and_excluding.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>The Interface Files</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="running_pyste.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="renaming_and_excluding.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+The interface files are the heart of Pyste. The user creates one or more
+interface files declaring the classes and functions he wants to export, and then
+invokes Pyste passing the interface files to it. Pyste then generates a single
+cpp file with <a href="../../index.html">
+Boost.Python</a> code, with all the classes and functions exported.</p>
+<p>
+Besides declaring the classes and functions, the user has a number of other
+options, like renaming e excluding classes and member functionis. Those are
+explained later on.</p>
+<a name="basics"></a><h2>Basics</h2><p>
+Suppose we have a class and some functions that we want to expose to Python
+declared in the header <tt>hello.h</tt>:</p>
+<code><pre>
+ <span class=keyword>struct </span><span class=identifier>World
+ </span><span class=special>{
+ </span><span class=identifier>World</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>): </span><span class=identifier>msg</span><span class=special>(</span><span class=identifier>msg</span><span class=special>) {}
+ </span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
+ };
+
+ </span><span class=keyword>enum </span><span class=identifier>choice </span><span class=special>{ </span><span class=identifier>red</span><span class=special>, </span><span class=identifier>blue </span><span class=special>};
+
+ </span><span class=keyword>namespace </span><span class=identifier>test </span><span class=special>{
+
+ </span><span class=keyword>void </span><span class=identifier>show</span><span class=special>(</span><span class=identifier>choice </span><span class=identifier>c</span><span class=special>) { </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>&quot;value: &quot; </span><span class=special>&lt;&lt; (</span><span class=keyword>int</span><span class=special>)</span><span class=identifier>c </span><span class=special>&lt;&lt; </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>; }
+
+ }
+</span></pre></code>
+<p>
+We create a file named <tt>hello.pyste</tt> and create instances of the classes
+<tt>Function</tt>, <tt>Class</tt> and <tt>Enum</tt>:</p>
+<code><pre>
+ <span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;test::show&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+ </span><span class=identifier>Enum</span><span class=special>(</span><span class=string>&quot;choice&quot;</span><span class=special>, </span><span class=string>&quot;hello.h&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+That will expose the class, the free function and the enum found in <tt>hello.h</tt>. </p>
+<a name="inheritance"></a><h2>Inheritance</h2><p>
+Pyste automatically generates the correct code (specifying <tt>bases&lt;&gt;</tt> in the
+<tt>class_</tt> declaration) <b>if</b> the Class() function that exports the base classes
+and their children are in the same Pyste file. If that's not the case, you have
+to indicate that there's a relationship between the Pyste files using the
+<tt>Import</tt> function specifying the other Pyste file.</p>
+<p>
+Suppose we have two classes, <tt>A</tt> and <tt>B</tt>, and A is a base class for B. We
+create two Pyste files:</p>
+<p>
+<tt>A.pyste</tt>:</p>
+<code><pre>
+ <span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;A&quot;</span><span class=special>, </span><span class=string>&quot;A.h&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+<tt>B.pyste</tt>:</p>
+<code><pre>
+ <span class=identifier>Import</span><span class=special>(</span><span class=string>&quot;A.pyste&quot;</span><span class=special>)
+ </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;B&quot;</span><span class=special>, </span><span class=string>&quot;B.h&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+Note that we specify that <tt>B</tt> needs to know about <tt>A</tt> to be properly exported.</p>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="running_pyste.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="renaming_and_excluding.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/doc/theme/alert.gif b/libs/python/pyste/doc/theme/alert.gif
new file mode 100644
index 000000000..270764cc5
--- /dev/null
+++ b/libs/python/pyste/doc/theme/alert.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/arrow.gif b/libs/python/pyste/doc/theme/arrow.gif
new file mode 100644
index 000000000..e33db0fb4
--- /dev/null
+++ b/libs/python/pyste/doc/theme/arrow.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/bkd.gif b/libs/python/pyste/doc/theme/bkd.gif
new file mode 100644
index 000000000..dcabcb806
--- /dev/null
+++ b/libs/python/pyste/doc/theme/bkd.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/bkd2.gif b/libs/python/pyste/doc/theme/bkd2.gif
new file mode 100644
index 000000000..b03d9ba97
--- /dev/null
+++ b/libs/python/pyste/doc/theme/bkd2.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/bulb.gif b/libs/python/pyste/doc/theme/bulb.gif
new file mode 100644
index 000000000..74f3baac4
--- /dev/null
+++ b/libs/python/pyste/doc/theme/bulb.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/bullet.gif b/libs/python/pyste/doc/theme/bullet.gif
new file mode 100644
index 000000000..da787e2ef
--- /dev/null
+++ b/libs/python/pyste/doc/theme/bullet.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/l_arr.gif b/libs/python/pyste/doc/theme/l_arr.gif
new file mode 100644
index 000000000..5b3cb1cbf
--- /dev/null
+++ b/libs/python/pyste/doc/theme/l_arr.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/l_arr_disabled.gif b/libs/python/pyste/doc/theme/l_arr_disabled.gif
new file mode 100644
index 000000000..ed58a605a
--- /dev/null
+++ b/libs/python/pyste/doc/theme/l_arr_disabled.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/note.gif b/libs/python/pyste/doc/theme/note.gif
new file mode 100644
index 000000000..bd92f0755
--- /dev/null
+++ b/libs/python/pyste/doc/theme/note.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/r_arr.gif b/libs/python/pyste/doc/theme/r_arr.gif
new file mode 100644
index 000000000..2dcdad117
--- /dev/null
+++ b/libs/python/pyste/doc/theme/r_arr.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/r_arr_disabled.gif b/libs/python/pyste/doc/theme/r_arr_disabled.gif
new file mode 100644
index 000000000..2100f78bf
--- /dev/null
+++ b/libs/python/pyste/doc/theme/r_arr_disabled.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/smiley.gif b/libs/python/pyste/doc/theme/smiley.gif
new file mode 100644
index 000000000..4c848f8fe
--- /dev/null
+++ b/libs/python/pyste/doc/theme/smiley.gif
Binary files differ
diff --git a/libs/python/pyste/doc/theme/style.css b/libs/python/pyste/doc/theme/style.css
new file mode 100644
index 000000000..643df02a9
--- /dev/null
+++ b/libs/python/pyste/doc/theme/style.css
@@ -0,0 +1,178 @@
+/*=============================================================================
+ Copyright (c) 2003 Bruno da Silva de Oliveira
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+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/libs/python/pyste/doc/theme/u_arr.gif b/libs/python/pyste/doc/theme/u_arr.gif
new file mode 100644
index 000000000..ada3d6e04
--- /dev/null
+++ b/libs/python/pyste/doc/theme/u_arr.gif
Binary files differ
diff --git a/libs/python/pyste/doc/wrappers.html b/libs/python/pyste/doc/wrappers.html
new file mode 100644
index 000000000..534ae5529
--- /dev/null
+++ b/libs/python/pyste/doc/wrappers.html
@@ -0,0 +1,124 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Wrappers</title>
+<link rel="stylesheet" href="theme/style.css" type="text/css">
+<link rel="prev" href="templates.html">
+<link rel="next" href="exporting_an_entire_header.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Wrappers</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="templates.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="exporting_an_entire_header.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<p>
+Suppose you have this function:</p>
+<code><pre>
+ <span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>names</span><span class=special>();
+</span></pre></code>
+<p>
+But you don't want to <a href="../../doc/v2/faq.html#question2">
+to export std::vector&lt;std::string&gt;</a>,
+you want this function to return a python list of strings. <a href="../../index.html">
+Boost.Python</a> has
+excellent support for things like that:</p>
+<code><pre>
+ <span class=identifier>list </span><span class=identifier>names_wrapper</span><span class=special>()
+ {
+ </span><span class=identifier>list </span><span class=identifier>result</span><span class=special>;
+ // </span><span class=identifier>call </span><span class=identifier>original </span><span class=identifier>function
+ </span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>names</span><span class=special>();
+ // </span><span class=identifier>put </span><span class=identifier>all </span><span class=identifier>the </span><span class=identifier>strings </span><span class=identifier>inside </span><span class=identifier>the </span><span class=identifier>python </span><span class=identifier>list
+ </span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>string</span><span class=special>&gt;::</span><span class=identifier>iterator </span><span class=identifier>it</span><span class=special>;
+ </span><span class=keyword>for </span><span class=special>(</span><span class=identifier>it </span><span class=special>= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(); </span><span class=identifier>it </span><span class=special>!= </span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>(); ++</span><span class=identifier>it</span><span class=special>){
+ </span><span class=identifier>result</span><span class=special>.</span><span class=identifier>append</span><span class=special>(*</span><span class=identifier>it</span><span class=special>);
+ }
+ </span><span class=keyword>return </span><span class=identifier>result</span><span class=special>;
+ }
+
+ </span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>test</span><span class=special>)
+ {
+ </span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;names&quot;</span><span class=special>, &amp;</span><span class=identifier>names_wrapper</span><span class=special>);
+ }
+</span></pre></code>
+<p>
+Nice heh? Pyste supports this mechanism too. You declare the <tt>names_wrapper</tt>
+function in a header named &quot;<tt>test_wrappers.h</tt>&quot; and in the interface file:</p>
+<code><pre>
+ <span class=identifier>Include</span><span class=special>(</span><span class=string>&quot;test_wrappers.h&quot;</span><span class=special>)
+ </span><span class=identifier>names </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;names&quot;</span><span class=special>, </span><span class=string>&quot;test.h&quot;</span><span class=special>)
+ </span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>names</span><span class=special>, </span><span class=string>&quot;names_wrapper&quot;</span><span class=special>)
+</span></pre></code>
+<p>
+You can optionally declare the function in the interface file itself:</p>
+<code><pre>
+ <span class=identifier>names_wrapper </span><span class=special>= </span><span class=identifier>Wrapper</span><span class=special>(</span><span class=string>&quot;names_wrapper&quot;</span><span class=special>,
+ </span><span class=string>&quot;&quot;</span><span class=string>&quot;
+ list names_wrapper()
+ {
+ // code to call name() and convert the vector to a list...
+ }
+ &quot;</span><span class=string>&quot;&quot;</span><span class=special>)
+ </span><span class=identifier>names </span><span class=special>= </span><span class=identifier>Function</span><span class=special>(</span><span class=string>&quot;names&quot;</span><span class=special>, </span><span class=string>&quot;test.h&quot;</span><span class=special>)
+ </span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>names</span><span class=special>, </span><span class=identifier>names_wrapper</span><span class=special>)
+</span></pre></code>
+<p>
+The same mechanism can be used with member functions too. Just remember that
+the first parameter of wrappers for member functions is a pointer to the
+class, as in:</p>
+<code><pre>
+ <span class=keyword>struct </span><span class=identifier>C
+ </span><span class=special>{
+ </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>names</span><span class=special>();
+ }
+
+ </span><span class=identifier>list </span><span class=identifier>names_wrapper</span><span class=special>(</span><span class=identifier>C</span><span class=special>* </span><span class=identifier>c</span><span class=special>)
+ {
+ // </span><span class=identifier>same </span><span class=identifier>as </span><span class=identifier>before</span><span class=special>, </span><span class=identifier>calling </span><span class=identifier>c</span><span class=special>-&gt;</span><span class=identifier>names</span><span class=special>() </span><span class=keyword>and </span><span class=identifier>converting </span><span class=identifier>result </span><span class=identifier>to </span><span class=identifier>a </span><span class=identifier>list
+ </span><span class=special>}
+</span></pre></code>
+<p>
+And then in the interface file:</p>
+<code><pre>
+ <span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=string>&quot;C&quot;</span><span class=special>, </span><span class=string>&quot;test.h&quot;</span><span class=special>)
+ </span><span class=identifier>set_wrapper</span><span class=special>(</span><span class=identifier>C</span><span class=special>.</span><span class=identifier>names</span><span class=special>, </span><span class=string>&quot;names_wrapper&quot;</span><span class=special>)
+</span></pre></code>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="note_box">
+
+<img src="theme/note.gif"></img>Even though <a href="../../index.html">
+Boost.Python</a> accepts either a pointer or a
+reference to the class in wrappers for member functions as the first parameter,
+Pyste expects them to be a <b>pointer</b>. Doing otherwise will prevent your
+code to compile when you set a wrapper for a virtual member function.
+ </td>
+ </tr>
+</table>
+<table border="0">
+ <tr>
+ <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
+ <td width="30"><a href="templates.html"><img src="theme/l_arr.gif" border="0"></a></td>
+ <td width="20"><a href="exporting_an_entire_header.html"><img src="theme/r_arr.gif" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/index.html b/libs/python/pyste/index.html
new file mode 100644
index 000000000..953b37c12
--- /dev/null
+++ b/libs/python/pyste/index.html
@@ -0,0 +1,90 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Pyste Documentation</title>
+<link rel="stylesheet" href="doc/theme/style.css" type="text/css">
+<link rel="next" href="doc/introduction.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" cellspacing="2">
+ <tr>
+ <td><img src="../../../boost.png">
+ </td>
+ <td width="85%">
+ <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Pyste Documentation</b></font>
+ </td>
+ </tr>
+</table>
+<br>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="toc_title">Table of contents</td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/introduction.html">Introduction</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/running_pyste.html">Running Pyste</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/the_interface_files.html">The Interface Files</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/renaming_and_excluding.html">Renaming and Excluding</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/policies.html">Policies</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/templates.html">Templates</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/wrappers.html">Wrappers</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/exporting_an_entire_header.html">Exporting An Entire Header</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/smart_pointers.html">Smart Pointers</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/global_variables.html">Global Variables</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/adding_new_methods.html">Adding New Methods</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/inserting_code.html">Inserting Code</a>
+ </td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2003 Bruno da Silva de Oliveira<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
+<font size="2">Distributed under
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) </font> </p>
+</body>
+</html>
diff --git a/libs/python/pyste/install/pyste.py b/libs/python/pyste/install/pyste.py
new file mode 100644
index 000000000..da9262353
--- /dev/null
+++ b/libs/python/pyste/install/pyste.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+# Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+from Pyste import pyste
+pyste.main()
diff --git a/libs/python/pyste/install/setup.py b/libs/python/pyste/install/setup.py
new file mode 100644
index 000000000..c17039817
--- /dev/null
+++ b/libs/python/pyste/install/setup.py
@@ -0,0 +1,20 @@
+# Copyright Prabhu Ramachandran 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+from distutils.core import setup
+import sys
+
+setup (name = "Pyste",
+ version = "0.9.10",
+ description = "Pyste - Python Semi-Automatic Exporter",
+ maintainer = "Bruno da Silva de Oliveira",
+ maintainer_email = "nicodemus@globalite.com.br",
+ licence = "Boost License",
+ long_description = "Pyste is a Boost.Python code generator",
+ url = "http://www.boost.org/libs/python/pyste/index.html",
+ platforms = ['Any'],
+ packages = ['Pyste'],
+ scripts = ['pyste.py'],
+ package_dir = {'Pyste': '../src/Pyste'},
+ )
diff --git a/libs/python/pyste/src/Pyste/ClassExporter.py b/libs/python/pyste/src/Pyste/ClassExporter.py
new file mode 100644
index 000000000..decaf628e
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/ClassExporter.py
@@ -0,0 +1,918 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import exporters
+from Exporter import Exporter
+from declarations import *
+from settings import *
+from policies import *
+from SingleCodeUnit import SingleCodeUnit
+from EnumExporter import EnumExporter
+from utils import makeid, enumerate
+import copy
+import exporterutils
+import re
+
+#==============================================================================
+# ClassExporter
+#==============================================================================
+class ClassExporter(Exporter):
+ 'Generates boost.python code to export a class declaration'
+
+ def __init__(self, info, parser_tail=None):
+ Exporter.__init__(self, info, parser_tail)
+ # sections of code
+ self.sections = {}
+ # template: each item in the list is an item into the class_<...>
+ # section.
+ self.sections['template'] = []
+ # constructor: each item in the list is a parameter to the class_
+ # constructor, like class_<C>(...)
+ self.sections['constructor'] = []
+ # inside: everything within the class_<> statement
+ self.sections['inside'] = []
+ # scope: items outside the class statement but within its scope.
+ # scope* s = new scope(class<>());
+ # ...
+ # delete s;
+ self.sections['scope'] = []
+ # declarations: outside the BOOST_PYTHON_MODULE macro
+ self.sections['declaration'] = []
+ self.sections['declaration-outside'] = []
+ self.sections['include'] = []
+ # a list of Constructor instances
+ self.constructors = []
+ # a list of code units, generated by nested declarations
+ self.nested_codeunits = []
+
+
+ def ScopeName(self):
+ return makeid(self.class_.FullName()) + '_scope'
+
+
+ def Name(self):
+ return self.info.name
+
+
+ def SetDeclarations(self, declarations):
+ Exporter.SetDeclarations(self, declarations)
+ if self.declarations:
+ decl = self.GetDeclaration(self.info.name)
+ if isinstance(decl, Typedef):
+ self.class_ = self.GetDeclaration(decl.type.name)
+ if not self.info.rename:
+ self.info.rename = decl.name
+ else:
+ self.class_ = decl
+ self.class_ = copy.deepcopy(self.class_)
+ else:
+ self.class_ = None
+
+
+ def ClassBases(self):
+ all_bases = []
+ for level in self.class_.hierarchy:
+ for base in level:
+ all_bases.append(base)
+ return [self.GetDeclaration(x.name) for x in all_bases]
+
+
+ def Order(self):
+ '''Return the TOTAL number of bases that this class has, including the
+ bases' bases. Do this because base classes must be instantialized
+ before the derived classes in the module definition.
+ '''
+ num_bases = len(self.ClassBases())
+ return num_bases, self.class_.FullName()
+
+
+ def Export(self, codeunit, exported_names):
+ self.InheritMethods(exported_names)
+ self.MakeNonVirtual()
+ if not self.info.exclude:
+ self.ExportBasics()
+ self.ExportBases(exported_names)
+ self.ExportConstructors()
+ self.ExportVariables()
+ self.ExportVirtualMethods(codeunit)
+ self.ExportMethods()
+ self.ExportOperators()
+ self.ExportNestedClasses(exported_names)
+ self.ExportNestedEnums(exported_names)
+ self.ExportSmartPointer()
+ self.ExportOpaquePointerPolicies()
+ self.ExportAddedCode()
+ self.Write(codeunit)
+ exported_names[self.Name()] = 1
+
+
+ def InheritMethods(self, exported_names):
+ '''Go up in the class hierarchy looking for classes that were not
+ exported yet, and then add their public members to this classes
+ members, as if they were members of this class. This allows the user to
+ just export one type and automatically get all the members from the
+ base classes.
+ '''
+ valid_members = (Method, ClassVariable, NestedClass, ClassEnumeration)
+ fullnames = [x.FullName() for x in self.class_]
+ pointers = [x.PointerDeclaration(True) for x in self.class_ if isinstance(x, Method)]
+ fullnames = dict([(x, None) for x in fullnames])
+ pointers = dict([(x, None) for x in pointers])
+ for level in self.class_.hierarchy:
+ level_exported = False
+ for base in level:
+ base = self.GetDeclaration(base.name)
+ if base.FullName() not in exported_names:
+ for member in base:
+ if type(member) in valid_members:
+ member_copy = copy.deepcopy(member)
+ member_copy.class_ = self.class_.FullName()
+ if isinstance(member_copy, Method):
+ pointer = member_copy.PointerDeclaration(True)
+ if pointer not in pointers:
+ self.class_.AddMember(member)
+ pointers[pointer] = None
+ elif member_copy.FullName() not in fullnames:
+ self.class_.AddMember(member)
+ else:
+ level_exported = True
+ if level_exported:
+ break
+ def IsValid(member):
+ return isinstance(member, valid_members) and member.visibility == Scope.public
+ self.public_members = [x for x in self.class_ if IsValid(x)]
+
+
+ def Write(self, codeunit):
+ indent = self.INDENT
+ boost_ns = namespaces.python
+ pyste_ns = namespaces.pyste
+ code = ''
+ # begin a scope for this class if needed
+ nested_codeunits = self.nested_codeunits
+ needs_scope = self.sections['scope'] or nested_codeunits
+ if needs_scope:
+ scope_name = self.ScopeName()
+ code += indent + boost_ns + 'scope* %s = new %sscope(\n' %\
+ (scope_name, boost_ns)
+ # export the template section
+ template_params = ', '.join(self.sections['template'])
+ code += indent + boost_ns + 'class_< %s >' % template_params
+ # export the constructor section
+ constructor_params = ', '.join(self.sections['constructor'])
+ code += '(%s)\n' % constructor_params
+ # export the inside section
+ in_indent = indent*2
+ for line in self.sections['inside']:
+ code += in_indent + line + '\n'
+ # write the scope section and end it
+ if not needs_scope:
+ code += indent + ';\n'
+ else:
+ code += indent + ');\n'
+ for line in self.sections['scope']:
+ code += indent + line + '\n'
+ # write the contents of the nested classes
+ for nested_unit in nested_codeunits:
+ code += '\n' + nested_unit.Section('module')
+ # close the scope
+ code += indent + 'delete %s;\n' % scope_name
+
+ # write the code to the module section in the codeunit
+ codeunit.Write('module', code + '\n')
+
+ # write the declarations to the codeunit
+ declarations = '\n'.join(self.sections['declaration'])
+ for nested_unit in nested_codeunits:
+ declarations += nested_unit.Section('declaration')
+ if declarations:
+ codeunit.Write('declaration', declarations + '\n')
+ declarations_outside = '\n'.join(self.sections['declaration-outside'])
+ if declarations_outside:
+ codeunit.Write('declaration-outside', declarations_outside + '\n')
+
+ # write the includes to the codeunit
+ includes = '\n'.join(self.sections['include'])
+ for nested_unit in nested_codeunits:
+ includes += nested_unit.Section('include')
+ if includes:
+ codeunit.Write('include', includes)
+
+
+ def Add(self, section, item):
+ 'Add the item into the corresponding section'
+ self.sections[section].append(item)
+
+
+ def ExportBasics(self):
+ '''Export the name of the class and its class_ statement.'''
+ class_name = self.class_.FullName()
+ self.Add('template', class_name)
+ name = self.info.rename or self.class_.name
+ self.Add('constructor', '"%s"' % name)
+
+
+ def ExportBases(self, exported_names):
+ 'Expose the bases of the class into the template section'
+ hierarchy = self.class_.hierarchy
+ exported = []
+ for level in hierarchy:
+ for base in level:
+ if base.visibility == Scope.public and base.name in exported_names:
+ exported.append(base.name)
+ if exported:
+ break
+ if exported:
+ code = namespaces.python + 'bases< %s > ' % (', '.join(exported))
+ self.Add('template', code)
+
+
+ def ExportConstructors(self):
+ '''Exports all the public contructors of the class, plus indicates if the
+ class is noncopyable.
+ '''
+ py_ns = namespaces.python
+ indent = self.INDENT
+
+ def init_code(cons):
+ 'return the init<>() code for the given contructor'
+ param_list = [p.FullName() for p in cons.parameters]
+ min_params_list = param_list[:cons.minArgs]
+ max_params_list = param_list[cons.minArgs:]
+ min_params = ', '.join(min_params_list)
+ max_params = ', '.join(max_params_list)
+ init = py_ns + 'init< '
+ init += min_params
+ if max_params:
+ if min_params:
+ init += ', '
+ init += py_ns + ('optional< %s >' % max_params)
+ init += ' >()'
+ return init
+
+ constructors = [x for x in self.public_members if isinstance(x, Constructor)]
+ # don't export copy constructors if the class is abstract
+ # we could remove all constructors, but this will have the effect of
+ # inserting no_init in the declaration, which would not allow
+ # even subclasses to be instantiated.
+ self.constructors = constructors[:]
+ if self.class_.abstract:
+ for cons in constructors:
+ if cons.IsCopy():
+ constructors.remove(cons)
+ break
+
+ if not constructors:
+ # declare no_init
+ self.Add('constructor', py_ns + 'no_init')
+ else:
+ # write the constructor with less parameters to the constructor section
+ smaller = None
+ for cons in constructors:
+ if smaller is None or len(cons.parameters) < len(smaller.parameters):
+ smaller = cons
+ assert smaller is not None
+ self.Add('constructor', init_code(smaller))
+ constructors.remove(smaller)
+ # write the rest to the inside section, using def()
+ for cons in constructors:
+ code = '.def(%s)' % init_code(cons)
+ self.Add('inside', code)
+
+ # check if the class is copyable
+ if not self.class_.HasCopyConstructor() or self.class_.abstract:
+ self.Add('template', namespaces.boost + 'noncopyable')
+
+
+ def ExportVariables(self):
+ 'Export the variables of the class, both static and simple variables'
+ vars = [x for x in self.public_members if isinstance(x, Variable)]
+ for var in vars:
+ if self.info[var.name].exclude:
+ continue
+ name = self.info[var.name].rename or var.name
+ fullname = var.FullName()
+ if var.type.const:
+ def_ = '.def_readonly'
+ else:
+ def_ = '.def_readwrite'
+ code = '%s("%s", &%s)' % (def_, name, fullname)
+ self.Add('inside', code)
+
+
+ def OverloadName(self, method):
+ 'Returns the name of the overloads struct for the given method'
+ name = makeid(method.FullName())
+ overloads = '_overloads_%i_%i' % (method.minArgs, method.maxArgs)
+ return name + overloads
+
+
+ def GetAddedMethods(self):
+ added_methods = self.info.__added__
+ result = []
+ if added_methods:
+ for name, rename in added_methods:
+ decl = self.GetDeclaration(name)
+ self.info[name].rename = rename
+ result.append(decl)
+ return result
+
+
+ def ExportMethods(self):
+ '''Export all the non-virtual methods of this class, plus any function
+ that is to be exported as a method'''
+
+ declared = {}
+ def DeclareOverloads(m):
+ 'Declares the macro for the generation of the overloads'
+ if (isinstance(m, Method) and m.static) or type(m) == Function:
+ func = m.FullName()
+ macro = 'BOOST_PYTHON_FUNCTION_OVERLOADS'
+ else:
+ func = m.name
+ macro = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS'
+ code = '%s(%s, %s, %i, %i)\n' % (macro, self.OverloadName(m), func, m.minArgs, m.maxArgs)
+ if code not in declared:
+ declared[code] = True
+ self.Add('declaration', code)
+
+
+ def Pointer(m):
+ 'returns the correct pointer declaration for the method m'
+ # check if this method has a wrapper set for him
+ wrapper = self.info[m.name].wrapper
+ if wrapper:
+ return '&' + wrapper.FullName()
+ else:
+ return m.PointerDeclaration()
+
+ def IsExportable(m):
+ 'Returns true if the given method is exportable by this routine'
+ ignore = (Constructor, ClassOperator, Destructor)
+ return isinstance(m, Function) and not isinstance(m, ignore) and not m.virtual
+
+ methods = [x for x in self.public_members if IsExportable(x)]
+ methods.extend(self.GetAddedMethods())
+
+ staticmethods = {}
+
+ for method in methods:
+ method_info = self.info[method.name]
+
+ # skip this method if it was excluded by the user
+ if method_info.exclude:
+ continue
+
+ # rename the method if the user requested
+ name = method_info.rename or method.name
+
+ # warn the user if this method needs a policy and doesn't have one
+ method_info.policy = exporterutils.HandlePolicy(method, method_info.policy)
+
+ # check for policies
+ policy = method_info.policy or ''
+ if policy:
+ policy = ', %s%s()' % (namespaces.python, policy.Code())
+ # check for overloads
+ overload = ''
+ if method.minArgs != method.maxArgs and not method_info.wrapper:
+ # add the overloads for this method
+ DeclareOverloads(method)
+ overload_name = self.OverloadName(method)
+ overload = ', %s%s()' % (namespaces.pyste, overload_name)
+
+ # build the .def string to export the method
+ pointer = Pointer(method)
+ code = '.def("%s", %s' % (name, pointer)
+ code += policy
+ code += overload
+ code += ')'
+ self.Add('inside', code)
+ # static method
+ if isinstance(method, Method) and method.static:
+ staticmethods[name] = 1
+ # add wrapper code if this method has one
+ wrapper = method_info.wrapper
+ if wrapper and wrapper.code:
+ self.Add('declaration', wrapper.code)
+
+ # export staticmethod statements
+ for name in staticmethods:
+ code = '.staticmethod("%s")' % name
+ self.Add('inside', code)
+
+
+
+ def MakeNonVirtual(self):
+ '''Make all methods that the user indicated to no_override no more virtual, delegating their
+ export to the ExportMethods routine'''
+ for member in self.class_:
+ if type(member) == Method and member.virtual:
+ member.virtual = not self.info[member.name].no_override
+
+
+ def ExportVirtualMethods(self, codeunit):
+ # check if this class has any virtual methods
+ has_virtual_methods = False
+ for member in self.class_:
+ if type(member) == Method and member.virtual:
+ has_virtual_methods = True
+ break
+
+ holder = self.info.holder
+ if has_virtual_methods:
+ generator = _VirtualWrapperGenerator(self.class_, self.ClassBases(), self.info, codeunit)
+ if holder:
+ self.Add('template', holder(generator.FullName()))
+ else:
+ self.Add('template', generator.FullName())
+ for definition in generator.GenerateDefinitions():
+ self.Add('inside', definition)
+ self.Add('declaration', generator.GenerateVirtualWrapper(self.INDENT))
+ else:
+ if holder:
+ self.Add('template', holder(self.class_.FullName()))
+
+ # operators natively supported by boost
+ BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -= '\
+ '*= /= %= ^= &= |= <<= >>='.split()
+ # create a map for faster lookup
+ BOOST_SUPPORTED_OPERATORS = dict(zip(BOOST_SUPPORTED_OPERATORS, range(len(BOOST_SUPPORTED_OPERATORS))))
+
+ # a dict of operators that are not directly supported by boost, but can be exposed
+ # simply as a function with a special name
+ BOOST_RENAME_OPERATORS = {
+ '()' : '__call__',
+ }
+
+ # converters which have a special name in python
+ # it's a map of a regular expression of the converter's result to the
+ # appropriate python name
+ SPECIAL_CONVERTERS = {
+ re.compile(r'(const)?\s*double$') : '__float__',
+ re.compile(r'(const)?\s*float$') : '__float__',
+ re.compile(r'(const)?\s*int$') : '__int__',
+ re.compile(r'(const)?\s*long$') : '__long__',
+ re.compile(r'(const)?\s*char\s*\*?$') : '__str__',
+ re.compile(r'(const)?.*::basic_string<.*>\s*(\*|\&)?$') : '__str__',
+ }
+
+
+ def ExportOperators(self):
+ 'Export all member operators and free operators related to this class'
+
+ def GetFreeOperators():
+ 'Get all the free (global) operators related to this class'
+ operators = []
+ for decl in self.declarations:
+ if isinstance(decl, Operator):
+ # check if one of the params is this class
+ for param in decl.parameters:
+ if param.name == self.class_.FullName():
+ operators.append(decl)
+ break
+ return operators
+
+ def GetOperand(param):
+ 'Returns the operand of this parameter (either "self", or "other<type>")'
+ if param.name == self.class_.FullName():
+ return namespaces.python + 'self'
+ else:
+ return namespaces.python + ('other< %s >()' % param.name)
+
+
+ def HandleSpecialOperator(operator):
+ # gatter information about the operator and its parameters
+ result_name = operator.result.name
+ param1_name = ''
+ if operator.parameters:
+ param1_name = operator.parameters[0].name
+
+ # check for str
+ ostream = 'basic_ostream'
+ is_str = result_name.find(ostream) != -1 and param1_name.find(ostream) != -1
+ if is_str:
+ namespace = namespaces.python + 'self_ns::'
+ self_ = namespaces.python + 'self'
+ return '.def(%sstr(%s))' % (namespace, self_)
+
+ # is not a special operator
+ return None
+
+
+
+ frees = GetFreeOperators()
+ members = [x for x in self.public_members if type(x) == ClassOperator]
+ all_operators = frees + members
+ operators = [x for x in all_operators if not self.info['operator'][x.name].exclude]
+
+ for operator in operators:
+ # gatter information about the operator, for use later
+ wrapper = self.info['operator'][operator.name].wrapper
+ if wrapper:
+ pointer = '&' + wrapper.FullName()
+ if wrapper.code:
+ self.Add('declaration-outside', wrapper.code)
+ else:
+ pointer = operator.PointerDeclaration()
+ rename = self.info['operator'][operator.name].rename
+
+ # check if this operator will be exported as a method
+ export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS
+
+ # check if this operator has a special representation in boost
+ special_code = HandleSpecialOperator(operator)
+ has_special_representation = special_code is not None
+
+ if export_as_method:
+ # export this operator as a normal method, renaming or using the given wrapper
+ if not rename:
+ if wrapper:
+ rename = wrapper.name
+ else:
+ rename = self.BOOST_RENAME_OPERATORS[operator.name]
+ policy = ''
+ policy_obj = self.info['operator'][operator.name].policy
+ if policy_obj:
+ policy = ', %s()' % policy_obj.Code()
+ self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy))
+
+ elif has_special_representation:
+ self.Add('inside', special_code)
+
+ elif operator.name in self.BOOST_SUPPORTED_OPERATORS:
+ # export this operator using boost's facilities
+ op = operator
+ is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\
+ isinstance(op, ClassOperator) and len(op.parameters) == 0
+ if is_unary:
+ self.Add('inside', '.def( %s%sself )' % \
+ (operator.name, namespaces.python))
+ else:
+ # binary operator
+ if len(operator.parameters) == 2:
+ left_operand = GetOperand(operator.parameters[0])
+ right_operand = GetOperand(operator.parameters[1])
+ else:
+ left_operand = namespaces.python + 'self'
+ right_operand = GetOperand(operator.parameters[0])
+ self.Add('inside', '.def( %s %s %s )' % \
+ (left_operand, operator.name, right_operand))
+
+ # export the converters.
+ # export them as simple functions with a pre-determined name
+
+ converters = [x for x in self.public_members if type(x) == ConverterOperator]
+
+ def ConverterMethodName(converter):
+ result_fullname = converter.result.FullName()
+ result_name = converter.result.name
+ for regex, method_name in self.SPECIAL_CONVERTERS.items():
+ if regex.match(result_fullname):
+ return method_name
+ else:
+ # extract the last name from the full name
+ result_name = makeid(result_name)
+ return 'to_' + result_name
+
+ for converter in converters:
+ info = self.info['operator'][converter.result.FullName()]
+ # check if this operator should be excluded
+ if info.exclude:
+ continue
+
+ special_code = HandleSpecialOperator(converter)
+ if info.rename or not special_code:
+ # export as method
+ name = info.rename or ConverterMethodName(converter)
+ pointer = converter.PointerDeclaration()
+ policy_code = ''
+ if info.policy:
+ policy_code = ', %s()' % info.policy.Code()
+ self.Add('inside', '.def("%s", %s%s)' % (name, pointer, policy_code))
+
+ elif special_code:
+ self.Add('inside', special_code)
+
+
+
+ def ExportNestedClasses(self, exported_names):
+ nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)]
+ for nested_class in nested_classes:
+ nested_info = self.info[nested_class.name]
+ nested_info.include = self.info.include
+ nested_info.name = nested_class.FullName()
+ exporter = self.__class__(nested_info)
+ exporter.SetDeclarations(self.declarations)
+ codeunit = SingleCodeUnit(None, None)
+ exporter.Export(codeunit, exported_names)
+ self.nested_codeunits.append(codeunit)
+
+
+ def ExportNestedEnums(self, exported_names):
+ nested_enums = [x for x in self.public_members if isinstance(x, ClassEnumeration)]
+ for enum in nested_enums:
+ enum_info = self.info[enum.name]
+ enum_info.include = self.info.include
+ enum_info.name = enum.FullName()
+ exporter = EnumExporter(enum_info)
+ exporter.SetDeclarations(self.declarations)
+ codeunit = SingleCodeUnit(None, None)
+ exporter.Export(codeunit, exported_names)
+ self.nested_codeunits.append(codeunit)
+
+
+ def ExportSmartPointer(self):
+ smart_ptr = self.info.smart_ptr
+ if smart_ptr:
+ class_name = self.class_.FullName()
+ smart_ptr = smart_ptr % class_name
+ self.Add('scope', '%sregister_ptr_to_python< %s >();' % (namespaces.python, smart_ptr))
+
+
+ def ExportOpaquePointerPolicies(self):
+ # check all methods for 'return_opaque_pointer' policies
+ methods = [x for x in self.public_members if isinstance(x, Method)]
+ for method in methods:
+ return_opaque_policy = return_value_policy(return_opaque_pointer)
+ if self.info[method.name].policy == return_opaque_policy:
+ macro = exporterutils.EspecializeTypeID(method.result.name)
+ if macro:
+ self.Add('declaration-outside', macro)
+
+ def ExportAddedCode(self):
+ if self.info.__code__:
+ for code in self.info.__code__:
+ self.Add('inside', code)
+
+
+#==============================================================================
+# Virtual Wrapper utils
+#==============================================================================
+
+def _ParamsInfo(m, count=None):
+ if count is None:
+ count = len(m.parameters)
+ param_names = ['p%i' % i for i in range(count)]
+ param_types = [x.FullName() for x in m.parameters[:count]]
+ params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)]
+ #for i, p in enumerate(m.parameters[:count]):
+ # if p.default is not None:
+ # #params[i] += '=%s' % p.default
+ # params[i] += '=%s' % (p.name + '()')
+ params = ', '.join(params)
+ return params, param_names, param_types
+
+
+class _VirtualWrapperGenerator(object):
+ 'Generates code to export the virtual methods of the given class'
+
+ def __init__(self, class_, bases, info, codeunit):
+ self.class_ = copy.deepcopy(class_)
+ self.bases = bases[:]
+ self.info = info
+ self.wrapper_name = makeid(class_.FullName()) + '_Wrapper'
+ self.virtual_methods = None
+ self._method_count = {}
+ self.codeunit = codeunit
+ self.GenerateVirtualMethods()
+
+
+ SELF = 'py_self'
+
+
+ def DefaultImplementationNames(self, method):
+ '''Returns a list of default implementations for this method, one for each
+ number of default arguments. Always returns at least one name, and return from
+ the one with most arguments to the one with the least.
+ '''
+ base_name = 'default_' + method.name
+ minArgs = method.minArgs
+ maxArgs = method.maxArgs
+ if minArgs == maxArgs:
+ return [base_name]
+ else:
+ return [base_name + ('_%i' % i) for i in range(minArgs, maxArgs+1)]
+
+
+ def Declaration(self, method, indent):
+ '''Returns a string with the declarations of the virtual wrapper and
+ its default implementations. This string must be put inside the Wrapper
+ body.
+ '''
+ pyste = namespaces.pyste
+ python = namespaces.python
+ rename = self.info[method.name].rename or method.name
+ result = method.result.FullName()
+ return_str = 'return '
+ if result == 'void':
+ return_str = ''
+ params, param_names, param_types = _ParamsInfo(method)
+ constantness = ''
+ if method.const:
+ constantness = ' const'
+
+ # call_method callback
+ decl = indent + '%s %s(%s)%s%s {\n' % (result, method.name, params, constantness, method.Exceptions())
+ param_names_str = ', '.join(param_names)
+ if param_names_str:
+ param_names_str = ', ' + param_names_str
+
+ self_str = self.SELF
+
+ decl += indent*2 + '%(return_str)s%(python)scall_method< %(result)s >' \
+ '(%(self_str)s, "%(rename)s"%(param_names_str)s);\n' % locals()
+ decl += indent + '}\n'
+
+ # default implementations (with overloading)
+ def DefaultImpl(method, param_names):
+ 'Return the body of a default implementation wrapper'
+ indent2 = indent * 2
+ wrapper = self.info[method.name].wrapper
+ if not wrapper:
+ # return the default implementation of the class
+ return indent2 + '%s%s(%s);\n' % \
+ (return_str, method.FullName(), ', '.join(param_names))
+ else:
+ if wrapper.code:
+ self.codeunit.Write('declaration-outside', wrapper.code)
+ # return a call for the wrapper
+ params = ', '.join(['this'] + param_names)
+ return indent2 + '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
+
+ if not method.abstract and method.visibility != Scope.private:
+ minArgs = method.minArgs
+ maxArgs = method.maxArgs
+ impl_names = self.DefaultImplementationNames(method)
+ for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)):
+ params, param_names, param_types = _ParamsInfo(method, argNum)
+ decl += '\n'
+ decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness)
+ decl += DefaultImpl(method, param_names)
+ decl += indent + '}\n'
+ return decl
+
+
+ def MethodDefinition(self, method):
+ '''Returns a list of lines, which should be put inside the class_
+ statement to export this method.'''
+ # dont define abstract methods
+ pyste = namespaces.pyste
+ rename = self.info[method.name].rename or method.name
+ default_names = self.DefaultImplementationNames(method)
+ class_name = self.class_.FullName()
+ wrapper_name = pyste + self.wrapper_name
+ result = method.result.FullName()
+ is_method_unique = method.is_unique
+ constantness = ''
+ if method.const:
+ constantness = ' const'
+
+ # create a list of default-impl pointers
+ minArgs = method.minArgs
+ maxArgs = method.maxArgs
+ if method.abstract:
+ default_pointers = []
+ elif is_method_unique:
+ default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names]
+ else:
+ default_pointers = []
+ for impl_name, argNum in zip(default_names, range(minArgs, maxArgs+1)):
+ param_list = [x.FullName() for x in method.parameters[:argNum]]
+ params = ', '.join(param_list)
+ signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness)
+ default_pointer = '(%s)&%s::%s' % (signature, wrapper_name, impl_name)
+ default_pointers.append(default_pointer)
+
+ # get the pointer of the method
+ pointer = method.PointerDeclaration()
+ if method.abstract:
+ pointer = namespaces.python + ('pure_virtual(%s)' % pointer)
+
+ # warn the user if this method needs a policy and doesn't have one
+ method_info = self.info[method.name]
+ method_info.policy = exporterutils.HandlePolicy(method, method_info.policy)
+
+ # Add policy to overloaded methods also
+ policy = method_info.policy or ''
+ if policy:
+ policy = ', %s%s()' % (namespaces.python, policy.Code())
+
+ # generate the defs
+ definitions = []
+ # basic def
+ if default_pointers:
+ definitions.append('.def("%s", %s, %s%s)' % (rename, pointer, default_pointers[-1], policy))
+ for default_pointer in default_pointers[:-1]:
+ definitions.append('.def("%s", %s%s)' % (rename, default_pointer, policy))
+ else:
+ definitions.append('.def("%s", %s%s)' % (rename, pointer, policy))
+ return definitions
+
+
+ def FullName(self):
+ return namespaces.pyste + self.wrapper_name
+
+
+ def GenerateVirtualMethods(self):
+ '''To correctly export all virtual methods, we must also make wrappers
+ for the virtual methods of the bases of this class, as if the methods
+ were from this class itself.
+ This method creates the instance variable self.virtual_methods.
+ '''
+ def IsVirtual(m):
+ if type(m) is Method:
+ pure_virtual = m.abstract and m.virtual
+ virtual = m.virtual and m.visibility != Scope.private
+ return virtual or pure_virtual
+ else:
+ return False
+
+ # extract the virtual methods, avoiding duplications. The duplication
+ # must take in account the full signature without the class name, so
+ # that inherited members are correctly excluded if the subclass overrides
+ # them.
+ def MethodSig(method):
+ if method.const:
+ const = ' const'
+ else:
+ const = ''
+ if method.result:
+ result = method.result.FullName()
+ else:
+ result = ''
+ params = ', '.join([x.FullName() for x in method.parameters])
+ return '%s %s(%s)%s%s' % (
+ result, method.name, params, const, method.Exceptions())
+
+ already_added = {}
+ self.virtual_methods = []
+ for member in self.class_:
+ if IsVirtual(member):
+ already_added[MethodSig(member)] = None
+ self.virtual_methods.append(member)
+
+ for base in self.bases:
+ base_methods = [copy.deepcopy(x) for x in base if IsVirtual(x)]
+ for base_method in base_methods:
+ self.class_.AddMember(base_method)
+
+ all_methods = [x for x in self.class_ if IsVirtual(x)]
+
+ for member in all_methods:
+ sig = MethodSig(member)
+ if IsVirtual(member) and not sig in already_added:
+ self.virtual_methods.append(member)
+ already_added[sig] = 0
+
+
+ def Constructors(self):
+ return self.class_.Constructors(publics_only=True)
+
+
+ def GenerateDefinitions(self):
+ defs = []
+ for method in self.virtual_methods:
+ exclude = self.info[method.name].exclude
+ # generate definitions only for public methods and non-abstract methods
+ if method.visibility == Scope.public and not exclude:
+ defs.extend(self.MethodDefinition(method))
+ return defs
+
+
+ def GenerateVirtualWrapper(self, indent):
+ 'Return the wrapper for this class'
+
+ # generate the class code
+ class_name = self.class_.FullName()
+ code = 'struct %s: %s\n' % (self.wrapper_name, class_name)
+ code += '{\n'
+ # generate constructors (with the overloads for each one)
+ for cons in self.Constructors(): # only public constructors
+ minArgs = cons.minArgs
+ maxArgs = cons.maxArgs
+ # from the min number of arguments to the max number, generate
+ # all version of the given constructor
+ cons_code = ''
+ for argNum in range(minArgs, maxArgs+1):
+ params, param_names, param_types = _ParamsInfo(cons, argNum)
+ if params:
+ params = ', ' + params
+ cons_code += indent + '%s(PyObject* %s_%s):\n' % \
+ (self.wrapper_name, self.SELF, params)
+ cons_code += indent*2 + '%s(%s), %s(%s_) {}\n\n' % \
+ (class_name, ', '.join(param_names), self.SELF, self.SELF)
+ code += cons_code
+ # generate the body
+ body = []
+ for method in self.virtual_methods:
+ if not self.info[method.name].exclude:
+ body.append(self.Declaration(method, indent))
+ body = '\n'.join(body)
+ code += body + '\n'
+ # add the self member
+ code += indent + 'PyObject* %s;\n' % self.SELF
+ code += '};\n'
+ return code
diff --git a/libs/python/pyste/src/Pyste/CodeExporter.py b/libs/python/pyste/src/Pyste/CodeExporter.py
new file mode 100644
index 000000000..382fffbd5
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/CodeExporter.py
@@ -0,0 +1,26 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from Exporter import Exporter
+
+#==============================================================================
+# CodeExporter
+#==============================================================================
+class CodeExporter(Exporter):
+
+ def __init__(self, info):
+ Exporter.__init__(self, info)
+
+
+ def Name(self):
+ return self.info.code
+
+
+ def Export(self, codeunit, exported_names):
+ codeunit.Write(self.info.section, self.info.code)
+
+
+ def WriteInclude(self, codeunit):
+ pass
diff --git a/libs/python/pyste/src/Pyste/CppParser.py b/libs/python/pyste/src/Pyste/CppParser.py
new file mode 100644
index 000000000..be68a448a
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/CppParser.py
@@ -0,0 +1,247 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from GCCXMLParser import ParseDeclarations
+import tempfile
+import shutil
+import os
+import sys
+import os.path
+import settings
+import shutil
+import shelve
+from cPickle import dump, load
+
+#==============================================================================
+# exceptions
+#==============================================================================
+class CppParserError(Exception): pass
+
+#==============================================================================
+# CppParser
+#==============================================================================
+class CppParser:
+ 'Parses a header file and returns a list of declarations'
+
+ def __init__(self, includes=None, defines=None, cache_dir=None, version=None, gccxml_path = 'gccxml'):
+ 'includes and defines ar the directives given to gcc'
+ if includes is None:
+ includes = []
+ if defines is None:
+ defines = []
+ self.includes = includes
+ self.gccxml_path = gccxml_path
+ self.defines = defines
+ self.version = version
+ #if cache_dir is None:
+ # cache_dir = tempfile.mktemp()
+ # self.delete_cache = True
+ #else:
+ # self.delete_cache = False
+ self.delete_cache = False
+ self.cache_dir = cache_dir
+ self.cache_files = []
+ self.mem_cache = {}
+ # create the cache dir
+ if cache_dir:
+ try:
+ os.makedirs(cache_dir)
+ except OSError: pass
+
+
+ def __del__(self):
+ self.Close()
+
+
+ def _IncludeParams(self, filename):
+ includes = self.includes[:]
+ filedir = os.path.dirname(filename)
+ if not filedir:
+ filedir = '.'
+ includes.insert(0, filedir)
+ includes = ['-I "%s"' % self.Unixfy(x) for x in includes]
+ return ' '.join(includes)
+
+
+ def _DefineParams(self):
+ defines = ['-D "%s"' % x for x in self.defines]
+ return ' '.join(defines)
+
+
+ def FindHeader(self, header):
+ if os.path.isfile(header):
+ return header
+ for path in self.includes:
+ filename = os.path.join(path, header)
+ if os.path.isfile(filename):
+ return filename
+ else:
+ name = os.path.basename(header)
+ raise RuntimeError, 'Header file "%s" not found!' % name
+
+
+ def AppendTail(self, filename, tail):
+ '''Creates a temporary file, appends the text tail to it, and returns
+ the filename of the file.
+ '''
+ if hasattr(tempfile, 'mkstemp'):
+ f_no, temp = tempfile.mkstemp('.h')
+ f = file(temp, 'a')
+ os.close(f_no)
+ else:
+ temp = tempfile.mktemp('.h')
+ f = file(temp, 'a')
+ f.write('#include "%s"\n\n' % os.path.abspath(filename))
+ f.write(tail)
+ f.write('\n')
+ f.close()
+ return temp
+
+
+ def Unixfy(self, path):
+ return path.replace('\\', '/')
+
+
+ def ParseWithGCCXML(self, header, tail):
+ '''Parses the given header using gccxml and GCCXMLParser.
+ '''
+ header = self.FindHeader(header)
+ if tail:
+ filename = self.AppendTail(header, tail)
+ else:
+ filename = header
+ xmlfile = tempfile.mktemp('.xml')
+ try:
+ # get the params
+ includes = self._IncludeParams(filename)
+ defines = self._DefineParams()
+ # call gccxml
+ cmd = '%s %s %s "%s" -fxml=%s'
+ filename = self.Unixfy(filename)
+ xmlfile = self.Unixfy(xmlfile)
+ status = os.system(cmd % (self.gccxml_path, includes, defines, filename, xmlfile))
+ if status != 0 or not os.path.isfile(xmlfile):
+ raise CppParserError, 'Error executing gccxml'
+ # parse the resulting xml
+ declarations = ParseDeclarations(xmlfile)
+ # make the declarations' location to point to the original file
+ if tail:
+ for decl in declarations:
+ decl_filename = os.path.normpath(os.path.normcase(decl.location[0]))
+ filename = os.path.normpath(os.path.normcase(filename))
+ if decl_filename == filename:
+ decl.location = header, decl.location[1]
+ # return the declarations
+ return declarations
+ finally:
+ if settings.DEBUG and os.path.isfile(xmlfile):
+ debugname = os.path.basename(header)
+ debugname = os.path.splitext(debugname)[0] + '.xml'
+ print 'DEBUG:', debugname
+ shutil.copy(xmlfile, debugname)
+ # delete the temporary files
+ try:
+ os.remove(xmlfile)
+ if tail:
+ os.remove(filename)
+ except OSError: pass
+
+
+ def Parse(self, header, interface, tail=None):
+ '''Parses the given filename related to the given interface and returns
+ the (declarations, headerfile). The header returned is normally the
+ same as the given to this method (except that it is the full path),
+ except if tail is not None: in this case, the header is copied to a temp
+ filename and the tail code is appended to it before being passed on to
+ gccxml. This temp filename is then returned.
+ '''
+ if tail is None:
+ tail = ''
+ tail = tail.strip()
+ declarations = self.GetCache(header, interface, tail)
+ if declarations is None:
+ declarations = self.ParseWithGCCXML(header, tail)
+ self.CreateCache(header, interface, tail, declarations)
+ header_fullpath = os.path.abspath(self.FindHeader(header))
+ return declarations, header_fullpath
+
+
+ def CacheFileName(self, interface):
+ interface_name = os.path.basename(interface)
+ cache_file = os.path.splitext(interface_name)[0] + '.pystec'
+ cache_file = os.path.join(self.cache_dir, cache_file)
+ return cache_file
+
+
+ def GetCache(self, header, interface, tail):
+ key = (header, interface, tail)
+ # try memory cache first
+ if key in self.mem_cache:
+ return self.mem_cache[key]
+
+ # get the cache from the disk
+ if self.cache_dir is None:
+ return None
+ header = self.FindHeader(header)
+ cache_file = self.CacheFileName(interface)
+ if os.path.isfile(cache_file):
+ f = file(cache_file, 'rb')
+ try:
+ version = load(f)
+ if version != self.version:
+ return None
+ cache = load(f)
+ if cache.has_key(key):
+ self.cache_files.append(cache_file)
+ return cache[key]
+ else:
+ return None
+ finally:
+ f.close()
+ else:
+ return None
+
+
+ def CreateCache(self, header, interface, tail, declarations):
+ key = (header, interface, tail)
+
+ # our memory cache only holds one item
+ self.mem_cache.clear()
+ self.mem_cache[key] = declarations
+
+ # save the cache in the disk
+ if self.cache_dir is None:
+ return
+ header = self.FindHeader(header)
+ cache_file = self.CacheFileName(interface)
+ if os.path.isfile(cache_file):
+ f = file(cache_file, 'rb')
+ try:
+ version = load(f)
+ cache = load(f)
+ finally:
+ f.close()
+ else:
+ cache = {}
+ cache[key] = declarations
+ self.cache_files.append(cache_file)
+ f = file(cache_file, 'wb')
+ try:
+ dump(self.version, f, 1)
+ dump(cache, f, 1)
+ finally:
+ f.close()
+ return cache_file
+
+
+ def Close(self):
+ if self.delete_cache and self.cache_files:
+ for filename in self.cache_files:
+ try:
+ os.remove(filename)
+ except OSError:
+ pass
+ self.cache_files = []
+ shutil.rmtree(self.cache_dir)
diff --git a/libs/python/pyste/src/Pyste/EnumExporter.py b/libs/python/pyste/src/Pyste/EnumExporter.py
new file mode 100644
index 000000000..0107fbee3
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/EnumExporter.py
@@ -0,0 +1,58 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from Exporter import Exporter
+from settings import *
+import utils
+
+#==============================================================================
+# EnumExporter
+#==============================================================================
+class EnumExporter(Exporter):
+ 'Exports enumerators'
+
+ def __init__(self, info):
+ Exporter.__init__(self, info)
+
+
+ def SetDeclarations(self, declarations):
+ Exporter.SetDeclarations(self, declarations)
+ if self.declarations:
+ self.enum = self.GetDeclaration(self.info.name)
+ else:
+ self.enum = None
+
+ def Export(self, codeunit, exported_names):
+ if self.info.exclude:
+ return
+ indent = self.INDENT
+ in_indent = self.INDENT*2
+ rename = self.info.rename or self.enum.name
+ full_name = self.enum.FullName()
+ unnamed_enum = False
+ if rename.startswith('$_') or rename.startswith('._'):
+ unnamed_enum = True
+ code = ''
+ if not unnamed_enum:
+ code += indent + namespaces.python
+ code += 'enum_< %s >("%s")\n' % (full_name, rename)
+ for name in self.enum.values:
+ rename = self.info[name].rename or name
+ value_fullname = self.enum.ValueFullName(name)
+ if not unnamed_enum:
+ code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname)
+ else:
+ code += indent + namespaces.python
+ code += 'scope().attr("%s") = (int)%s;\n' % (rename, value_fullname )
+ if self.info.export_values and not unnamed_enum:
+ code += in_indent + '.export_values()\n'
+ if not unnamed_enum:
+ code += indent + ';\n'
+ code += '\n'
+ codeunit.Write('module', code)
+ exported_names[self.enum.FullName()] = 1
+
+ def Name(self):
+ return self.info.name
diff --git a/libs/python/pyste/src/Pyste/Exporter.py b/libs/python/pyste/src/Pyste/Exporter.py
new file mode 100644
index 000000000..d87b37c58
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/Exporter.py
@@ -0,0 +1,94 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import os.path
+
+#==============================================================================
+# Exporter
+#==============================================================================
+class Exporter(object):
+ 'Base class for objects capable to generate boost.python code.'
+
+ INDENT = ' ' * 4
+
+ def __init__(self, info, parser_tail=None):
+ self.info = info
+ self.parser_tail = parser_tail
+ self.interface_file = None
+ self.declarations = []
+
+
+ def Name(self):
+ raise NotImplementedError(self.__class__.__name__)
+
+
+ def Tail(self):
+ return self.parser_tail
+
+
+ def Parse(self, parser):
+ self.parser = parser
+ header = self.info.include
+ tail = self.parser_tail
+ declarations, parser_header = parser.parse(header, tail)
+ self.parser_header = parser_header
+ self.SetDeclarations(declarations)
+
+
+ def SetParsedHeader(self, parsed_header):
+ self.parser_header = parsed_header
+
+
+ def SetDeclarations(self, declarations):
+ self.declarations = declarations
+
+
+ def GenerateCode(self, codeunit, exported_names):
+ self.WriteInclude(codeunit)
+ self.Export(codeunit, exported_names)
+
+
+ def WriteInclude(self, codeunit):
+ codeunit.Write('include', '#include <%s>\n' % self.info.include)
+
+
+ def Export(self, codeunit, exported_names):
+ 'subclasses must override this to do the real work'
+ pass
+
+
+ def GetDeclarations(self, fullname):
+ decls = []
+ for decl in self.declarations:
+ if decl.FullName() == fullname:
+ decls.append(decl)
+ if not decls:
+ raise RuntimeError, 'no %s declaration found!' % fullname
+ return decls
+
+
+ def GetDeclaration(self, fullname):
+ decls = self.GetDeclarations(fullname)
+ #assert len(decls) == 1
+ return decls[0]
+
+
+ def Order(self):
+ '''Returns a string that uniquely identifies this instance. All
+ exporters will be sorted by Order before being exported.
+ '''
+ return 0, self.info.name
+
+
+ def Header(self):
+ return self.info.include
+
+
+ def __eq__(self, other):
+ return type(self) is type(other) and self.Name() == other.Name() \
+ and self.interface_file == other.interface_file
+
+ def __ne__(self, other):
+ return not self == other
diff --git a/libs/python/pyste/src/Pyste/FunctionExporter.py b/libs/python/pyste/src/Pyste/FunctionExporter.py
new file mode 100644
index 000000000..5765f65e9
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/FunctionExporter.py
@@ -0,0 +1,92 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from Exporter import Exporter
+from policies import *
+from declarations import *
+from settings import *
+import utils
+import exporterutils
+
+
+#==============================================================================
+# FunctionExporter
+#==============================================================================
+class FunctionExporter(Exporter):
+ 'Generates boost.python code to export the given function.'
+
+ def __init__(self, info, tail=None):
+ Exporter.__init__(self, info, tail)
+
+
+ def Export(self, codeunit, exported_names):
+ if not self.info.exclude:
+ decls = self.GetDeclarations(self.info.name)
+ for decl in decls:
+ self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy)
+ self.ExportDeclaration(decl, len(decls) == 1, codeunit)
+ self.ExportOpaquePointer(decl, codeunit)
+ self.GenerateOverloads(decls, codeunit)
+ exported_names[self.Name()] = 1
+
+
+ def ExportDeclaration(self, decl, unique, codeunit):
+ name = self.info.rename or decl.name
+ defs = namespaces.python + 'def("%s", ' % name
+ wrapper = self.info.wrapper
+ if wrapper:
+ pointer = '&' + wrapper.FullName()
+ else:
+ pointer = decl.PointerDeclaration()
+ defs += pointer
+ defs += self.PolicyCode()
+ overload = self.OverloadName(decl)
+ if overload:
+ defs += ', %s()' % (namespaces.pyste + overload)
+ defs += ');'
+ codeunit.Write('module', self.INDENT + defs + '\n')
+ # add the code of the wrapper
+ if wrapper and wrapper.code:
+ codeunit.Write('declaration', wrapper.code + '\n')
+
+
+ def OverloadName(self, decl):
+ if decl.minArgs != decl.maxArgs:
+ return '%s_overloads_%i_%i' % \
+ (decl.name, decl.minArgs, decl.maxArgs)
+ else:
+ return ''
+
+
+ def GenerateOverloads(self, declarations, codeunit):
+ codes = {}
+ for decl in declarations:
+ overload = self.OverloadName(decl)
+ if overload and overload not in codes:
+ code = 'BOOST_PYTHON_FUNCTION_OVERLOADS(%s, %s, %i, %i)' %\
+ (overload, decl.FullName(), decl.minArgs, decl.maxArgs)
+ codeunit.Write('declaration', code + '\n')
+ codes[overload] = None
+
+
+ def PolicyCode(self):
+ policy = self.info.policy
+ if policy is not None:
+ assert isinstance(policy, Policy)
+ return ', %s()' % policy.Code()
+ else:
+ return ''
+
+
+ def ExportOpaquePointer(self, function, codeunit):
+ if self.info.policy == return_value_policy(return_opaque_pointer):
+ typename = function.result.name
+ macro = exporterutils.EspecializeTypeID(typename)
+ if macro:
+ codeunit.Write('declaration-outside', macro)
+
+
+ def Name(self):
+ return self.info.name
diff --git a/libs/python/pyste/src/Pyste/GCCXMLParser.py b/libs/python/pyste/src/Pyste/GCCXMLParser.py
new file mode 100644
index 000000000..4a1017204
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/GCCXMLParser.py
@@ -0,0 +1,478 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from declarations import *
+try:
+ # try to use internal elementtree
+ from xml.etree.cElementTree import ElementTree
+except ImportError:
+ # try to use cElementTree if avaiable
+ try:
+ from cElementTree import ElementTree
+ except ImportError:
+ # fall back to the normal elementtree
+ from elementtree.ElementTree import ElementTree
+from xml.parsers.expat import ExpatError
+from copy import deepcopy
+from utils import enumerate
+
+
+#==============================================================================
+# Exceptions
+#==============================================================================
+class InvalidXMLError(Exception): pass
+
+class ParserError(Exception): pass
+
+class InvalidContextError(ParserError): pass
+
+
+#==============================================================================
+# GCCXMLParser
+#==============================================================================
+class GCCXMLParser(object):
+ 'Parse a GCC_XML file and extract the top-level declarations.'
+
+ interested_tags = {'Class':0, 'Function':0, 'Variable':0, 'Enumeration':0}
+
+ def Parse(self, filename):
+ self.elements = self.GetElementsFromXML(filename)
+ # high level declarations
+ self.declarations = []
+ self._names = {}
+ # parse the elements
+ for id in self.elements:
+ element, decl = self.elements[id]
+ if decl is None:
+ try:
+ self.ParseElement(id, element)
+ except InvalidContextError:
+ pass # ignore those nodes with invalid context
+ # (workaround gccxml bug)
+
+
+ def Declarations(self):
+ return self.declarations
+
+
+ def AddDecl(self, decl):
+ if decl.FullName() in self._names:
+ decl.is_unique= False
+ for d in self.declarations:
+ if d.FullName() == decl.FullName():
+ d.is_unique = False
+ self._names[decl.FullName()] = 0
+ self.declarations.append(decl)
+
+
+ def ParseElement(self, id, element):
+ method = 'Parse' + element.tag
+ if hasattr(self, method):
+ func = getattr(self, method)
+ func(id, element)
+ else:
+ self.ParseUnknown(id, element)
+
+
+ def GetElementsFromXML(self,filename):
+ 'Extracts a dictionary of elements from the gcc_xml file.'
+
+ tree = ElementTree()
+ try:
+ tree.parse(filename)
+ except ExpatError:
+ raise InvalidXMLError, 'Not a XML file: %s' % filename
+
+ root = tree.getroot()
+ if root.tag != 'GCC_XML':
+ raise InvalidXMLError, 'Not a valid GCC_XML file'
+
+ # build a dictionary of id -> element, None
+ elementlist = root.getchildren()
+ elements = {}
+ for element in elementlist:
+ id = element.get('id')
+ if id:
+ elements[id] = element, None
+ return elements
+
+
+ def GetDecl(self, id):
+ if id not in self.elements:
+ if id == '_0':
+ raise InvalidContextError, 'Invalid context found in the xml file.'
+ else:
+ msg = 'ID not found in elements: %s' % id
+ raise ParserError, msg
+
+ elem, decl = self.elements[id]
+ if decl is None:
+ self.ParseElement(id, elem)
+ elem, decl = self.elements[id]
+ if decl is None:
+ raise ParserError, 'Could not parse element: %s' % elem.tag
+ return decl
+
+
+ def GetType(self, id):
+ def Check(id, feature):
+ pos = id.find(feature)
+ if pos != -1:
+ id = id[:pos] + id[pos+1:]
+ return True, id
+ else:
+ return False, id
+ const, id = Check(id, 'c')
+ volatile, id = Check(id, 'v')
+ restricted, id = Check(id, 'r')
+ decl = self.GetDecl(id)
+ if isinstance(decl, Type):
+ res = deepcopy(decl)
+ if const:
+ res.const = const
+ if volatile:
+ res.volatile = volatile
+ if restricted:
+ res.restricted = restricted
+ else:
+ res = Type(decl.FullName(), const)
+ res.volatile = volatile
+ res.restricted = restricted
+ return res
+
+
+ def GetLocation(self, location):
+ file, line = location.split(':')
+ file = self.GetDecl(file)
+ return file, int(line)
+
+
+ def Update(self, id, decl):
+ element, _ = self.elements[id]
+ self.elements[id] = element, decl
+
+
+ def ParseUnknown(self, id, element):
+ name = '__Unknown_Element_%s' % id
+ decl = Unknown(name)
+ self.Update(id, decl)
+
+
+ def ParseNamespace(self, id, element):
+ namespace = element.get('name')
+ context = element.get('context')
+ if context:
+ outer = self.GetDecl(context)
+ if not outer.endswith('::'):
+ outer += '::'
+ namespace = outer + namespace
+ if namespace.startswith('::'):
+ namespace = namespace[2:]
+ self.Update(id, namespace)
+
+
+ def ParseFile(self, id, element):
+ filename = element.get('name')
+ self.Update(id, filename)
+
+
+ def ParseVariable(self, id, element):
+ # in gcc_xml, a static Field is declared as a Variable, so we check
+ # this and call the Field parser.
+ context = self.GetDecl(element.get('context'))
+ if isinstance(context, Class):
+ self.ParseField(id, element)
+ elem, decl = self.elements[id]
+ decl.static = True
+ else:
+ namespace = context
+ name = element.get('name')
+ type_ = self.GetType(element.get('type'))
+ location = self.GetLocation(element.get('location'))
+ variable = Variable(type_, name, namespace)
+ variable.location = location
+ self.AddDecl(variable)
+ self.Update(id, variable)
+
+
+ def GetArguments(self, element):
+ args = []
+ for child in element:
+ if child.tag == 'Argument':
+ type = self.GetType(child.get('type'))
+ type.default = child.get('default')
+ args.append(type)
+ return args
+
+
+ def GetExceptions(self, exception_list):
+ if exception_list is None:
+ return None
+
+ exceptions = []
+ for t in exception_list.split():
+ exceptions.append(self.GetType(t))
+
+ return exceptions
+
+
+ def ParseFunction(self, id, element, functionType=Function):
+ '''functionType is used because a Operator is identical to a normal
+ function, only the type of the function changes.'''
+ name = element.get('name')
+ returns = self.GetType(element.get('returns'))
+ namespace = self.GetDecl(element.get('context'))
+ location = self.GetLocation(element.get('location'))
+ params = self.GetArguments(element)
+ incomplete = bool(int(element.get('incomplete', 0)))
+ throws = self.GetExceptions(element.get('throw', None))
+ function = functionType(name, namespace, returns, params, throws)
+ function.location = location
+ self.AddDecl(function)
+ self.Update(id, function)
+
+
+ def ParseOperatorFunction(self, id, element):
+ self.ParseFunction(id, element, Operator)
+
+
+ def GetHierarchy(self, bases):
+ '''Parses the string "bases" from the xml into a list of tuples of Base
+ instances. The first tuple is the most direct inheritance, and then it
+ goes up in the hierarchy.
+ '''
+
+ if bases is None:
+ return []
+ base_names = bases.split()
+ this_level = []
+ next_levels = []
+ for base in base_names:
+ # get the visibility
+ split = base.split(':')
+ if len(split) == 2:
+ visib = split[0]
+ base = split[1]
+ else:
+ visib = Scope.public
+ decl = self.GetDecl(base)
+ if not isinstance(decl, Class):
+ # on windows, there are some classes which "bases" points to an
+ # "Unimplemented" tag, but we are not interested in this classes
+ # anyway
+ continue
+ base = Base(decl.FullName(), visib)
+ this_level.append(base)
+ # normalize with the other levels
+ for index, level in enumerate(decl.hierarchy):
+ if index < len(next_levels):
+ next_levels[index] = next_levels[index] + level
+ else:
+ next_levels.append(level)
+ hierarchy = []
+ if this_level:
+ hierarchy.append(tuple(this_level))
+ if next_levels:
+ hierarchy.extend(next_levels)
+ return hierarchy
+
+
+ def GetMembers(self, member_list):
+ # members must be a string with the ids of the members
+ if member_list is None:
+ return []
+ members = []
+ for member in member_list.split():
+ decl = self.GetDecl(member)
+ if type(decl) in Class.ValidMemberTypes():
+ members.append(decl)
+ return members
+
+
+ def ParseClass(self, id, element):
+ name = element.get('name')
+ abstract = bool(int(element.get('abstract', '0')))
+ location = self.GetLocation(element.get('location'))
+ context = self.GetDecl(element.get('context'))
+ incomplete = bool(int(element.get('incomplete', 0)))
+ if isinstance(context, str):
+ class_ = Class(name, context, [], abstract)
+ else:
+ # a nested class
+ visib = element.get('access', Scope.public)
+ class_ = NestedClass(
+ name, context.FullName(), visib, [], abstract)
+ class_.incomplete = incomplete
+ # we have to add the declaration of the class before trying
+ # to parse its members and bases, to avoid recursion.
+ self.AddDecl(class_)
+ class_.location = location
+ self.Update(id, class_)
+ # now we can get the members and the bases
+ class_.hierarchy = self.GetHierarchy(element.get('bases'))
+ if class_.hierarchy:
+ class_.bases = class_.hierarchy[0]
+ members = self.GetMembers(element.get('members'))
+ for member in members:
+ class_.AddMember(member)
+
+
+ def ParseStruct(self, id, element):
+ self.ParseClass(id, element)
+
+
+ FUNDAMENTAL_RENAME = {
+ 'long long int' : 'boost::int64_t',
+ 'long long unsigned int' : 'boost::uint64_t',
+ }
+
+ def ParseFundamentalType(self, id, element):
+ name = element.get('name')
+ name = self.FUNDAMENTAL_RENAME.get(name, name)
+ type_ = FundamentalType(name)
+ self.Update(id, type_)
+
+
+ def ParseArrayType(self, id, element):
+ type = self.GetType(element.get('type'))
+ min = element.get('min')
+ max = element.get('max')
+ array = ArrayType(type.name, type.const, min, max)
+ self.Update(id, array)
+
+
+ def ParseReferenceType(self, id, element):
+ type = self.GetType(element.get('type'))
+ expand = not isinstance(type, FunctionType)
+ ref = ReferenceType(type.name, type.const, None, expand, type.suffix)
+ self.Update(id, ref)
+
+
+ def ParsePointerType(self, id, element):
+ type = self.GetType(element.get('type'))
+ expand = not isinstance(type, FunctionType)
+ ref = PointerType(type.name, type.const, None, expand, type.suffix)
+ self.Update(id, ref)
+
+
+ def ParseFunctionType(self, id, element):
+ result = self.GetType(element.get('returns'))
+ args = self.GetArguments(element)
+ func = FunctionType(result, args)
+ self.Update(id, func)
+
+
+ def ParseMethodType(self, id, element):
+ class_ = self.GetDecl(element.get('basetype')).FullName()
+ result = self.GetType(element.get('returns'))
+ args = self.GetArguments(element)
+ method = MethodType(result, args, class_)
+ self.Update(id, method)
+
+
+ def ParseField(self, id, element):
+ name = element.get('name')
+ visib = element.get('access', Scope.public)
+ classname = self.GetDecl(element.get('context')).FullName()
+ type_ = self.GetType(element.get('type'))
+ static = bool(int(element.get('extern', '0')))
+ location = self.GetLocation(element.get('location'))
+ var = ClassVariable(type_, name, classname, visib, static)
+ var.location = location
+ self.Update(id, var)
+
+
+ def ParseMethod(self, id, element, methodType=Method):
+ name = element.get('name')
+ result = self.GetType(element.get('returns'))
+ classname = self.GetDecl(element.get('context')).FullName()
+ visib = element.get('access', Scope.public)
+ static = bool(int(element.get('static', '0')))
+ virtual = bool(int(element.get('virtual', '0')))
+ abstract = bool(int(element.get('pure_virtual', '0')))
+ const = bool(int(element.get('const', '0')))
+ location = self.GetLocation(element.get('location'))
+ throws = self.GetExceptions(element.get('throw', None))
+ params = self.GetArguments(element)
+ method = methodType(
+ name, classname, result, params, visib, virtual, abstract, static, const, throws)
+ method.location = location
+ self.Update(id, method)
+
+
+ def ParseOperatorMethod(self, id, element):
+ self.ParseMethod(id, element, ClassOperator)
+
+
+ def ParseConstructor(self, id, element):
+ name = element.get('name')
+ visib = element.get('access', Scope.public)
+ classname = self.GetDecl(element.get('context')).FullName()
+ location = self.GetLocation(element.get('location'))
+ params = self.GetArguments(element)
+ artificial = element.get('artificial', False)
+ ctor = Constructor(name, classname, params, visib)
+ ctor.location = location
+ self.Update(id, ctor)
+
+
+ def ParseDestructor(self, id, element):
+ name = element.get('name')
+ visib = element.get('access', Scope.public)
+ classname = self.GetDecl(element.get('context')).FullName()
+ virtual = bool(int(element.get('virtual', '0')))
+ location = self.GetLocation(element.get('location'))
+ des = Destructor(name, classname, visib, virtual)
+ des.location = location
+ self.Update(id, des)
+
+
+ def ParseConverter(self, id, element):
+ self.ParseMethod(id, element, ConverterOperator)
+
+
+ def ParseTypedef(self, id, element):
+ name = element.get('name')
+ type = self.GetType(element.get('type'))
+ context = self.GetDecl(element.get('context'))
+ if isinstance(context, Class):
+ context = context.FullName()
+ typedef = Typedef(type, name, context)
+ self.Update(id, typedef)
+ self.AddDecl(typedef)
+
+
+ def ParseEnumeration(self, id, element):
+ name = element.get('name')
+ location = self.GetLocation(element.get('location'))
+ context = self.GetDecl(element.get('context'))
+ incomplete = bool(int(element.get('incomplete', 0)))
+ if isinstance(context, str):
+ enum = Enumeration(name, context)
+ else:
+ visib = element.get('access', Scope.public)
+ enum = ClassEnumeration(name, context.FullName(), visib)
+ self.AddDecl(enum)
+ enum.location = location
+ for child in element:
+ if child.tag == 'EnumValue':
+ name = child.get('name')
+ value = int(child.get('init'))
+ enum.values[name] = value
+ enum.incomplete = incomplete
+ self.Update(id, enum)
+
+
+
+def ParseDeclarations(filename):
+ 'Returns a list of the top declarations found in the gcc_xml file.'
+
+ parser = GCCXMLParser()
+ parser.Parse(filename)
+ return parser.Declarations()
+
+
+if __name__ == '__main__':
+ ParseDeclarations(r'D:\Programming\Libraries\boost-cvs\boost\libs\python\pyste\example\test.xml')
diff --git a/libs/python/pyste/src/Pyste/HeaderExporter.py b/libs/python/pyste/src/Pyste/HeaderExporter.py
new file mode 100644
index 000000000..47651ba70
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/HeaderExporter.py
@@ -0,0 +1,81 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from Exporter import Exporter
+from ClassExporter import ClassExporter
+from FunctionExporter import FunctionExporter
+from EnumExporter import EnumExporter
+from VarExporter import VarExporter
+from infos import *
+from declarations import *
+import os.path
+import exporters
+import MultipleCodeUnit
+
+#==============================================================================
+# HeaderExporter
+#==============================================================================
+class HeaderExporter(Exporter):
+ 'Exports all declarations found in the given header'
+
+ def __init__(self, info, parser_tail=None):
+ Exporter.__init__(self, info, parser_tail)
+
+
+ def WriteInclude(self, codeunit):
+ pass
+
+
+ def IsInternalName(self, name):
+ '''Returns true if the given name looks like a internal compiler
+ structure'''
+ return name.startswith('_')
+
+
+ def Export(self, codeunit, exported_names):
+ header = os.path.normpath(self.parser_header)
+ for decl in self.declarations:
+ # check if this declaration is in the header
+ location = os.path.abspath(decl.location[0])
+ if location == header and not self.IsInternalName(decl.name):
+ # ok, check the type of the declaration and export it accordingly
+ self.HandleDeclaration(decl, codeunit, exported_names)
+
+
+ def HandleDeclaration(self, decl, codeunit, exported_names):
+ '''Dispatch the declaration to the appropriate method, that must create
+ a suitable info object for a Exporter, create a Exporter, set its
+ declarations and append it to the list of exporters.
+ '''
+ dispatch_table = {
+ Class : ClassExporter,
+ Enumeration : EnumExporter,
+ Function : FunctionExporter,
+ Variable : VarExporter,
+ }
+
+ exporter_class = dispatch_table.get(type(decl))
+ if exporter_class is not None:
+ self.HandleExporter(decl, exporter_class, codeunit, exported_names)
+
+
+ def HandleExporter(self, decl, exporter_type, codeunit, exported_names):
+ # only export complete declarations
+ if not decl.incomplete:
+ info = self.info[decl.name]
+ info.name = decl.FullName()
+ info.include = self.info.include
+ exporter = exporter_type(info)
+ exporter.SetDeclarations(self.declarations)
+ exporter.SetParsedHeader(self.parser_header)
+ if isinstance(codeunit, MultipleCodeUnit.MultipleCodeUnit):
+ codeunit.SetCurrent(self.interface_file, exporter.Name())
+ else:
+ codeunit.SetCurrent(exporter.Name())
+ exporter.GenerateCode(codeunit, exported_names)
+
+
+ def Name(self):
+ return self.info.include
diff --git a/libs/python/pyste/src/Pyste/MultipleCodeUnit.py b/libs/python/pyste/src/Pyste/MultipleCodeUnit.py
new file mode 100644
index 000000000..65faad45d
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/MultipleCodeUnit.py
@@ -0,0 +1,135 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from SingleCodeUnit import SingleCodeUnit
+import os
+import utils
+from SmartFile import SmartFile
+
+
+#==============================================================================
+# MultipleCodeUnit
+#==============================================================================
+class MultipleCodeUnit(object):
+ '''
+ Represents a bunch of cpp files, where each cpp file represents a header
+ to be exported by pyste. Another cpp, named <module>.cpp is created too.
+ '''
+
+ def __init__(self, modulename, outdir):
+ self.modulename = modulename
+ self.outdir = outdir
+ self.codeunits = {} # maps from a (filename, function) to a SingleCodeUnit
+ self.functions = []
+ self._current = None
+ self.all = SingleCodeUnit(None, None)
+
+
+ def _FunctionName(self, interface_file):
+ name = os.path.splitext(interface_file)[0]
+ return 'Export_%s' % utils.makeid(name)
+
+
+ def _FileName(self, interface_file):
+ filename = os.path.basename(interface_file)
+ filename = '_%s.cpp' % os.path.splitext(filename)[0]
+ return os.path.join(self.outdir, filename)
+
+
+ def SetCurrent(self, interface_file, export_name):
+ 'Changes the current code unit'
+ if export_name is None:
+ self._current = None
+ elif export_name is '__all__':
+ self._current = self.all
+ else:
+ filename = self._FileName(interface_file)
+ function = self._FunctionName(interface_file)
+ try:
+ codeunit = self.codeunits[filename]
+ except KeyError:
+ codeunit = SingleCodeUnit(None, filename)
+ codeunit.module_definition = 'void %s()' % function
+ self.codeunits[filename] = codeunit
+ if function not in self.functions:
+ self.functions.append(function)
+ self._current = codeunit
+
+
+ def Current(self):
+ return self._current
+
+ current = property(Current, SetCurrent)
+
+
+ def Write(self, section, code):
+ if self._current is not None:
+ self.current.Write(section, code)
+
+
+ def Section(self, section):
+ if self._current is not None:
+ return self.current.Section(section)
+
+
+ def _CreateOutputDir(self):
+ try:
+ os.mkdir(self.outdir)
+ except OSError: pass # already created
+
+
+ def Save(self):
+ # create the directory where all the files will go
+ self._CreateOutputDir();
+ # order all code units by filename, and merge them all
+ codeunits = {} # filename => list of codeunits
+
+ # While ordering all code units by file name, the first code
+ # unit in the list of code units is used as the main unit
+ # which dumps all the include, declaration and
+ # declaration-outside sections at the top of the file.
+ for filename, codeunit in self.codeunits.items():
+ if filename not in codeunits:
+ # this codeunit is the main codeunit.
+ codeunits[filename] = [codeunit]
+ codeunit.Merge(self.all)
+ else:
+ main_unit = codeunits[filename][0]
+ for section in ('include', 'declaration', 'declaration-outside'):
+ main_unit.code[section] = main_unit.code[section] + codeunit.code[section]
+ codeunit.code[section] = ''
+ codeunits[filename].append(codeunit)
+
+ # Now write all the codeunits appending them correctly.
+ for file_units in codeunits.values():
+ append = False
+ for codeunit in file_units:
+ codeunit.Save(append)
+ if not append:
+ append = True
+
+
+ def GenerateMain(self, interfaces):
+ # generate the main cpp
+ filename = os.path.join(self.outdir, '_main.cpp')
+ fout = SmartFile(filename, 'w')
+ fout.write(utils.left_equals('Include'))
+ fout.write('#include <boost/python/module.hpp>\n\n')
+ fout.write(utils.left_equals('Exports'))
+ functions = [self._FunctionName(x) for x in interfaces]
+ for function in functions:
+ fout.write('void %s();\n' % function)
+ fout.write('\n')
+ fout.write(utils.left_equals('Module'))
+ fout.write('BOOST_PYTHON_MODULE(%s)\n' % self.modulename)
+ fout.write('{\n')
+ indent = ' ' * 4
+ for function in functions:
+ fout.write(indent)
+ fout.write('%s();\n' % function)
+ fout.write('}\n')
+
+
+
diff --git a/libs/python/pyste/src/Pyste/SingleCodeUnit.py b/libs/python/pyste/src/Pyste/SingleCodeUnit.py
new file mode 100644
index 000000000..2e59dbb80
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/SingleCodeUnit.py
@@ -0,0 +1,121 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from settings import namespaces
+import settings
+from utils import remove_duplicated_lines, left_equals
+from SmartFile import SmartFile
+
+
+#==============================================================================
+# SingleCodeUnit
+#==============================================================================
+class SingleCodeUnit:
+ '''
+ Represents a cpp file, where other objects can write in one of the
+ predefined sections.
+ The avaiable sections are:
+ pchinclude - The pre-compiled header area
+ include - The include area of the cpp file
+ declaration - The part before the module definition
+ module - Inside the BOOST_PYTHON_MODULE macro
+ '''
+
+ def __init__(self, modulename, filename):
+ self.modulename = modulename
+ self.filename = filename
+ # define the avaiable sections
+ self.code = {}
+ # include section
+ self.code['pchinclude'] = ''
+ # include section
+ self.code['include'] = ''
+ # declaration section (inside namespace)
+ self.code['declaration'] = ''
+ # declaration (outside namespace)
+ self.code['declaration-outside'] = ''
+ # inside BOOST_PYTHON_MACRO
+ self.code['module'] = ''
+ # create the default module definition
+ self.module_definition = 'BOOST_PYTHON_MODULE(%s)' % modulename
+
+
+ def Write(self, section, code):
+ 'write the given code in the section of the code unit'
+ if section not in self.code:
+ raise RuntimeError, 'Invalid CodeUnit section: %s' % section
+ self.code[section] += code
+
+
+ def Merge(self, other):
+ for section in ('include', 'declaration', 'declaration-outside', 'module'):
+ self.code[section] = self.code[section] + other.code[section]
+
+
+ def Section(self, section):
+ return self.code[section]
+
+
+ def SetCurrent(self, *args):
+ pass
+
+
+ def Current(self):
+ pass
+
+
+ def Save(self, append=False):
+ 'Writes this code unit to the filename'
+ space = '\n\n'
+ if not append:
+ flag = 'w'
+ else:
+ flag = 'a'
+ fout = SmartFile(self.filename, flag)
+ fout.write('\n')
+ # includes
+ # boost.python header
+ if self.code['pchinclude']:
+ fout.write(left_equals('PCH'))
+ fout.write(self.code['pchinclude']+'\n')
+ fout.write('#ifdef _MSC_VER\n')
+ fout.write('#pragma hdrstop\n')
+ fout.write('#endif\n')
+ else:
+ fout.write(left_equals('Boost Includes'))
+ fout.write('#include <boost/python.hpp>\n')
+ # include numerical boost for int64 definitions
+ fout.write('#include <boost/cstdint.hpp>\n')
+ fout.write('\n')
+ # other includes
+ if self.code['include']:
+ fout.write(left_equals('Includes'))
+ includes = remove_duplicated_lines(self.code['include'])
+ fout.write(includes)
+ fout.write(space)
+ # using
+ if settings.USING_BOOST_NS and not append:
+ fout.write(left_equals('Using'))
+ fout.write('using namespace boost::python;\n\n')
+ # declarations
+ declaration = self.code['declaration']
+ declaration_outside = self.code['declaration-outside']
+ if declaration_outside or declaration:
+ fout.write(left_equals('Declarations'))
+ if declaration_outside:
+ fout.write(declaration_outside + '\n\n')
+ if declaration:
+ pyste_namespace = namespaces.pyste[:-2]
+ fout.write('namespace %s {\n\n' % pyste_namespace)
+ fout.write(declaration)
+ fout.write('\n}// namespace %s\n' % pyste_namespace)
+ fout.write(space)
+ # module
+ fout.write(left_equals('Module'))
+ fout.write(self.module_definition + '\n')
+ fout.write('{\n')
+ fout.write(self.code['module'])
+ fout.write('}\n\n')
+ fout.close()
diff --git a/libs/python/pyste/src/Pyste/SmartFile.py b/libs/python/pyste/src/Pyste/SmartFile.py
new file mode 100644
index 000000000..039579e3b
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/SmartFile.py
@@ -0,0 +1,60 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import os
+import md5
+
+#==============================================================================
+# SmartFile
+#==============================================================================
+class SmartFile(object):
+ '''
+ A file-like object used for writing files. The given file will only be
+ actually written to disk if there's not a file with the same name, or if
+ the existing file is *different* from the file to be written.
+ '''
+
+ def __init__(self, filename, mode='w'):
+ self.filename = filename
+ self.mode = mode
+ self._contents = []
+ self._closed = False
+
+
+ def __del__(self):
+ if not self._closed:
+ self.close()
+
+
+ def write(self, string):
+ self._contents.append(string)
+
+
+ def _dowrite(self, contents):
+ f = file(self.filename, self.mode)
+ f.write(contents)
+ f.close()
+
+
+ def _GetMD5(self, string):
+ return md5.new(string).digest()
+
+
+ def close(self):
+ # if the filename doesn't exist, write the file right away
+ this_contents = ''.join(self._contents)
+ if not os.path.isfile(self.filename):
+ self._dowrite(this_contents)
+ else:
+ # read the contents of the file already in disk
+ f = file(self.filename)
+ other_contents = f.read()
+ f.close()
+ # test the md5 for both files
+ this_md5 = self._GetMD5(this_contents)
+ other_md5 = self._GetMD5(other_contents)
+ if this_md5 != other_md5:
+ self._dowrite(this_contents)
+ self._closed = True
diff --git a/libs/python/pyste/src/Pyste/VarExporter.py b/libs/python/pyste/src/Pyste/VarExporter.py
new file mode 100644
index 000000000..d3571e751
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/VarExporter.py
@@ -0,0 +1,40 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from Exporter import Exporter
+from settings import *
+import utils
+
+#==============================================================================
+# VarExporter
+#==============================================================================
+class VarExporter(Exporter):
+ '''Exports a global variable.
+ '''
+
+ def __init__(self, info):
+ Exporter.__init__(self, info)
+
+
+ def Export(self, codeunit, exported_names):
+ if self.info.exclude: return
+ decl = self.GetDeclaration(self.info.name)
+ if not decl.type.const:
+ msg = '---> Warning: The global variable "%s" is non-const:\n' \
+ ' changes in Python will not reflect in C++.'
+ print msg % self.info.name
+ print
+ rename = self.info.rename or self.info.name
+ code = self.INDENT + namespaces.python
+ code += 'scope().attr("%s") = %s;\n' % (rename, self.info.name)
+ codeunit.Write('module', code)
+
+
+ def Order(self):
+ return 0, self.info.name
+
+
+ def Name(self):
+ return self.info.name
diff --git a/libs/python/pyste/src/Pyste/__init__.py b/libs/python/pyste/src/Pyste/__init__.py
new file mode 100644
index 000000000..02eec64b7
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/__init__.py
@@ -0,0 +1,6 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+
diff --git a/libs/python/pyste/src/Pyste/declarations.py b/libs/python/pyste/src/Pyste/declarations.py
new file mode 100644
index 000000000..6eff97dc5
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/declarations.py
@@ -0,0 +1,653 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+'''
+Defines classes that represent declarations found in C++ header files.
+
+'''
+
+# version indicates the version of the declarations. Whenever a declaration
+# changes, this variable should be updated, so that the caches can be rebuilt
+# automatically
+version = '1.0'
+
+#==============================================================================
+# Declaration
+#==============================================================================
+class Declaration(object):
+ '''Base class for all declarations.
+ @ivar name: The name of the declaration.
+ @ivar namespace: The namespace of the declaration.
+ '''
+
+ def __init__(self, name, namespace):
+ '''
+ @type name: string
+ @param name: The name of this declaration
+ @type namespace: string
+ @param namespace: the full namespace where this declaration resides.
+ '''
+ self.name = name
+ self.namespace = namespace
+ self.location = '', -1 # (filename, line)
+ self.incomplete = False
+ self.is_unique = True
+
+
+ def FullName(self):
+ '''
+ Returns the full qualified name: "boost::inner::Test"
+ @rtype: string
+ @return: The full name of the declaration.
+ '''
+ namespace = self.namespace or ''
+ if namespace and not namespace.endswith('::'):
+ namespace += '::'
+ return namespace + self.name
+
+
+ def __repr__(self):
+ return '<Declaration %s at %s>' % (self.FullName(), id(self))
+
+
+ def __str__(self):
+ return 'Declaration of %s' % self.FullName()
+
+
+#==============================================================================
+# Class
+#==============================================================================
+class Class(Declaration):
+ '''
+ Represents a C++ class or struct. Iteration through it yields its members.
+
+ @type abstract: bool
+ @ivar abstract: if the class has any abstract methods.
+
+ @type bases: tuple
+ @ivar bases: tuple with L{Base} instances, representing the most direct
+ inheritance.
+
+ @type hierarchy: list
+ @ivar hierarchy: a list of tuples of L{Base} instances, representing
+ the entire hierarchy tree of this object. The first tuple is the parent
+ classes, and the other ones go up in the hierarchy.
+ '''
+
+ def __init__(self, name, namespace, members, abstract):
+ Declaration.__init__(self, name, namespace)
+ self.__members = members
+ self.__member_names = {}
+ self.abstract = abstract
+ self.bases = ()
+ self.hierarchy = ()
+ self.operator = {}
+
+
+ def __iter__(self):
+ '''iterates through the class' members.
+ '''
+ return iter(self.__members)
+
+
+ def Constructors(self, publics_only=True):
+ '''Returns a list of the constructors for this class.
+ @rtype: list
+ '''
+ constructors = []
+ for member in self:
+ if isinstance(member, Constructor):
+ if publics_only and member.visibility != Scope.public:
+ continue
+ constructors.append(member)
+ return constructors
+
+
+ def HasCopyConstructor(self):
+ '''Returns true if this class has a public copy constructor.
+ @rtype: bool
+ '''
+ for cons in self.Constructors():
+ if cons.IsCopy():
+ return True
+ return False
+
+
+ def HasDefaultConstructor(self):
+ '''Returns true if this class has a public default constructor.
+ @rtype: bool
+ '''
+ for cons in self.Constructors():
+ if cons.IsDefault():
+ return True
+ return False
+
+
+ def AddMember(self, member):
+ if member.name in self.__member_names:
+ member.is_unique = False
+ for m in self:
+ if m.name == member.name:
+ m.is_unique = False
+ else:
+ member.is_unique = True
+ self.__member_names[member.name] = 1
+ self.__members.append(member)
+ if isinstance(member, ClassOperator):
+ self.operator[member.name] = member
+
+
+ def ValidMemberTypes():
+ return (NestedClass, Method, Constructor, Destructor, ClassVariable,
+ ClassOperator, ConverterOperator, ClassEnumeration)
+ ValidMemberTypes = staticmethod(ValidMemberTypes)
+
+
+#==============================================================================
+# NestedClass
+#==============================================================================
+class NestedClass(Class):
+ '''The declaration of a class/struct inside another class/struct.
+
+ @type class: string
+ @ivar class: fullname of the class where this class is contained.
+
+ @type visibility: L{Scope}
+ @ivar visibility: the visibility of this class.
+ '''
+
+ def __init__(self, name, class_, visib, members, abstract):
+ Class.__init__(self, name, None, members, abstract)
+ self.class_ = class_
+ self.visibility = visib
+
+
+ def FullName(self):
+ '''The full name of this class, like ns::outer::inner.
+ @rtype: string
+ '''
+ return '%s::%s' % (self.class_, self.name)
+
+
+#==============================================================================
+# Scope
+#==============================================================================
+class Scope:
+ '''Used to represent the visibility of various members inside a class.
+ @cvar public: public visibility
+ @cvar private: private visibility
+ @cvar protected: protected visibility
+ '''
+ public = 'public'
+ private = 'private'
+ protected = 'protected'
+
+
+#==============================================================================
+# Base
+#==============================================================================
+class Base:
+ '''Represents a base class of another class.
+ @ivar _name: the full name of the base class.
+ @ivar _visibility: the visibility of the derivation.
+ '''
+
+ def __init__(self, name, visibility=Scope.public):
+ self.name = name
+ self.visibility = visibility
+
+
+#==============================================================================
+# Function
+#==============================================================================
+class Function(Declaration):
+ '''The declaration of a function.
+ @ivar _result: instance of L{Type} or None.
+ @ivar _parameters: list of L{Type} instances.
+ @ivar _throws: exception specifiers or None
+ '''
+
+ def __init__(self, name, namespace, result, params, throws=None):
+ Declaration.__init__(self, name, namespace)
+ # the result type: instance of Type, or None (constructors)
+ self.result = result
+ # the parameters: instances of Type
+ self.parameters = params
+ # the exception specification
+ self.throws = throws
+
+
+ def Exceptions(self):
+ if self.throws is None:
+ return ""
+ else:
+ return " throw(%s)" % ', '.join ([x.FullName() for x in self.throws])
+
+
+ def PointerDeclaration(self, force=False):
+ '''Returns a declaration of a pointer to this function.
+ @param force: If True, returns a complete pointer declaration regardless
+ if this function is unique or not.
+ '''
+ if self.is_unique and not force:
+ return '&%s' % self.FullName()
+ else:
+ result = self.result.FullName()
+ params = ', '.join([x.FullName() for x in self.parameters])
+ return '(%s (*)(%s)%s)&%s' % (result, params, self.Exceptions(), self.FullName())
+
+
+ def MinArgs(self):
+ min = 0
+ for arg in self.parameters:
+ if arg.default is None:
+ min += 1
+ return min
+
+ minArgs = property(MinArgs)
+
+
+ def MaxArgs(self):
+ return len(self.parameters)
+
+ maxArgs = property(MaxArgs)
+
+
+
+#==============================================================================
+# Operator
+#==============================================================================
+class Operator(Function):
+ '''The declaration of a custom operator. Its name is the same as the
+ operator name in C++, ie, the name of the declaration "operator+(..)" is
+ "+".
+ '''
+
+ def FullName(self):
+ namespace = self.namespace or ''
+ if not namespace.endswith('::'):
+ namespace += '::'
+ return namespace + 'operator' + self.name
+
+
+#==============================================================================
+# Method
+#==============================================================================
+class Method(Function):
+ '''The declaration of a method.
+
+ @ivar _visibility: the visibility of this method.
+ @ivar _virtual: if this method is declared as virtual.
+ @ivar _abstract: if this method is virtual but has no default implementation.
+ @ivar _static: if this method is static.
+ @ivar _class: the full name of the class where this method was declared.
+ @ivar _const: if this method is declared as const.
+ @ivar _throws: list of exception specificiers or None
+ '''
+
+ def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const, throws=None):
+ Function.__init__(self, name, None, result, params, throws)
+ self.visibility = visib
+ self.virtual = virtual
+ self.abstract = abstract
+ self.static = static
+ self.class_ = class_
+ self.const = const
+
+
+ def FullName(self):
+ return self.class_ + '::' + self.name
+
+
+ def PointerDeclaration(self, force=False):
+ '''Returns a declaration of a pointer to this member function.
+ @param force: If True, returns a complete pointer declaration regardless
+ if this function is unique or not.
+ '''
+ if self.static:
+ # static methods are like normal functions
+ return Function.PointerDeclaration(self, force)
+ if self.is_unique and not force:
+ return '&%s' % self.FullName()
+ else:
+ result = self.result.FullName()
+ params = ', '.join([x.FullName() for x in self.parameters])
+ const = ''
+ if self.const:
+ const = 'const'
+ return '(%s (%s::*)(%s) %s%s)&%s' %\
+ (result, self.class_, params, const, self.Exceptions(), self.FullName())
+
+
+#==============================================================================
+# Constructor
+#==============================================================================
+class Constructor(Method):
+ '''A class' constructor.
+ '''
+
+ def __init__(self, name, class_, params, visib):
+ Method.__init__(self, name, class_, None, params, visib, False, False, False, False)
+
+
+ def IsDefault(self):
+ '''Returns True if this constructor is a default constructor.
+ '''
+ return len(self.parameters) == 0 and self.visibility == Scope.public
+
+
+ def IsCopy(self):
+ '''Returns True if this constructor is a copy constructor.
+ '''
+ if len(self.parameters) != 1:
+ return False
+ param = self.parameters[0]
+ class_as_param = self.parameters[0].name == self.class_
+ param_reference = isinstance(param, ReferenceType)
+ is_public = self.visibility == Scope.public
+ return param_reference and class_as_param and param.const and is_public
+
+
+ def PointerDeclaration(self, force=False):
+ return ''
+
+
+#==============================================================================
+# Destructor
+#==============================================================================
+class Destructor(Method):
+ 'The destructor of a class.'
+
+ def __init__(self, name, class_, visib, virtual):
+ Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False)
+
+ def FullName(self):
+ return self.class_ + '::~' + self.name
+
+
+ def PointerDeclaration(self, force=False):
+ return ''
+
+
+
+#==============================================================================
+# ClassOperator
+#==============================================================================
+class ClassOperator(Method):
+ 'A custom operator in a class.'
+
+ def FullName(self):
+ return self.class_ + '::operator ' + self.name
+
+
+
+#==============================================================================
+# ConverterOperator
+#==============================================================================
+class ConverterOperator(ClassOperator):
+ 'An operator in the form "operator OtherClass()".'
+
+ def FullName(self):
+ return self.class_ + '::operator ' + self.result.FullName()
+
+
+
+#==============================================================================
+# Type
+#==============================================================================
+class Type(Declaration):
+ '''Represents the type of a variable or parameter.
+ @ivar _const: if the type is constant.
+ @ivar _default: if this type has a default value associated with it.
+ @ivar _volatile: if this type was declared with the keyword volatile.
+ @ivar _restricted: if this type was declared with the keyword restricted.
+ @ivar _suffix: Suffix to get the full type name. '*' for pointers, for
+ example.
+ '''
+
+ def __init__(self, name, const=False, default=None, suffix=''):
+ Declaration.__init__(self, name, None)
+ # whatever the type is constant or not
+ self.const = const
+ # used when the Type is a function argument
+ self.default = default
+ self.volatile = False
+ self.restricted = False
+ self.suffix = suffix
+
+ def __repr__(self):
+ if self.const:
+ const = 'const '
+ else:
+ const = ''
+ return '<Type ' + const + self.name + '>'
+
+
+ def FullName(self):
+ if self.const:
+ const = 'const '
+ else:
+ const = ''
+ return const + self.name + self.suffix
+
+
+#==============================================================================
+# ArrayType
+#==============================================================================
+class ArrayType(Type):
+ '''Represents an array.
+ @ivar min: the lower bound of the array, usually 0. Can be None.
+ @ivar max: the upper bound of the array. Can be None.
+ '''
+
+ def __init__(self, name, const, min, max):
+ 'min and max can be None.'
+ Type.__init__(self, name, const)
+ self.min = min
+ self.max = max
+
+
+
+#==============================================================================
+# ReferenceType
+#==============================================================================
+class ReferenceType(Type):
+ '''A reference type.'''
+
+ def __init__(self, name, const=False, default=None, expandRef=True, suffix=''):
+ Type.__init__(self, name, const, default)
+ if expandRef:
+ self.suffix = suffix + '&'
+
+
+#==============================================================================
+# PointerType
+#==============================================================================
+class PointerType(Type):
+ 'A pointer type.'
+
+ def __init__(self, name, const=False, default=None, expandPointer=False, suffix=''):
+ Type.__init__(self, name, const, default)
+ if expandPointer:
+ self.suffix = suffix + '*'
+
+
+#==============================================================================
+# FundamentalType
+#==============================================================================
+class FundamentalType(Type):
+ 'One of the fundamental types, like int, void, etc.'
+
+ def __init__(self, name, const=False, default=None):
+ Type.__init__(self, name, const, default)
+
+
+
+#==============================================================================
+# FunctionType
+#==============================================================================
+class FunctionType(Type):
+ '''A pointer to a function.
+ @ivar _result: the return value
+ @ivar _parameters: a list of Types, indicating the parameters of the function.
+ @ivar _name: the name of the function.
+ '''
+
+ def __init__(self, result, parameters):
+ Type.__init__(self, '', False)
+ self.result = result
+ self.parameters = parameters
+ self.name = self.FullName()
+
+
+ def FullName(self):
+ full = '%s (*)' % self.result.FullName()
+ params = [x.FullName() for x in self.parameters]
+ full += '(%s)' % ', '.join(params)
+ return full
+
+
+#==============================================================================
+# MethodType
+#==============================================================================
+class MethodType(FunctionType):
+ '''A pointer to a member function of a class.
+ @ivar _class: The fullname of the class that the method belongs to.
+ '''
+
+ def __init__(self, result, parameters, class_):
+ self.class_ = class_
+ FunctionType.__init__(self, result, parameters)
+
+
+ def FullName(self):
+ full = '%s (%s::*)' % (self.result.FullName(), self.class_)
+ params = [x.FullName() for x in self.parameters]
+ full += '(%s)' % ', '.join(params)
+ return full
+
+
+#==============================================================================
+# Variable
+#==============================================================================
+class Variable(Declaration):
+ '''Represents a global variable.
+
+ @type _type: L{Type}
+ @ivar _type: The type of the variable.
+ '''
+
+ def __init__(self, type, name, namespace):
+ Declaration.__init__(self, name, namespace)
+ self.type = type
+
+
+#==============================================================================
+# ClassVariable
+#==============================================================================
+class ClassVariable(Variable):
+ '''Represents a class variable.
+
+ @type _visibility: L{Scope}
+ @ivar _visibility: The visibility of this variable within the class.
+
+ @type _static: bool
+ @ivar _static: Indicates if the variable is static.
+
+ @ivar _class: Full name of the class that this variable belongs to.
+ '''
+
+ def __init__(self, type, name, class_, visib, static):
+ Variable.__init__(self, type, name, None)
+ self.visibility = visib
+ self.static = static
+ self.class_ = class_
+
+
+ def FullName(self):
+ return self.class_ + '::' + self.name
+
+
+#==============================================================================
+# Enumeration
+#==============================================================================
+class Enumeration(Declaration):
+ '''Represents an enum.
+
+ @type _values: dict of str => int
+ @ivar _values: holds the values for this enum.
+ '''
+
+ def __init__(self, name, namespace):
+ Declaration.__init__(self, name, namespace)
+ self.values = {} # dict of str => int
+
+
+ def ValueFullName(self, name):
+ '''Returns the full name for a value in the enum.
+ '''
+ assert name in self.values
+ namespace = self.namespace
+ if namespace:
+ namespace += '::'
+ return namespace + name
+
+
+#==============================================================================
+# ClassEnumeration
+#==============================================================================
+class ClassEnumeration(Enumeration):
+ '''Represents an enum inside a class.
+
+ @ivar _class: The full name of the class where this enum belongs.
+ @ivar _visibility: The visibility of this enum inside his class.
+ '''
+
+ def __init__(self, name, class_, visib):
+ Enumeration.__init__(self, name, None)
+ self.class_ = class_
+ self.visibility = visib
+
+
+ def FullName(self):
+ return '%s::%s' % (self.class_, self.name)
+
+
+ def ValueFullName(self, name):
+ assert name in self.values
+ return '%s::%s' % (self.class_, name)
+
+
+#==============================================================================
+# Typedef
+#==============================================================================
+class Typedef(Declaration):
+ '''A Typedef declaration.
+
+ @type _type: L{Type}
+ @ivar _type: The type of the typedef.
+
+ @type _visibility: L{Scope}
+ @ivar _visibility: The visibility of this typedef.
+ '''
+
+ def __init__(self, type, name, namespace):
+ Declaration.__init__(self, name, namespace)
+ self.type = type
+ self.visibility = Scope.public
+
+
+
+
+
+#==============================================================================
+# Unknown
+#==============================================================================
+class Unknown(Declaration):
+ '''A declaration that Pyste does not know how to handle.
+ '''
+
+ def __init__(self, name):
+ Declaration.__init__(self, name, None)
diff --git a/libs/python/pyste/src/Pyste/exporters.py b/libs/python/pyste/src/Pyste/exporters.py
new file mode 100644
index 000000000..f573d01be
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/exporters.py
@@ -0,0 +1,12 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+
+# a list of Exporter instances
+exporters = []
+
+current_interface = None # the current interface file being processed
+importing = False # whetever we are now importing a pyste file.
+ # exporters created here shouldn't export themselves
diff --git a/libs/python/pyste/src/Pyste/exporterutils.py b/libs/python/pyste/src/Pyste/exporterutils.py
new file mode 100644
index 000000000..363700d2b
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/exporterutils.py
@@ -0,0 +1,87 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+'''
+Various helpers for interface files.
+'''
+
+from settings import *
+from policies import *
+from declarations import *
+
+#==============================================================================
+# FunctionWrapper
+#==============================================================================
+class FunctionWrapper(object):
+ '''Holds information about a wrapper for a function or a method. It is
+ divided in 2 parts: the name of the Wrapper, and its code. The code is
+ placed in the declaration section of the module, while the name is used to
+ def' the function or method (with the pyste namespace prepend to it). If
+ code is None, the name is left unchanged.
+ '''
+
+ def __init__(self, name, code=None):
+ self.name = name
+ self.code = code
+
+ def FullName(self):
+ if self.code:
+ return namespaces.pyste + self.name
+ else:
+ return self.name
+
+
+_printed_warnings = {} # used to avoid double-prints of warnings
+
+#==============================================================================
+# HandlePolicy
+#==============================================================================
+def HandlePolicy(function, policy):
+ '''Show a warning to the user if the function needs a policy and doesn't
+ have one. Return a policy to the function, which is the given policy itself
+ if it is not None, or a default policy for this method.
+ '''
+
+ def IsString(type):
+ 'Return True if the Type instance can be considered a string'
+ return type.FullName() == 'const char*'
+
+ def IsPyObject(type):
+ return type.FullName() == '_object *' # internal name of PyObject
+
+ result = function.result
+ # if the function returns const char*, a policy is not needed
+ if IsString(result) or IsPyObject(result):
+ return policy
+ # if returns a const T&, set the default policy
+ if policy is None and result.const and isinstance(result, ReferenceType):
+ policy = return_value_policy(copy_const_reference)
+ # basic test if the result type demands a policy
+ needs_policy = isinstance(result, (ReferenceType, PointerType))
+ # show a warning to the user, if needed
+ if needs_policy and policy is None:
+ global _printed_warnings
+ warning = '---> Error: %s returns a pointer or a reference, ' \
+ 'but no policy was specified.' % function.FullName()
+ if warning not in _printed_warnings:
+ print warning
+ print
+ # avoid double prints of the same warning
+ _printed_warnings[warning] = 1
+ return policy
+
+
+#==============================================================================
+# EspecializeTypeID
+#==============================================================================
+_exported_type_ids = {}
+def EspecializeTypeID(typename):
+ global _exported_type_ids
+ macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)\n' % typename
+ if macro not in _exported_type_ids:
+ _exported_type_ids[macro] = 1
+ return macro
+ else:
+ return None
diff --git a/libs/python/pyste/src/Pyste/infos.py b/libs/python/pyste/src/Pyste/infos.py
new file mode 100644
index 000000000..2a4f01eaf
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/infos.py
@@ -0,0 +1,259 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import os.path
+import copy
+import exporters
+from ClassExporter import ClassExporter
+from FunctionExporter import FunctionExporter
+from EnumExporter import EnumExporter
+from HeaderExporter import HeaderExporter
+from VarExporter import VarExporter
+from CodeExporter import CodeExporter
+from exporterutils import FunctionWrapper
+from utils import makeid
+import warnings
+
+#==============================================================================
+# DeclarationInfo
+#==============================================================================
+class DeclarationInfo:
+
+ def __init__(self, otherInfo=None):
+ self.__infos = {}
+ self.__attributes = {}
+ if otherInfo is not None:
+ self.__infos = copy.deepcopy(otherInfo.__infos)
+ self.__attributes = copy.deepcopy(otherInfo.__attributes)
+
+
+ def __getitem__(self, name):
+ 'Used to access sub-infos'
+ if name.startswith('__'):
+ raise AttributeError
+ default = DeclarationInfo()
+ default._Attribute('name', name)
+ return self.__infos.setdefault(name, default)
+
+
+ def __getattr__(self, name):
+ return self[name]
+
+
+ def _Attribute(self, name, value=None):
+ if value is None:
+ # get value
+ return self.__attributes.get(name)
+ else:
+ # set value
+ self.__attributes[name] = value
+
+
+ def AddExporter(self, exporter):
+ # this was causing a much serious bug, as reported by Niall Douglas:
+ # another solution must be found!
+ #if not exporters.importing:
+ if exporter not in exporters.exporters:
+ exporters.exporters.append(exporter)
+ exporter.interface_file = exporters.current_interface
+
+
+#==============================================================================
+# FunctionInfo
+#==============================================================================
+class FunctionInfo(DeclarationInfo):
+
+ def __init__(self, name, include, tail=None, otherOption=None,
+ exporter_class = FunctionExporter):
+ DeclarationInfo.__init__(self, otherOption)
+ self._Attribute('name', name)
+ self._Attribute('include', include)
+ self._Attribute('exclude', False)
+ # create a FunctionExporter
+ exporter = exporter_class(InfoWrapper(self), tail)
+ self.AddExporter(exporter)
+
+
+#==============================================================================
+# ClassInfo
+#==============================================================================
+class ClassInfo(DeclarationInfo):
+
+ def __init__(self, name, include, tail=None, otherInfo=None,
+ exporter_class = ClassExporter):
+ DeclarationInfo.__init__(self, otherInfo)
+ self._Attribute('name', name)
+ self._Attribute('include', include)
+ self._Attribute('exclude', False)
+ # create a ClassExporter
+ exporter = exporter_class(InfoWrapper(self), tail)
+ self.AddExporter(exporter)
+
+
+#==============================================================================
+# templates
+#==============================================================================
+def GenerateName(name, type_list):
+ name = name.replace('::', '_')
+ names = [name] + type_list
+ return makeid('_'.join(names))
+
+
+class ClassTemplateInfo(DeclarationInfo):
+
+ def __init__(self, name, include,
+ exporter_class = ClassExporter):
+ DeclarationInfo.__init__(self)
+ self._Attribute('name', name)
+ self._Attribute('include', include)
+ self._exporter_class = exporter_class
+
+
+ def Instantiate(self, type_list, rename=None):
+ if not rename:
+ rename = GenerateName(self._Attribute('name'), type_list)
+ # generate code to instantiate the template
+ types = ', '.join(type_list)
+ tail = 'typedef %s< %s > %s;\n' % (self._Attribute('name'), types, rename)
+ tail += 'void __instantiate_%s()\n' % rename
+ tail += '{ sizeof(%s); }\n\n' % rename
+ # create a ClassInfo
+ class_ = ClassInfo(rename, self._Attribute('include'), tail, self,
+ exporter_class = self._exporter_class)
+ return class_
+
+
+ def __call__(self, types, rename=None):
+ if isinstance(types, str):
+ types = types.split()
+ return self.Instantiate(types, rename)
+
+#==============================================================================
+# EnumInfo
+#==============================================================================
+class EnumInfo(DeclarationInfo):
+
+ def __init__(self, name, include, exporter_class = EnumExporter):
+ DeclarationInfo.__init__(self)
+ self._Attribute('name', name)
+ self._Attribute('include', include)
+ self._Attribute('exclude', False)
+ self._Attribute('export_values', False)
+ exporter = exporter_class(InfoWrapper(self))
+ self.AddExporter(exporter)
+
+
+#==============================================================================
+# HeaderInfo
+#==============================================================================
+class HeaderInfo(DeclarationInfo):
+
+ def __init__(self, include, exporter_class = HeaderExporter):
+ warnings.warn('AllFromHeader is not working in all cases in the current version.')
+ DeclarationInfo.__init__(self)
+ self._Attribute('include', include)
+ exporter = exporter_class(InfoWrapper(self))
+ self.AddExporter(exporter)
+
+
+#==============================================================================
+# VarInfo
+#==============================================================================
+class VarInfo(DeclarationInfo):
+
+ def __init__(self, name, include, exporter_class = VarExporter):
+ DeclarationInfo.__init__(self)
+ self._Attribute('name', name)
+ self._Attribute('include', include)
+ exporter = exporter_class(InfoWrapper(self))
+ self.AddExporter(exporter)
+
+
+#==============================================================================
+# CodeInfo
+#==============================================================================
+class CodeInfo(DeclarationInfo):
+
+ def __init__(self, code, section, exporter_class = CodeExporter):
+ DeclarationInfo.__init__(self)
+ self._Attribute('code', code)
+ self._Attribute('section', section)
+ exporter = exporter_class(InfoWrapper(self))
+ self.AddExporter(exporter)
+
+
+#==============================================================================
+# InfoWrapper
+#==============================================================================
+class InfoWrapper:
+ 'Provides a nicer interface for a info'
+
+ def __init__(self, info):
+ self.__dict__['_info'] = info # so __setattr__ is not called
+
+ def __getitem__(self, name):
+ return InfoWrapper(self._info[name])
+
+ def __getattr__(self, name):
+ return self._info._Attribute(name)
+
+ def __setattr__(self, name, value):
+ self._info._Attribute(name, value)
+
+
+#==============================================================================
+# Functions
+#==============================================================================
+def exclude(info):
+ info._Attribute('exclude', True)
+
+def set_policy(info, policy):
+ info._Attribute('policy', policy)
+
+def rename(info, name):
+ info._Attribute('rename', name)
+
+def set_wrapper(info, wrapper):
+ if isinstance(wrapper, str):
+ wrapper = FunctionWrapper(wrapper)
+ info._Attribute('wrapper', wrapper)
+
+def instantiate(template, types, rename=None):
+ if isinstance(types, str):
+ types = types.split()
+ return template.Instantiate(types, rename)
+
+def use_shared_ptr(info):
+ info._Attribute('smart_ptr', 'boost::shared_ptr< %s >')
+
+def use_auto_ptr(info):
+ info._Attribute('smart_ptr', 'std::auto_ptr< %s >')
+
+def holder(info, function):
+ msg = "Expected a callable that accepts one string argument."
+ assert callable(function), msg
+ info._Attribute('holder', function)
+
+def add_method(info, name, rename=None):
+ added = info._Attribute('__added__')
+ if added is None:
+ info._Attribute('__added__', [(name, rename)])
+ else:
+ added.append((name, rename))
+
+
+def class_code(info, code):
+ added = info._Attribute('__code__')
+ if added is None:
+ info._Attribute('__code__', [code])
+ else:
+ added.append(code)
+
+def final(info):
+ info._Attribute('no_override', True)
+
+
+def export_values(info):
+ info._Attribute('export_values', True)
diff --git a/libs/python/pyste/src/Pyste/policies.py b/libs/python/pyste/src/Pyste/policies.py
new file mode 100644
index 000000000..57ebd0dea
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/policies.py
@@ -0,0 +1,95 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+class Policy(object):
+ 'Represents one of the call policies of boost.python.'
+
+ def __init__(self):
+ if type(self) is Policy:
+ raise RuntimeError, "Can't create an instance of the class Policy"
+
+
+ def Code(self):
+ 'Returns the string corresponding to a instancialization of the policy.'
+ pass
+
+
+ def _next(self):
+ if self.next is not None:
+ return ', %s >' % self.next.Code()
+ else:
+ return ' >'
+
+
+ def __eq__(self, other):
+ try:
+ return self.Code() == other.Code()
+ except AttributeError:
+ return False
+
+
+
+class return_internal_reference(Policy):
+ 'Ties the return value to one of the parameters.'
+
+ def __init__(self, param=1, next=None):
+ '''
+ param is the position of the parameter, or None for "self".
+ next indicates the next policy, or None.
+ '''
+ self.param = param
+ self.next=next
+
+
+ def Code(self):
+ c = 'return_internal_reference< %i' % self.param
+ c += self._next()
+ return c
+
+
+
+class with_custodian_and_ward(Policy):
+ 'Ties lifetime of two arguments of a function.'
+
+ def __init__(self, custodian, ward, next=None):
+ self.custodian = custodian
+ self.ward = ward
+ self.next = next
+
+ def Code(self):
+ c = 'with_custodian_and_ward< %i, %i' % (self.custodian, self.ward)
+ c += self._next()
+ return c
+
+
+
+class return_value_policy(Policy):
+ 'Policy to convert return values.'
+
+ def __init__(self, which, next=None):
+ self.which = which
+ self.next = next
+
+
+ def Code(self):
+ c = 'return_value_policy< %s' % self.which
+ c += self._next()
+ return c
+
+class return_self(Policy):
+
+ def Code(self):
+ return 'return_self<>'
+
+
+# values for return_value_policy
+reference_existing_object = 'reference_existing_object'
+copy_const_reference = 'copy_const_reference'
+copy_non_const_reference = 'copy_non_const_reference'
+manage_new_object = 'manage_new_object'
+return_opaque_pointer = 'return_opaque_pointer'
+return_by_value = 'return_by_value'
diff --git a/libs/python/pyste/src/Pyste/pyste.py b/libs/python/pyste/src/Pyste/pyste.py
new file mode 100644
index 000000000..cedffff55
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/pyste.py
@@ -0,0 +1,424 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+"""
+Pyste version %s
+
+Usage:
+ pyste [options] interface-files
+
+where options are:
+ --module=<name> The name of the module that will be generated;
+ defaults to the first interface filename, without
+ the extension.
+ -I <path> Add an include path
+ -D <symbol> Define symbol
+ --multiple Create various cpps, instead of only one
+ (useful during development)
+ --out=<name> Specify output filename (default: <module>.cpp)
+ in --multiple mode, this will be a directory
+ --no-using Do not declare "using namespace boost";
+ use explicit declarations instead
+ --pyste-ns=<name> Set the namespace where new types will be declared;
+ default is the empty namespace
+ --debug Writes the xml for each file parsed in the current
+ directory
+ --cache-dir=<dir> Directory for cache files (speeds up future runs)
+ --only-create-cache Recreates all caches (doesn't generate code).
+ --generate-main Generates the _main.cpp file (in multiple mode)
+ --file-list A file with one pyste file per line. Use as a
+ substitute for passing the files in the command
+ line.
+ --gccxml-path=<path> Path to gccxml executable (default: gccxml)
+ --no-default-include Do not use INCLUDE environment variable for include
+ files to pass along gccxml.
+ -h, --help Print this help and exit
+ -v, --version Print version information
+"""
+
+import sys
+import os
+import getopt
+import exporters
+import SingleCodeUnit
+import MultipleCodeUnit
+import infos
+import exporterutils
+import settings
+import gc
+import sys
+from policies import *
+from CppParser import CppParser, CppParserError
+import time
+import declarations
+
+__version__ = '0.9.30'
+
+def RecursiveIncludes(include):
+ 'Return a list containg the include dir and all its subdirectories'
+ dirs = [include]
+ def visit(arg, dir, names):
+ # ignore CVS dirs
+ if os.path.split(dir)[1] != 'CVS':
+ dirs.append(dir)
+ os.path.walk(include, visit, None)
+ return dirs
+
+
+def GetDefaultIncludes():
+ if 'INCLUDE' in os.environ:
+ include = os.environ['INCLUDE']
+ return include.split(os.pathsep)
+ else:
+ return []
+
+
+def ProcessIncludes(includes):
+ if sys.platform == 'win32':
+ index = 0
+ for include in includes:
+ includes[index] = include.replace('\\', '/')
+ index += 1
+
+
+def ReadFileList(filename):
+ f = file(filename)
+ files = []
+ try:
+ for line in f:
+ line = line.strip()
+ if line:
+ files.append(line)
+ finally:
+ f.close()
+ return files
+
+
+def ParseArguments():
+
+ def Usage():
+ print __doc__ % __version__
+ sys.exit(1)
+
+ try:
+ options, files = getopt.getopt(
+ sys.argv[1:],
+ 'R:I:D:vh',
+ ['module=', 'multiple', 'out=', 'no-using', 'pyste-ns=', 'debug', 'cache-dir=',
+ 'only-create-cache', 'version', 'generate-main', 'file-list=', 'help',
+ 'gccxml-path=', 'no-default-include'])
+ except getopt.GetoptError, e:
+ print
+ print 'ERROR:', e
+ Usage()
+
+ default_includes = GetDefaultIncludes()
+ includes = []
+ defines = []
+ module = None
+ out = None
+ multiple = False
+ cache_dir = None
+ create_cache = False
+ generate_main = False
+ gccxml_path = 'gccxml'
+
+ for opt, value in options:
+ if opt == '-I':
+ includes.append(value)
+ elif opt == '-D':
+ defines.append(value)
+ elif opt == '-R':
+ includes.extend(RecursiveIncludes(value))
+ elif opt == '--module':
+ module = value
+ elif opt == '--out':
+ out = value
+ elif opt == '--no-using':
+ settings.namespaces.python = 'boost::python::'
+ settings.USING_BOOST_NS = False
+ elif opt == '--pyste-ns':
+ settings.namespaces.pyste = value + '::'
+ elif opt == '--debug':
+ settings.DEBUG = True
+ elif opt == '--multiple':
+ multiple = True
+ elif opt == '--cache-dir':
+ cache_dir = value
+ elif opt == '--only-create-cache':
+ create_cache = True
+ elif opt == '--file-list':
+ files += ReadFileList(value)
+ elif opt in ['-h', '--help']:
+ Usage()
+ elif opt in ['-v', '--version']:
+ print 'Pyste version %s' % __version__
+ sys.exit(2)
+ elif opt == '--generate-main':
+ generate_main = True
+ elif opt == '--gccxml-path':
+ gccxml_path = value
+ elif opt == '--no-default-include':
+ default_includes = []
+ else:
+ print 'Unknown option:', opt
+ Usage()
+
+ includes[0:0] = default_includes
+ if not files:
+ Usage()
+ if not module:
+ module = os.path.splitext(os.path.basename(files[0]))[0]
+ if not out:
+ out = module
+ if not multiple:
+ out += '.cpp'
+ for file in files:
+ d = os.path.dirname(os.path.abspath(file))
+ if d not in sys.path:
+ sys.path.append(d)
+
+ if create_cache and not cache_dir:
+ print 'Error: Use --cache-dir to indicate where to create the cache files!'
+ Usage()
+ sys.exit(3)
+
+ if generate_main and not multiple:
+ print 'Error: --generate-main only valid in multiple mode.'
+ Usage()
+ sys.exit(3)
+
+ ProcessIncludes(includes)
+ return includes, defines, module, out, files, multiple, cache_dir, create_cache, \
+ generate_main, gccxml_path
+
+
+def PCHInclude(*headers):
+ code = '\n'.join(['#include <%s>' % x for x in headers])
+ infos.CodeInfo(code, 'pchinclude')
+
+
+def CreateContext():
+ 'create the context where a interface file will be executed'
+ context = {}
+ context['Import'] = Import
+ # infos
+ context['Function'] = infos.FunctionInfo
+ context['Class'] = infos.ClassInfo
+ context['Include'] = lambda header: infos.CodeInfo('#include <%s>\n' % header, 'include')
+ context['PCHInclude'] = PCHInclude
+ context['Template'] = infos.ClassTemplateInfo
+ context['Enum'] = infos.EnumInfo
+ context['AllFromHeader'] = infos.HeaderInfo
+ context['Var'] = infos.VarInfo
+ # functions
+ context['rename'] = infos.rename
+ context['set_policy'] = infos.set_policy
+ context['exclude'] = infos.exclude
+ context['set_wrapper'] = infos.set_wrapper
+ context['use_shared_ptr'] = infos.use_shared_ptr
+ context['use_auto_ptr'] = infos.use_auto_ptr
+ context['holder'] = infos.holder
+ context['add_method'] = infos.add_method
+ context['final'] = infos.final
+ context['export_values'] = infos.export_values
+ # policies
+ context['return_internal_reference'] = return_internal_reference
+ context['with_custodian_and_ward'] = with_custodian_and_ward
+ context['return_value_policy'] = return_value_policy
+ context['reference_existing_object'] = reference_existing_object
+ context['copy_const_reference'] = copy_const_reference
+ context['copy_non_const_reference'] = copy_non_const_reference
+ context['return_opaque_pointer'] = return_opaque_pointer
+ context['manage_new_object'] = manage_new_object
+ context['return_by_value'] = return_by_value
+ context['return_self'] = return_self
+ # utils
+ context['Wrapper'] = exporterutils.FunctionWrapper
+ context['declaration_code'] = lambda code: infos.CodeInfo(code, 'declaration-outside')
+ context['module_code'] = lambda code: infos.CodeInfo(code, 'module')
+ context['class_code'] = infos.class_code
+ return context
+
+
+def Begin():
+ # parse arguments
+ includes, defines, module, out, interfaces, multiple, cache_dir, create_cache, generate_main, gccxml_path = ParseArguments()
+ # run pyste scripts
+ for interface in interfaces:
+ ExecuteInterface(interface)
+ # create the parser
+ parser = CppParser(includes, defines, cache_dir, declarations.version, gccxml_path)
+ try:
+ if not create_cache:
+ if not generate_main:
+ return GenerateCode(parser, module, out, interfaces, multiple)
+ else:
+ return GenerateMain(module, out, OrderInterfaces(interfaces))
+ else:
+ return CreateCaches(parser)
+ finally:
+ parser.Close()
+
+
+def CreateCaches(parser):
+ # There is one cache file per interface so we organize the headers
+ # by interfaces. For each interface collect the tails from the
+ # exporters sharing the same header.
+ tails = JoinTails(exporters.exporters)
+
+ # now for each interface file take each header, and using the tail
+ # get the declarations and cache them.
+ for interface, header in tails:
+ tail = tails[(interface, header)]
+ declarations = parser.ParseWithGCCXML(header, tail)
+ cachefile = parser.CreateCache(header, interface, tail, declarations)
+ print 'Cached', cachefile
+
+ return 0
+
+
+_imported_count = {} # interface => count
+
+def ExecuteInterface(interface):
+ old_interface = exporters.current_interface
+ if not os.path.exists(interface):
+ if old_interface and os.path.exists(old_interface):
+ d = os.path.dirname(old_interface)
+ interface = os.path.join(d, interface)
+ if not os.path.exists(interface):
+ raise IOError, "Cannot find interface file %s."%interface
+
+ _imported_count[interface] = _imported_count.get(interface, 0) + 1
+ exporters.current_interface = interface
+ context = CreateContext()
+ context['INTERFACE_FILE'] = os.path.abspath(interface)
+ execfile(interface, context)
+ exporters.current_interface = old_interface
+
+
+def Import(interface):
+ exporters.importing = True
+ ExecuteInterface(interface)
+ exporters.importing = False
+
+
+def JoinTails(exports):
+ '''Returns a dict of {(interface, header): tail}, where tail is the
+ joining of all tails of all exports for the header.
+ '''
+ tails = {}
+ for export in exports:
+ interface = export.interface_file
+ header = export.Header()
+ tail = export.Tail() or ''
+ if (interface, header) in tails:
+ all_tails = tails[(interface,header)]
+ all_tails += '\n' + tail
+ tails[(interface, header)] = all_tails
+ else:
+ tails[(interface, header)] = tail
+
+ return tails
+
+
+
+def OrderInterfaces(interfaces):
+ interfaces_order = [(_imported_count[x], x) for x in interfaces]
+ interfaces_order.sort()
+ interfaces_order.reverse()
+ return [x for _, x in interfaces_order]
+
+
+
+def GenerateMain(module, out, interfaces):
+ codeunit = MultipleCodeUnit.MultipleCodeUnit(module, out)
+ codeunit.GenerateMain(interfaces)
+ return 0
+
+
+def GenerateCode(parser, module, out, interfaces, multiple):
+ # prepare to generate the wrapper code
+ if multiple:
+ codeunit = MultipleCodeUnit.MultipleCodeUnit(module, out)
+ else:
+ codeunit = SingleCodeUnit.SingleCodeUnit(module, out)
+ # stop referencing the exporters here
+ exports = exporters.exporters
+ exporters.exporters = None
+ exported_names = dict([(x.Name(), None) for x in exports])
+
+ # order the exports
+ order = {}
+ for export in exports:
+ if export.interface_file in order:
+ order[export.interface_file].append(export)
+ else:
+ order[export.interface_file] = [export]
+ exports = []
+ interfaces_order = OrderInterfaces(interfaces)
+ for interface in interfaces_order:
+ exports.extend(order[interface])
+ del order
+ del interfaces_order
+
+ # now generate the code in the correct order
+ #print exported_names
+ tails = JoinTails(exports)
+ for i in xrange(len(exports)):
+ export = exports[i]
+ interface = export.interface_file
+ header = export.Header()
+ if header:
+ tail = tails[(interface, header)]
+ declarations, parsed_header = parser.Parse(header, interface, tail)
+ else:
+ declarations = []
+ parsed_header = None
+ ExpandTypedefs(declarations, exported_names)
+ export.SetDeclarations(declarations)
+ export.SetParsedHeader(parsed_header)
+ if multiple:
+ codeunit.SetCurrent(export.interface_file, export.Name())
+ export.GenerateCode(codeunit, exported_names)
+ # force collect of cyclic references
+ exports[i] = None
+ del declarations
+ del export
+ gc.collect()
+ # finally save the code unit
+ codeunit.Save()
+ if not multiple:
+ print 'Module %s generated' % module
+ return 0
+
+
+def ExpandTypedefs(decls, exported_names):
+ '''Check if the names in exported_names are a typedef, and add the real class
+ name in the dict.
+ '''
+ for name in exported_names.keys():
+ for decl in decls:
+ if isinstance(decl, declarations.Typedef):
+ exported_names[decl.type.FullName()] = None
+
+def UsePsyco():
+ 'Tries to use psyco if possible'
+ try:
+ import psyco
+ psyco.profile()
+ except: pass
+
+
+def main():
+ start = time.clock()
+ UsePsyco()
+ status = Begin()
+ print '%0.2f seconds' % (time.clock()-start)
+ sys.exit(status)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/libs/python/pyste/src/Pyste/settings.py b/libs/python/pyste/src/Pyste/settings.py
new file mode 100644
index 000000000..ba613b234
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/settings.py
@@ -0,0 +1,21 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+
+#==============================================================================
+# Global information
+#==============================================================================
+
+DEBUG = False
+USING_BOOST_NS = True
+
+class namespaces:
+ boost = 'boost::'
+ pyste = ''
+ python = '' # default is to not use boost::python namespace explicitly, so
+ # use the "using namespace" statement instead
+
+import sys
+msvc = sys.platform == 'win32'
diff --git a/libs/python/pyste/src/Pyste/utils.py b/libs/python/pyste/src/Pyste/utils.py
new file mode 100644
index 000000000..a8843e3f6
--- /dev/null
+++ b/libs/python/pyste/src/Pyste/utils.py
@@ -0,0 +1,78 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+from __future__ import generators
+import string
+import sys
+
+#==============================================================================
+# enumerate
+#==============================================================================
+def enumerate(seq):
+ i = 0
+ for x in seq:
+ yield i, x
+ i += 1
+
+
+#==============================================================================
+# makeid
+#==============================================================================
+_valid_chars = string.ascii_letters + string.digits + '_'
+_valid_chars = dict(zip(_valid_chars, _valid_chars))
+
+def makeid(name):
+ 'Returns the name as a valid identifier'
+ if type(name) != str:
+ print type(name), name
+ newname = []
+ for char in name:
+ if char not in _valid_chars:
+ char = '_'
+ newname.append(char)
+ newname = ''.join(newname)
+ # avoid duplications of '_' chars
+ names = [x for x in newname.split('_') if x]
+ return '_'.join(names)
+
+
+#==============================================================================
+# remove_duplicated_lines
+#==============================================================================
+def remove_duplicated_lines(text):
+ includes = text.splitlines()
+ d = dict([(include, 0) for include in includes])
+ includes = d.keys()
+ includes.sort()
+ return '\n'.join(includes)
+
+
+#==============================================================================
+# left_equals
+#==============================================================================
+def left_equals(s):
+ s = '// %s ' % s
+ return s + ('='*(80-len(s))) + '\n'
+
+
+#==============================================================================
+# post_mortem
+#==============================================================================
+def post_mortem():
+
+ def info(type, value, tb):
+ if hasattr(sys, 'ps1') or not sys.stderr.isatty():
+ # we are in interactive mode or we don't have a tty-like
+ # device, so we call the default hook
+ sys.__excepthook__(type, value, tb)
+ else:
+ import traceback, pdb
+ # we are NOT in interactive mode, print the exception...
+ traceback.print_exception(type, value, tb)
+ print
+ # ...then start the debugger in post-mortem mode.
+ pdb.pm()
+
+ sys.excepthook = info
diff --git a/libs/python/pyste/tests/GCCXMLParserUT.py b/libs/python/pyste/tests/GCCXMLParserUT.py
new file mode 100644
index 000000000..7175c9c68
--- /dev/null
+++ b/libs/python/pyste/tests/GCCXMLParserUT.py
@@ -0,0 +1,341 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import sys
+sys.path.append('../src')
+import unittest
+import tempfile
+import os.path
+from Pyste import GCCXMLParser
+from Pyste.declarations import *
+
+
+class Tester(unittest.TestCase):
+
+ def TestConstructor(self, class_, method, visib):
+ self.assert_(isinstance(method, Constructor))
+ self.assertEqual(method.FullName(), class_.FullName() + '::' + method.name)
+ self.assertEqual(method.result, None)
+ self.assertEqual(method.visibility, visib)
+ self.assert_(not method.virtual)
+ self.assert_(not method.abstract)
+ self.assert_(not method.static)
+
+ def TestDefaultConstructor(self, class_, method, visib):
+ self.TestConstructor(class_, method, visib)
+ self.assert_(method.IsDefault())
+
+ def TestCopyConstructor(self, class_, method, visib):
+ self.TestConstructor(class_, method, visib)
+ self.assertEqual(len(method.parameters), 1)
+ param = method.parameters[0]
+ self.TestType(
+ param,
+ ReferenceType,
+ class_.FullName(),
+ 'const %s&' % class_.FullName(),
+ True)
+ self.assert_(method.IsCopy())
+
+
+ def TestType(self, type_, classtype_, name, fullname, const):
+ self.assert_(isinstance(type_, classtype_))
+ self.assertEqual(type_.name, name)
+ self.assertEqual(type_.namespace, None)
+ self.assertEqual(type_.FullName(), fullname)
+ self.assertEqual(type_.const, const)
+
+
+class ClassBaseTest(Tester):
+
+ def setUp(self):
+ self.base = GetDecl('Base')
+
+ def testClass(self):
+ 'test the properties of the class Base'
+ self.assert_(isinstance(self.base, Class))
+ self.assert_(self.base.abstract)
+
+
+ def testFoo(self):
+ 'test function foo in class Base'
+ foo = GetMember(self.base, 'foo')
+ self.assert_(isinstance(foo, Method))
+ self.assertEqual(foo.visibility, Scope.public)
+ self.assert_(foo.virtual)
+ self.assert_(foo.abstract)
+ self.failIf(foo.static)
+ self.assertEqual(foo.class_, 'test::Base')
+ self.failIf(foo.const)
+ self.assertEqual(foo.FullName(), 'test::Base::foo')
+ self.assertEqual(foo.result.name, 'void')
+ self.assertEqual(len(foo.parameters), 1)
+ param = foo.parameters[0]
+ self.TestType(param, FundamentalType, 'int', 'int', False)
+ self.assertEqual(foo.namespace, None)
+ self.assertEqual(
+ foo.PointerDeclaration(1), '(void (test::Base::*)(int) )&test::Base::foo')
+
+ def testX(self):
+ 'test the member x in class Base'
+ x = GetMember(self.base, 'x')
+ self.assertEqual(x.class_, 'test::Base')
+ self.assertEqual(x.FullName(), 'test::Base::x')
+ self.assertEqual(x.namespace, None)
+ self.assertEqual(x.visibility, Scope.private)
+ self.TestType(x.type, FundamentalType, 'int', 'int', False)
+ self.assertEqual(x.static, False)
+
+ def testConstructors(self):
+ 'test constructors in class Base'
+ constructors = GetMembers(self.base, 'Base')
+ for cons in constructors:
+ if len(cons.parameters) == 0:
+ self.TestDefaultConstructor(self.base, cons, Scope.public)
+ elif len(cons.parameters) == 1: # copy constructor
+ self.TestCopyConstructor(self.base, cons, Scope.public)
+ elif len(cons.parameters) == 2: # other constructor
+ intp, floatp = cons.parameters
+ self.TestType(intp, FundamentalType, 'int', 'int', False)
+ self.TestType(floatp, FundamentalType, 'float', 'float', False)
+
+ def testSimple(self):
+ 'test function simple in class Base'
+ simple = GetMember(self.base, 'simple')
+ self.assert_(isinstance(simple, Method))
+ self.assertEqual(simple.visibility, Scope.protected)
+ self.assertEqual(simple.FullName(), 'test::Base::simple')
+ self.assertEqual(len(simple.parameters), 1)
+ param = simple.parameters[0]
+ self.TestType(param, ReferenceType, 'std::string', 'const std::string&', True)
+ self.TestType(simple.result, FundamentalType, 'bool', 'bool', False)
+ self.assertEqual(
+ simple.PointerDeclaration(1),
+ '(bool (test::Base::*)(const std::string&) )&test::Base::simple')
+
+
+ def testZ(self):
+ z = GetMember(self.base, 'z')
+ self.assert_(isinstance(z, Variable))
+ self.assertEqual(z.visibility, Scope.public)
+ self.assertEqual(z.FullName(), 'test::Base::z')
+ self.assertEqual(z.type.name, 'int')
+ self.assertEqual(z.type.const, False)
+ self.assert_(z.static)
+
+
+class ClassTemplateTest(Tester):
+
+ def setUp(self):
+ self.template = GetDecl('Template<int>')
+
+ def testClass(self):
+ 'test the properties of the Template<int> class'
+ self.assert_(isinstance(self.template, Class))
+ self.assert_(not self.template.abstract)
+ self.assertEqual(self.template.FullName(), 'Template<int>')
+ self.assertEqual(self.template.namespace, '')
+ self.assertEqual(self.template.name, 'Template<int>')
+
+ def testConstructors(self):
+ 'test the automatic constructors of the class Template<int>'
+ constructors = GetMembers(self.template, 'Template')
+ for cons in constructors:
+ if len(cons.parameters) == 0:
+ self.TestDefaultConstructor(self.template, cons, Scope.public)
+ elif len(cons.parameters) == 1:
+ self.TestCopyConstructor(self.template, cons, Scope.public)
+
+
+ def testValue(self):
+ 'test the class variable value'
+ value = GetMember(self.template, 'value')
+ self.assert_(isinstance(value, ClassVariable))
+ self.assert_(value.name, 'value')
+ self.TestType(value.type, FundamentalType, 'int', 'int', False)
+ self.assert_(not value.static)
+ self.assertEqual(value.visibility, Scope.public)
+ self.assertEqual(value.class_, 'Template<int>')
+ self.assertEqual(value.FullName(), 'Template<int>::value')
+
+ def testBase(self):
+ 'test the superclasses of Template<int>'
+ bases = self.template.bases
+ self.assertEqual(len(bases), 1)
+ base = bases[0]
+ self.assert_(isinstance(base, Base))
+ self.assertEqual(base.name, 'test::Base')
+ self.assertEqual(base.visibility, Scope.protected)
+
+
+
+class FreeFuncTest(Tester):
+
+ def setUp(self):
+ self.func = GetDecl('FreeFunc')
+
+ def testFunc(self):
+ 'test attributes of FreeFunc'
+ self.assert_(isinstance(self.func, Function))
+ self.assertEqual(self.func.name, 'FreeFunc')
+ self.assertEqual(self.func.FullName(), 'test::FreeFunc')
+ self.assertEqual(self.func.namespace, 'test')
+ self.assertEqual(
+ self.func.PointerDeclaration(1),
+ '(const test::Base& (*)(const std::string&, int))&test::FreeFunc')
+
+
+ def testResult(self):
+ 'test the return value of FreeFunc'
+ res = self.func.result
+ self.TestType(res, ReferenceType, 'test::Base', 'const test::Base&', True)
+
+ def testParameters(self):
+ 'test the parameters of FreeFunc'
+ self.assertEqual(len(self.func.parameters), 2)
+ strp, intp = self.func.parameters
+ self.TestType(strp, ReferenceType, 'std::string', 'const std::string&', True)
+ self.assertEqual(strp.default, None)
+ self.TestType(intp, FundamentalType, 'int', 'int', False)
+ self.assertEqual(intp.default, '10')
+
+
+
+class testFunctionPointers(Tester):
+
+ def testMethodPointer(self):
+ 'test declaration of a pointer-to-method'
+ meth = GetDecl('MethodTester')
+ param = meth.parameters[0]
+ fullname = 'void (test::Base::*)(int)'
+ self.TestType(param, PointerType, fullname, fullname, False)
+
+ def testFunctionPointer(self):
+ 'test declaration of a pointer-to-function'
+ func = GetDecl('FunctionTester')
+ param = func.parameters[0]
+ fullname = 'void (*)(int)'
+ self.TestType(param, PointerType, fullname, fullname, False)
+
+
+
+# =============================================================================
+# Support routines
+# =============================================================================
+
+cppcode = '''
+namespace std {
+ class string;
+}
+namespace test {
+class Base
+{
+public:
+ Base();
+ Base(const Base&);
+ Base(int, float);
+
+ virtual void foo(int = 0.0) = 0;
+ static int z;
+protected:
+ bool simple(const std::string&);
+private:
+ int x;
+};
+
+void MethodTester( void (Base::*)(int) );
+void FunctionTester( void (*)(int) );
+
+
+const Base & FreeFunc(const std::string&, int=10);
+
+}
+
+template <class T>
+struct Template: protected test::Base
+{
+ T value;
+ virtual void foo(int);
+};
+
+Template<int> __aTemplateInt;
+'''
+
+def GetXMLFile():
+ '''Generates an gccxml file using the code from the global cppcode.
+ Returns the xml's filename.'''
+ # write the code to a header file
+ tmpfile = tempfile.mktemp() + '.h'
+ f = file(tmpfile, 'w')
+ f.write(cppcode)
+ f.close()
+ # run gccxml
+ outfile = tmpfile + '.xml'
+ if os.system('gccxml "%s" "-fxml=%s"' % (tmpfile, outfile)) != 0:
+ raise RuntimeError, 'Error executing GCCXML.'
+ # read the output file into the xmlcode
+ f = file(outfile)
+ xmlcode = f.read()
+ #print xmlcode
+ f.close()
+ # remove the header
+ os.remove(tmpfile)
+ return outfile
+
+
+
+def GetDeclarations():
+ 'Uses the GCCXMLParser module to get the declarations.'
+ xmlfile = GetXMLFile()
+ declarations = GCCXMLParser.ParseDeclarations(xmlfile)
+ os.remove(xmlfile)
+ return declarations
+
+# the declarations to be analysed
+declarations = GetDeclarations()
+
+
+def GetDecl(name):
+ 'returns one of the top declarations given its name'
+ for decl in declarations:
+ if decl.name == name:
+ return decl
+ else:
+ raise RuntimeError, 'Declaration not found: %s' % name
+
+
+def GetMember(class_, name):
+ 'gets the member of the given class by its name'
+
+ res = None
+ multipleFound = False
+ for member in class_:
+ if member.name == name:
+ if res is not None:
+ multipleFound = True
+ break
+ res = member
+ if res is None or multipleFound:
+ raise RuntimeError, \
+ 'No member or more than one member found in class %s: %s' \
+ % (class_.name, name)
+ return res
+
+
+def GetMembers(class_, name):
+ 'gets the members of the given class by its name'
+ res = []
+ for member in class_:
+ if member.name == name:
+ res.append(member)
+ if len(res) in (0, 1):
+ raise RuntimeError, \
+ 'GetMembers: 0 or 1 members found in class %s: %s' \
+ % (class_.name, name)
+ return res
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/SmartFileUT.py b/libs/python/pyste/tests/SmartFileUT.py
new file mode 100644
index 000000000..9e4e99883
--- /dev/null
+++ b/libs/python/pyste/tests/SmartFileUT.py
@@ -0,0 +1,84 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import sys
+sys.path.append('../src')
+from SmartFile import *
+import unittest
+import tempfile
+import os
+import time
+
+
+class SmartFileTest(unittest.TestCase):
+
+ FILENAME = tempfile.mktemp()
+
+ def setUp(self):
+ self._Clean()
+
+ def tearDown(self):
+ self._Clean()
+
+ def _Clean(self):
+ try:
+ os.remove(self.FILENAME)
+ except OSError: pass
+
+
+ def testNonExistant(self):
+ "Must override the file, as there's no file in the disk yet"
+ self.assert_(not os.path.isfile(self.FILENAME))
+ f = SmartFile(self.FILENAME, 'w')
+ f.write('Testing 123\nTesting again.')
+ f.close()
+ self.assert_(os.path.isfile(self.FILENAME))
+
+
+ def testOverride(self):
+ "Must override the file, because the contents are different"
+ contents = 'Contents!\nContents!'
+ # create the file normally first
+ f = file(self.FILENAME, 'w')
+ f.write(contents)
+ f.close()
+ file_time = os.path.getmtime(self.FILENAME)
+ self.assert_(os.path.isfile(self.FILENAME))
+ time.sleep(2)
+ f = SmartFile(self.FILENAME, 'w')
+ f.write(contents + '_')
+ f.close()
+ new_file_time = os.path.getmtime(self.FILENAME)
+ self.assert_(new_file_time != file_time)
+
+
+ def testNoOverride(self):
+ "Must not override the file, because the contents are the same"
+ contents = 'Contents!\nContents!'
+ # create the file normally first
+ f = file(self.FILENAME, 'w')
+ f.write(contents)
+ f.close()
+ file_time = os.path.getmtime(self.FILENAME)
+ self.assert_(os.path.isfile(self.FILENAME))
+ time.sleep(2)
+ f = SmartFile(self.FILENAME, 'w')
+ f.write(contents)
+ f.close()
+ new_file_time = os.path.getmtime(self.FILENAME)
+ self.assert_(new_file_time == file_time)
+
+
+ def testAutoClose(self):
+ "Must be closed when garbage-collected"
+ def foo():
+ f = SmartFile(self.FILENAME)
+ f.write('testing')
+ self.assert_(not os.path.isfile(self.FILENAME))
+ foo()
+ self.assert_(os.path.isfile(self.FILENAME))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/abstract_test.h b/libs/python/pyste/tests/abstract_test.h
new file mode 100644
index 000000000..e0fba2b24
--- /dev/null
+++ b/libs/python/pyste/tests/abstract_test.h
@@ -0,0 +1,22 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include <vector>
+#include <string>
+
+namespace abstract {
+
+struct A {
+ virtual ~A() {}
+ virtual std::string f()=0;
+};
+
+struct B: A {
+ std::string f() { return "B::f"; }
+};
+
+std::string call(A* a) { return a->f(); }
+
+}
diff --git a/libs/python/pyste/tests/abstract_test.pyste b/libs/python/pyste/tests/abstract_test.pyste
new file mode 100644
index 000000000..c65bb3ad6
--- /dev/null
+++ b/libs/python/pyste/tests/abstract_test.pyste
@@ -0,0 +1,3 @@
+Class('abstract::A', 'abstract_test.h')
+Class('abstract::B', 'abstract_test.h')
+Function('abstract::call', 'abstract_test.h')
diff --git a/libs/python/pyste/tests/abstract_testUT.py b/libs/python/pyste/tests/abstract_testUT.py
new file mode 100644
index 000000000..4dc61a262
--- /dev/null
+++ b/libs/python/pyste/tests/abstract_testUT.py
@@ -0,0 +1,26 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _abstract_test import *
+
+class AbstractTest(unittest.TestCase):
+
+ def testIt(self):
+ class C(A):
+ def f(self):
+ return 'C::f'
+
+ a = A()
+ b = B()
+ c = C()
+ self.assertRaises(RuntimeError, a.f)
+ self.assertEqual(b.f(), 'B::f')
+ self.assertEqual(call(b), 'B::f')
+ self.assertEqual(c.f(), 'C::f')
+ self.assertEqual(call(c), 'C::f')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/add_test.h b/libs/python/pyste/tests/add_test.h
new file mode 100644
index 000000000..447e8814c
--- /dev/null
+++ b/libs/python/pyste/tests/add_test.h
@@ -0,0 +1,18 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+namespace add_test {
+
+struct C
+{
+ int x;
+};
+
+const int get_x(C& c)
+{
+ return c.x;
+}
+
+}
diff --git a/libs/python/pyste/tests/add_test.pyste b/libs/python/pyste/tests/add_test.pyste
new file mode 100644
index 000000000..cc7faa9ed
--- /dev/null
+++ b/libs/python/pyste/tests/add_test.pyste
@@ -0,0 +1,2 @@
+C = Class('add_test::C', 'add_test.h')
+add_method(C, 'add_test::get_x')
diff --git a/libs/python/pyste/tests/add_testUT.py b/libs/python/pyste/tests/add_testUT.py
new file mode 100644
index 000000000..16f57a320
--- /dev/null
+++ b/libs/python/pyste/tests/add_testUT.py
@@ -0,0 +1,16 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _add_test import *
+
+class AddMethodTest(unittest.TestCase):
+
+ def testIt(self):
+ c = C()
+ c.x = 10
+ self.assertEqual(c.get_x(), 10)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/basic.cpp b/libs/python/pyste/tests/basic.cpp
new file mode 100644
index 000000000..d07b6da62
--- /dev/null
+++ b/libs/python/pyste/tests/basic.cpp
@@ -0,0 +1,13 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "basic.h"
+
+namespace basic {
+
+ int C::static_value = 3;
+ const int C::const_static_value = 100;
+
+}
diff --git a/libs/python/pyste/tests/basic.h b/libs/python/pyste/tests/basic.h
new file mode 100644
index 000000000..690fed2d3
--- /dev/null
+++ b/libs/python/pyste/tests/basic.h
@@ -0,0 +1,69 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BASIC_H
+#define BASIC_H
+
+
+#include <string>
+
+namespace basic {
+
+struct C
+{
+ // test virtuallity
+ C(): value(1), const_value(0) {}
+ virtual int f(int x = 10)
+ {
+ return x*2;
+ }
+
+ int foo(int x=1){
+ return x+1;
+ }
+
+ const std::string& get_name() { return name; }
+ void set_name(const std::string& name) { this->name = name; }
+private:
+ std::string name;
+
+public:
+ // test data members
+ static int static_value;
+ static const int const_static_value;
+
+ int value;
+ const int const_value;
+
+ // test static functions
+ static int mul(int x, int y) { return x*y; }
+ static double mul(double x, double y) { return x*y; }
+
+ static int square(int x=2) { return x*x; }
+};
+
+inline int call_f(C& c)
+{
+ return c.f();
+}
+
+inline int call_f(C& c, int x)
+{
+ return c.f(x);
+}
+
+inline int get_static()
+{
+ return C::static_value;
+}
+
+inline int get_value(C& c)
+{
+ return c.value;
+}
+
+}
+
+#endif
diff --git a/libs/python/pyste/tests/basic.pyste b/libs/python/pyste/tests/basic.pyste
new file mode 100644
index 000000000..4fe0b5b31
--- /dev/null
+++ b/libs/python/pyste/tests/basic.pyste
@@ -0,0 +1,5 @@
+Class('basic::C', 'basic.h')
+Function('basic::call_f', 'basic.h')
+Function('basic::get_static', 'basic.h')
+Function('basic::get_value', 'basic.h')
+
diff --git a/libs/python/pyste/tests/basicUT.py b/libs/python/pyste/tests/basicUT.py
new file mode 100644
index 000000000..9a18bcbf3
--- /dev/null
+++ b/libs/python/pyste/tests/basicUT.py
@@ -0,0 +1,73 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _basic import *
+
+class BasicExampleTest(unittest.TestCase):
+
+ def testIt(self):
+
+ # test virtual functions
+ class D(C):
+ def f(self, x=10):
+ return x+1
+
+ d = D()
+ c = C()
+
+ self.assertEqual(c.f(), 20)
+ self.assertEqual(c.f(3), 6)
+ self.assertEqual(d.f(), 11)
+ self.assertEqual(d.f(3), 4)
+ self.assertEqual(call_f(c), 20)
+ self.assertEqual(call_f(c, 4), 8)
+ self.assertEqual(call_f(d), 11)
+ self.assertEqual(call_f(d, 3), 4)
+
+ # test data members
+ def testValue(value):
+ self.assertEqual(c.value, value)
+ self.assertEqual(d.value, value)
+ self.assertEqual(get_value(c), value)
+ self.assertEqual(get_value(d), value)
+ testValue(1)
+ c.value = 30
+ d.value = 30
+ testValue(30)
+ self.assertEqual(c.const_value, 0)
+ self.assertEqual(d.const_value, 0)
+ def set_const_value():
+ c.const_value = 12
+ self.assertRaises(AttributeError, set_const_value)
+
+ # test static data-members
+ def testStatic(value):
+ self.assertEqual(C.static_value, value)
+ self.assertEqual(c.static_value, value)
+ self.assertEqual(D.static_value, value)
+ self.assertEqual(d.static_value, value)
+ self.assertEqual(get_static(), value)
+ testStatic(3)
+ C.static_value = 10
+ testStatic(10)
+ self.assertEqual(C.const_static_value, 100)
+ def set_const_static():
+ C.const_static_value = 1
+ self.assertRaises(AttributeError, set_const_static)
+
+ # test static function
+ def test_mul(result, *args):
+ self.assertEqual(C.mul(*args), result)
+ self.assertEqual(c.mul(*args), result)
+ test_mul(16, 8, 2)
+ test_mul(6.0, 2.0, 3.0)
+ self.assertEqual(C.square(), 4)
+ self.assertEqual(c.square(), 4)
+ self.assertEqual(C.square(3), 9)
+ self.assertEqual(c.square(3), 9)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/code_test.h b/libs/python/pyste/tests/code_test.h
new file mode 100644
index 000000000..0a31205a3
--- /dev/null
+++ b/libs/python/pyste/tests/code_test.h
@@ -0,0 +1,8 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+struct A {
+ int x;
+};
diff --git a/libs/python/pyste/tests/code_test.pyste b/libs/python/pyste/tests/code_test.pyste
new file mode 100644
index 000000000..467996fdb
--- /dev/null
+++ b/libs/python/pyste/tests/code_test.pyste
@@ -0,0 +1,9 @@
+Class('A', 'code_test.h')
+Include('string')
+declaration_code('''
+int get(A& a) { return a.x; }
+
+std::string foo() { return "Hello!"; }
+''')
+module_code(' def("get", &get);\n')
+module_code(' def("foo", &foo);\n')
diff --git a/libs/python/pyste/tests/code_testUT.py b/libs/python/pyste/tests/code_testUT.py
new file mode 100644
index 000000000..1059570aa
--- /dev/null
+++ b/libs/python/pyste/tests/code_testUT.py
@@ -0,0 +1,18 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _code_test import *
+
+class CodeTest(unittest.TestCase):
+
+ def testIt(self):
+ a = A()
+ a.x = 12
+ self.assertEqual(get(a), 12)
+ self.assertEqual(foo(), "Hello!")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/enums.h b/libs/python/pyste/tests/enums.h
new file mode 100644
index 000000000..afe33ca48
--- /dev/null
+++ b/libs/python/pyste/tests/enums.h
@@ -0,0 +1,34 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef ENUMS_H
+#define ENUMS_H
+
+namespace enums {
+
+enum color { red, blue };
+
+struct X
+{
+ enum choices
+ {
+ good = 1,
+ bad = 2
+ };
+
+ int set(choices c)
+ {
+ return (int)c;
+ }
+};
+
+enum {
+ x = 0,
+ y = 1
+};
+
+}
+
+#endif
diff --git a/libs/python/pyste/tests/enums.pyste b/libs/python/pyste/tests/enums.pyste
new file mode 100644
index 000000000..c18a1244f
--- /dev/null
+++ b/libs/python/pyste/tests/enums.pyste
@@ -0,0 +1,8 @@
+h = AllFromHeader('enums.h')
+rename(h.color.red, 'Red')
+rename(h.color.blue, 'Blue')
+export_values(h.color)
+rename(h.X.choices.bad, 'Bad')
+rename(h.X.choices.good, 'Good')
+rename(h.X.choices, 'Choices')
+
diff --git a/libs/python/pyste/tests/enumsUT.py b/libs/python/pyste/tests/enumsUT.py
new file mode 100644
index 000000000..7c7720dcb
--- /dev/null
+++ b/libs/python/pyste/tests/enumsUT.py
@@ -0,0 +1,24 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _enums import *
+
+class EnumsTest(unittest.TestCase):
+
+ def testIt(self):
+ self.assertEqual(int(Red), 0)
+ self.assertEqual(int(Blue), 1)
+
+ self.assertEqual(int(X.Choices.Good), 1)
+ self.assertEqual(int(X.Choices.Bad), 2)
+ a = X()
+ self.assertEqual(a.set(a.Choices.Good), 1)
+ self.assertEqual(a.set(a.Choices.Bad), 2)
+ self.assertEqual(x, 0)
+ self.assertEqual(y, 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/header_test.h b/libs/python/pyste/tests/header_test.h
new file mode 100644
index 000000000..030d0d26c
--- /dev/null
+++ b/libs/python/pyste/tests/header_test.h
@@ -0,0 +1,43 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef HEADER_TEST_H
+#define HEADER_TEST_H
+
+#include <map>
+#include <string>
+
+namespace header_test {
+
+enum choice { red, blue };
+
+inline std::string choice_str(choice c)
+{
+ std::map<choice, std::string> choice_map;
+ choice_map[red] = "red";
+ choice_map[blue] = "blue";
+ return choice_map[c];
+}
+
+struct C
+{
+ choice c;
+
+ std::string get()
+ {
+ return choice_str(c);
+ }
+};
+
+// test the exclusion of the following
+
+struct ForwardDeclared; // should be excluded automatically
+struct A {};
+void foo();
+enum bar { value };
+
+}
+
+#endif
diff --git a/libs/python/pyste/tests/header_test.pyste b/libs/python/pyste/tests/header_test.pyste
new file mode 100644
index 000000000..3bd55501c
--- /dev/null
+++ b/libs/python/pyste/tests/header_test.pyste
@@ -0,0 +1,4 @@
+h = AllFromHeader('header_test.h')
+exclude(h.A)
+exclude(h.foo)
+exclude(h.bar)
diff --git a/libs/python/pyste/tests/header_testUT.py b/libs/python/pyste/tests/header_testUT.py
new file mode 100644
index 000000000..aa0d4a16f
--- /dev/null
+++ b/libs/python/pyste/tests/header_testUT.py
@@ -0,0 +1,27 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _header_test import *
+
+class HeaderTest(unittest.TestCase):
+
+ def testIt(self):
+ self.assertEqual(choice.red, 0)
+ self.assertEqual(choice.blue, 1)
+ self.assertEqual(choice_str(choice.blue), 'blue')
+ self.assertEqual(choice_str(choice.red), 'red')
+ c = C()
+ c.c = choice.blue
+ self.assertEqual(c.get(), 'blue')
+ c.c = choice.red
+ self.assertEqual(c.get(), 'red')
+ # the following classes/functions should not have being exported
+ self.assertRaises(NameError, lambda: A())
+ self.assertRaises(NameError, lambda: foo())
+ self.assertRaises(NameError, lambda: bar.value)
+ self.assertRaises(NameError, lambda: ForwardDeclared())
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/infosUT.py b/libs/python/pyste/tests/infosUT.py
new file mode 100644
index 000000000..93769f34e
--- /dev/null
+++ b/libs/python/pyste/tests/infosUT.py
@@ -0,0 +1,55 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import sys
+from Pyste.infos import *
+from Pyste.policies import *
+from Pyste.exporterutils import *
+import unittest
+
+#================================================================================
+# InfosTest
+#================================================================================
+class InfosTest(unittest.TestCase):
+
+ def testFunctionInfo(self):
+ info = FunctionInfo('test::foo', 'foo.h')
+ rename(info, 'hello')
+ set_policy(info, return_internal_reference())
+ set_wrapper(info, FunctionWrapper('foo_wrapper'))
+
+ info = InfoWrapper(info)
+
+ self.assertEqual(info.rename, 'hello')
+ self.assertEqual(info.policy.Code(), 'return_internal_reference< 1 >')
+ self.assertEqual(info.wrapper.name, 'foo_wrapper')
+
+
+ def testClassInfo(self):
+ info = ClassInfo('test::IFoo', 'foo.h')
+ rename(info.name, 'Name')
+ rename(info.exclude, 'Exclude')
+ rename(info, 'Foo')
+ rename(info.Bar, 'bar')
+ set_policy(info.Baz, return_internal_reference())
+ rename(info.operator['>>'], 'from_string')
+ exclude(info.Bar)
+ set_wrapper(info.Baz, FunctionWrapper('baz_wrapper'))
+
+ info = InfoWrapper(info)
+
+ self.assertEqual(info.rename, 'Foo')
+ self.assertEqual(info['Bar'].rename, 'bar')
+ self.assertEqual(info['name'].rename, 'Name')
+ self.assertEqual(info['exclude'].rename, 'Exclude')
+ self.assertEqual(info['Bar'].exclude, True)
+ self.assertEqual(info['Baz'].policy.Code(), 'return_internal_reference< 1 >')
+ self.assertEqual(info['Baz'].wrapper.name, 'baz_wrapper')
+ self.assertEqual(info['operator']['>>'].rename, 'from_string')
+
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/inherit.cpp b/libs/python/pyste/tests/inherit.cpp
new file mode 100644
index 000000000..a75e83891
--- /dev/null
+++ b/libs/python/pyste/tests/inherit.cpp
@@ -0,0 +1,8 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "inherit.h"
+
+int inherit::C::s = 1;
diff --git a/libs/python/pyste/tests/inherit.h b/libs/python/pyste/tests/inherit.h
new file mode 100644
index 000000000..8f903f4fd
--- /dev/null
+++ b/libs/python/pyste/tests/inherit.h
@@ -0,0 +1,43 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+namespace inherit {
+
+template<typename T>
+class A
+{
+public:
+ void set(T v) { mData = v; }
+
+ T get() const { return mData; }
+
+private:
+ T mData;
+};
+
+
+class B : public A<int>
+{
+public:
+ int go() { return get(); }
+};
+
+struct C : B
+{
+ enum ab { a = 1, b = 2 };
+ int f1() { return 1; }
+ int x;
+ static int s;
+};
+
+struct D : C
+{
+ int f2() { return 2; }
+ int y;
+};
+
+struct X {};
+struct E: X, D {};
+}
diff --git a/libs/python/pyste/tests/inherit.pyste b/libs/python/pyste/tests/inherit.pyste
new file mode 100644
index 000000000..0dc029989
--- /dev/null
+++ b/libs/python/pyste/tests/inherit.pyste
@@ -0,0 +1,8 @@
+A = Template('inherit::A', 'inherit.h')
+A_int = A('int', 'A_int')
+
+Class('inherit::B', 'inherit.h')
+Class('inherit::D', 'inherit.h')
+E = Class('inherit::E', 'inherit.h')
+exclude(E.s)
+exclude(E.ab)
diff --git a/libs/python/pyste/tests/inherit2.h b/libs/python/pyste/tests/inherit2.h
new file mode 100644
index 000000000..af9387bd0
--- /dev/null
+++ b/libs/python/pyste/tests/inherit2.h
@@ -0,0 +1,35 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+namespace inherit2 {
+
+struct A
+{
+ int x;
+ int getx() { return x; }
+ int foo() { return 0; }
+ int foo(int x) { return x; }
+};
+
+struct B : A
+{
+ int y;
+ int gety() { return y; }
+ int foo() { return 1; }
+};
+
+struct C : B
+{
+ int z;
+ int getz() { return z; }
+};
+
+struct D : C
+{
+ int w;
+ int getw() { return w; }
+};
+
+}
diff --git a/libs/python/pyste/tests/inherit2.pyste b/libs/python/pyste/tests/inherit2.pyste
new file mode 100644
index 000000000..380821398
--- /dev/null
+++ b/libs/python/pyste/tests/inherit2.pyste
@@ -0,0 +1,2 @@
+Class('inherit2::B', 'inherit2.h')
+Class('inherit2::D', 'inherit2.h')
diff --git a/libs/python/pyste/tests/inherit2UT.py b/libs/python/pyste/tests/inherit2UT.py
new file mode 100644
index 000000000..85afce617
--- /dev/null
+++ b/libs/python/pyste/tests/inherit2UT.py
@@ -0,0 +1,31 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _inherit2 import *
+
+class InheritExampleTest(unittest.TestCase):
+
+ def testIt(self):
+ b = B()
+ d = D()
+
+ self.assert_(issubclass(D, B))
+ b.x, b.y = 10, 5
+ self.assertEqual(b.getx(), 10)
+ self.assertEqual(b.gety(), 5)
+ d.x, d.y, d.z, d.w = 20, 15, 10, 5
+ self.assertEqual(d.getx(), 20)
+ self.assertEqual(d.gety(), 15)
+ self.assertEqual(d.getz(), 10)
+ self.assertEqual(d.getw(), 5)
+ self.assertEqual(b.foo(), 1)
+ self.assertEqual(b.foo(3), 3)
+
+ def wrong():
+ return b.getw()
+ self.assertRaises(AttributeError, wrong)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/inherit3.h b/libs/python/pyste/tests/inherit3.h
new file mode 100644
index 000000000..1945fb514
--- /dev/null
+++ b/libs/python/pyste/tests/inherit3.h
@@ -0,0 +1,46 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+namespace inherit3 {
+
+struct A
+{
+ A() { x = 0; }
+ struct X { int y; };
+ int x;
+ virtual int foo() { return 0; }
+ virtual int foo(int x) { return x; }
+ A operator+(A o) const
+ {
+ A r;
+ r.x = o.x + x;
+ return r;
+ }
+ enum E { i, j };
+
+};
+
+struct B: A
+{
+ B() { x = 0; }
+ struct X { int y; };
+ int x;
+ int foo() { return 1; }
+ A operator+(A o) const
+ {
+ A r;
+ r.x = o.x + x;
+ return r;
+ }
+ enum E { i, j };
+
+};
+
+struct C: A
+{
+};
+
+}
diff --git a/libs/python/pyste/tests/inherit3.pyste b/libs/python/pyste/tests/inherit3.pyste
new file mode 100644
index 000000000..f95c06054
--- /dev/null
+++ b/libs/python/pyste/tests/inherit3.pyste
@@ -0,0 +1,2 @@
+Class('inherit3::B', 'inherit3.h')
+Class('inherit3::C', 'inherit3.h')
diff --git a/libs/python/pyste/tests/inherit3UT.py b/libs/python/pyste/tests/inherit3UT.py
new file mode 100644
index 000000000..b7dba1e93
--- /dev/null
+++ b/libs/python/pyste/tests/inherit3UT.py
@@ -0,0 +1,27 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _inherit3 import *
+
+class testInherit3(unittest.TestCase):
+
+ def testIt(self):
+ def testInst(c):
+ self.assertEqual(c.x, 0)
+ self.assertEqual(c.foo(3), 3)
+ x = c.X()
+ self.assertEqual(x.y, 0)
+ self.assertEqual(c.E.i, 0)
+ self.assertEqual(c.E.j, 1)
+ b = B()
+ c = C()
+ testInst(b)
+ testInst(c)
+ self.assertEqual(b.foo(), 1)
+ self.assertEqual(c.foo(), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/inherit4.h b/libs/python/pyste/tests/inherit4.h
new file mode 100644
index 000000000..a1cecfbc8
--- /dev/null
+++ b/libs/python/pyste/tests/inherit4.h
@@ -0,0 +1,23 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+namespace inherit4 {
+
+struct A
+{
+ int x;
+};
+
+struct B: A
+{
+ int y;
+};
+
+struct C: B
+{
+ int z;
+};
+
+}
diff --git a/libs/python/pyste/tests/inherit4.pyste b/libs/python/pyste/tests/inherit4.pyste
new file mode 100644
index 000000000..4809e022f
--- /dev/null
+++ b/libs/python/pyste/tests/inherit4.pyste
@@ -0,0 +1,3 @@
+Class('inherit4::A', 'inherit4.h')
+Class('inherit4::B', 'inherit4.h')
+Class('inherit4::C', 'inherit4.h')
diff --git a/libs/python/pyste/tests/inherit4UT.py b/libs/python/pyste/tests/inherit4UT.py
new file mode 100644
index 000000000..f2c75c553
--- /dev/null
+++ b/libs/python/pyste/tests/inherit4UT.py
@@ -0,0 +1,31 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _inherit4 import *
+
+class TestInherit4(unittest.TestCase):
+
+ def testIt(self):
+ self.assert_(issubclass(B, A))
+ self.assert_(issubclass(C, A))
+ self.assert_(issubclass(C, B))
+ a = A()
+ a.x = 1
+ b = B()
+ b.x = 10
+ b.y = 20
+ c = C()
+ c.x = 100
+ c.y = 200
+ c.z = 300
+ self.assertEqual(a.x, 1)
+ self.assertEqual(b.x, 10)
+ self.assertEqual(b.y, 20)
+ self.assertEqual(c.x, 100)
+ self.assertEqual(c.y, 200)
+ self.assertEqual(c.z, 300)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/inheritUT.py b/libs/python/pyste/tests/inheritUT.py
new file mode 100644
index 000000000..f3e7b4062
--- /dev/null
+++ b/libs/python/pyste/tests/inheritUT.py
@@ -0,0 +1,33 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _inherit import *
+
+class InheritExampleTest(unittest.TestCase):
+
+ def testIt(self):
+ a = A_int()
+ b = B()
+ self.assert_(isinstance(b, A_int))
+ self.assert_(issubclass(B, A_int))
+ a.set(10)
+ self.assertEqual(a.get(), 10)
+ b.set(1)
+ self.assertEqual(b.go(), 1)
+ self.assertEqual(b.get(), 1)
+
+ d = D()
+ self.assert_(issubclass(D, B))
+ self.assertEqual(d.x, 0)
+ self.assertEqual(d.y, 0)
+ self.assertEqual(d.s, 1)
+ self.assertEqual(D.s, 1)
+ self.assertEqual(d.f1(), 1)
+ self.assertEqual(d.f2(), 2)
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/nested.cpp b/libs/python/pyste/tests/nested.cpp
new file mode 100644
index 000000000..6e167ab06
--- /dev/null
+++ b/libs/python/pyste/tests/nested.cpp
@@ -0,0 +1,9 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "nested.h"
+
+int nested::X::staticXValue = 10;
+int nested::X::Y::staticYValue = 20;
diff --git a/libs/python/pyste/tests/nested.h b/libs/python/pyste/tests/nested.h
new file mode 100644
index 000000000..13ed60856
--- /dev/null
+++ b/libs/python/pyste/tests/nested.h
@@ -0,0 +1,32 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef NESTED_H
+#define NESTED_H
+
+namespace nested {
+
+struct X
+{
+ struct Y
+ {
+ int valueY;
+ static int staticYValue;
+ struct Z
+ {
+ int valueZ;
+ };
+ };
+
+ static int staticXValue;
+ int valueX;
+};
+
+typedef X Root;
+
+}
+
+#endif
diff --git a/libs/python/pyste/tests/nested.pyste b/libs/python/pyste/tests/nested.pyste
new file mode 100644
index 000000000..48bb26b55
--- /dev/null
+++ b/libs/python/pyste/tests/nested.pyste
@@ -0,0 +1 @@
+Class('nested::Root', 'nested.h')
diff --git a/libs/python/pyste/tests/nestedUT.py b/libs/python/pyste/tests/nestedUT.py
new file mode 100644
index 000000000..06c1c7beb
--- /dev/null
+++ b/libs/python/pyste/tests/nestedUT.py
@@ -0,0 +1,19 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _nested import *
+
+class NestedTest(unittest.TestCase):
+
+ def testIt(self):
+ self.assertEqual(Root.staticXValue, 10)
+ self.assertEqual(Root.Y.staticYValue, 20)
+ z = Root.Y.Z()
+ z.valueZ = 3
+ self.assertEqual(z.valueZ, 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/opaque.h b/libs/python/pyste/tests/opaque.h
new file mode 100644
index 000000000..1947830ea
--- /dev/null
+++ b/libs/python/pyste/tests/opaque.h
@@ -0,0 +1,57 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef OPAQUE_H
+#define OPAQUE_H
+
+#include <iostream>
+
+namespace opaque {
+
+
+struct C {
+ C(int v): value(v) {}
+ int value;
+};
+
+
+inline C* new_C()
+{
+ return new C(10);
+}
+
+inline C* new_C_zero()
+{
+ return new C(0);
+}
+
+inline int get(C* c)
+{
+ return c->value;
+}
+
+struct D {
+ D(double v): value(v) {}
+ double value;
+};
+
+struct A
+{
+ D* new_handle()
+ {
+ return new D(3.0);
+ }
+
+ double get(D* d)
+ {
+ return d->value;
+ }
+
+ int f(int x=0) { return x; }
+};
+
+}
+
+#endif
diff --git a/libs/python/pyste/tests/opaque.pyste b/libs/python/pyste/tests/opaque.pyste
new file mode 100644
index 000000000..8180d251c
--- /dev/null
+++ b/libs/python/pyste/tests/opaque.pyste
@@ -0,0 +1,7 @@
+foo = Function('opaque::new_C', 'opaque.h')
+set_policy(foo, return_value_policy(return_opaque_pointer))
+foo = Function('opaque::new_C_zero', 'opaque.h')
+set_policy(foo, return_value_policy(return_opaque_pointer))
+Function('opaque::get', 'opaque.h' )
+A = Class('opaque::A', 'opaque.h')
+set_policy(A.new_handle, return_value_policy(return_opaque_pointer))
diff --git a/libs/python/pyste/tests/opaqueUT.py b/libs/python/pyste/tests/opaqueUT.py
new file mode 100644
index 000000000..0f3e1e073
--- /dev/null
+++ b/libs/python/pyste/tests/opaqueUT.py
@@ -0,0 +1,24 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _opaque import *
+
+class OpaqueTest(unittest.TestCase):
+
+ def testIt(self):
+
+ c = new_C()
+ self.assertEqual(get(c), 10)
+ c = new_C_zero()
+ self.assertEqual(get(c), 0)
+ a = A()
+ d = a.new_handle()
+ self.assertEqual(a.get(d), 3.0)
+ self.assertEqual(a.f(), 0)
+ self.assertEqual(a.f(3), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/operators.cpp b/libs/python/pyste/tests/operators.cpp
new file mode 100644
index 000000000..cecdaca0d
--- /dev/null
+++ b/libs/python/pyste/tests/operators.cpp
@@ -0,0 +1,8 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "operators.h"
+
+double operators::C::x = 10;
diff --git a/libs/python/pyste/tests/operators.h b/libs/python/pyste/tests/operators.h
new file mode 100644
index 000000000..5d3944216
--- /dev/null
+++ b/libs/python/pyste/tests/operators.h
@@ -0,0 +1,52 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef OPERATORS_H
+#define OPERATORS_H
+
+
+namespace operators {
+
+struct C
+{
+ static double x;
+ double value;
+
+ const C operator+(const C other) const
+ {
+ C c;
+ c.value = value + other.value;
+ return c;
+ }
+ operator int() const
+ {
+ return (int)value;
+ }
+
+ double operator()()
+ {
+ return C::x;
+ }
+
+ double operator()(double other)
+ {
+ return C::x + other;
+ }
+
+ operator const char*() { return "C"; }
+};
+
+inline const C operator*(const C& lhs, const C& rhs)
+{
+ C c;
+ c.value = lhs.value * rhs.value;
+ return c;
+}
+
+
+}
+
+
+#endif
diff --git a/libs/python/pyste/tests/operators.pyste b/libs/python/pyste/tests/operators.pyste
new file mode 100644
index 000000000..4ab7a3709
--- /dev/null
+++ b/libs/python/pyste/tests/operators.pyste
@@ -0,0 +1,2 @@
+C = Class('operators::C', 'operators.h')
+#exclude(C.operator['+'])
diff --git a/libs/python/pyste/tests/operatorsUT.py b/libs/python/pyste/tests/operatorsUT.py
new file mode 100644
index 000000000..beb193173
--- /dev/null
+++ b/libs/python/pyste/tests/operatorsUT.py
@@ -0,0 +1,30 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _operators import *
+
+class OperatorTest(unittest.TestCase):
+
+ def testIt(self):
+ c = C()
+ c.value = 3.0
+ d = C()
+ d.value = 2.0
+ self.assertEqual(c.x, 10)
+ self.assertEqual(C.x, 10)
+ self.assertEqual(C.x, 10)
+ self.assertEqual((c * d).value, 6.0)
+ self.assertEqual((c + d).value, 5.0)
+ self.assertEqual(int(c), 3)
+ self.assertEqual(int(d), 2)
+ self.assertEqual(c(), 10)
+ self.assertEqual(d(), 10)
+ self.assertEqual(c(3.0), 13.0)
+ self.assertEqual(d(6.0), 16.0)
+ self.assertEqual(str(c), "C")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/policiesUT.py b/libs/python/pyste/tests/policiesUT.py
new file mode 100644
index 000000000..7255baeb4
--- /dev/null
+++ b/libs/python/pyste/tests/policiesUT.py
@@ -0,0 +1,67 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import sys
+import unittest
+from Pyste.policies import *
+
+
+#================================================================================
+# PolicicesTest
+#================================================================================
+class PoliciesTest(unittest.TestCase):
+
+ def testReturnInternal(self):
+ 'tests the code from a simple internal_reference'
+
+ x = return_internal_reference(1)
+ self.assertEqual(x.Code(), 'return_internal_reference< 1 >')
+ x = return_internal_reference(3)
+ self.assertEqual(x.Code(), 'return_internal_reference< 3 >')
+
+
+ def testCustodian(self):
+ 'tests the code from a simple custodian_and_ward'
+
+ x = with_custodian_and_ward(1,2)
+ self.assertEqual(x.Code(), 'with_custodian_and_ward< 1, 2 >')
+ x = with_custodian_and_ward(3,4)
+ self.assertEqual(x.Code(), 'with_custodian_and_ward< 3, 4 >')
+
+
+ def testReturnPolicies(self):
+ 'tests all the return_value_policies'
+
+ ret = 'return_value_policy< %s >'
+ x = return_value_policy(reference_existing_object)
+ self.assertEqual(x.Code(), ret % 'reference_existing_object')
+ x = return_value_policy(copy_const_reference)
+ self.assertEqual(x.Code(), ret % 'copy_const_reference')
+ x = return_value_policy(copy_non_const_reference)
+ self.assertEqual(x.Code(), ret % 'copy_non_const_reference')
+ x = return_value_policy(manage_new_object)
+ self.assertEqual(x.Code(), ret % 'manage_new_object')
+ x = return_value_policy(return_opaque_pointer)
+ self.assertEqual(x.Code(), ret % 'return_opaque_pointer')
+
+ def testReturnWithCustodiam(self):
+ 'test the mix of return_internal with custodian'
+
+ x = return_internal_reference(1, with_custodian_and_ward(3,2))
+ self.assertEqual(
+ x.Code(),
+ 'return_internal_reference< 1, with_custodian_and_ward< 3, 2 > >')
+
+
+ def testReturnPoliciesWithInternal(self):
+ 'test the mix of return_internal with return_policy'
+
+ x = return_internal_reference(1, return_value_policy(manage_new_object))
+ self.assertEqual(
+ x.Code(),
+ 'return_internal_reference< 1, return_value_policy< manage_new_object > >')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/runtests.py b/libs/python/pyste/tests/runtests.py
new file mode 100644
index 000000000..4bf83b345
--- /dev/null
+++ b/libs/python/pyste/tests/runtests.py
@@ -0,0 +1,21 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#!/usr/bin/python
+
+import sys
+sys.path.append('../src/Pyste')
+import unittest
+import os.path
+from glob import glob
+
+if __name__ == '__main__':
+ loader = unittest.defaultTestLoader
+ tests = []
+ for name in glob('*UT.py'):
+ module = __import__(os.path.splitext(name)[0])
+ tests.append(loader.loadTestsFromModule(module))
+ runner = unittest.TextTestRunner()
+ result = runner.run(unittest.TestSuite(tests))
+ sys.exit(not result.wasSuccessful())
diff --git a/libs/python/pyste/tests/smart_ptr.h b/libs/python/pyste/tests/smart_ptr.h
new file mode 100644
index 000000000..b230b9179
--- /dev/null
+++ b/libs/python/pyste/tests/smart_ptr.h
@@ -0,0 +1,50 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef SMART_PTR_H
+#define SMART_PTR_H
+
+
+#include <memory>
+#include <boost/shared_ptr.hpp>
+
+namespace smart_ptr {
+
+struct C
+{
+ int value;
+};
+
+inline boost::shared_ptr<C> NewC() { return boost::shared_ptr<C>( new C() ); }
+
+struct D
+{
+ boost::shared_ptr<C> Get() { return ptr; }
+ void Set( boost::shared_ptr<C> c ) { ptr = c; }
+private:
+ boost::shared_ptr<C> ptr;
+};
+
+inline std::auto_ptr<D> NewD() { return std::auto_ptr<D>( new D() ); }
+
+
+// test an abstract class
+struct A
+{
+ virtual int f() = 0;
+};
+
+struct B: A
+{
+ virtual int f(){ return 1; }
+};
+
+inline boost::shared_ptr<A> NewA() { return boost::shared_ptr<A>(new B()); }
+inline int GetA(boost::shared_ptr<A> a) { return a->f(); }
+
+}
+
+#endif
diff --git a/libs/python/pyste/tests/smart_ptr.pyste b/libs/python/pyste/tests/smart_ptr.pyste
new file mode 100644
index 000000000..cfbdd81ae
--- /dev/null
+++ b/libs/python/pyste/tests/smart_ptr.pyste
@@ -0,0 +1,13 @@
+C = Class('smart_ptr::C', 'smart_ptr.h')
+use_shared_ptr(C)
+
+D = Class('smart_ptr::D', 'smart_ptr.h')
+use_auto_ptr(D)
+
+A = Class('smart_ptr::A', 'smart_ptr.h')
+use_shared_ptr(A)
+
+Function('smart_ptr::NewC', 'smart_ptr.h')
+Function('smart_ptr::NewD', 'smart_ptr.h')
+Function('smart_ptr::NewA', 'smart_ptr.h')
+Function('smart_ptr::GetA', 'smart_ptr.h')
diff --git a/libs/python/pyste/tests/smart_ptrUT.py b/libs/python/pyste/tests/smart_ptrUT.py
new file mode 100644
index 000000000..9d81f08dd
--- /dev/null
+++ b/libs/python/pyste/tests/smart_ptrUT.py
@@ -0,0 +1,22 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _smart_ptr import *
+
+class BasicExampleTest(unittest.TestCase):
+
+ def testIt(self):
+ c = NewC()
+ d = NewD()
+ c.value = 3
+ d.Set(c)
+ c1 = d.Get()
+ c1.value = 6
+ self.assertEqual(c.value, 6)
+ a = NewA()
+ self.assertEqual(GetA(a), 1)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/templates.h b/libs/python/pyste/tests/templates.h
new file mode 100644
index 000000000..7258e91c7
--- /dev/null
+++ b/libs/python/pyste/tests/templates.h
@@ -0,0 +1,15 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+namespace templates {
+
+template <class T>
+struct Point
+{
+ T x;
+ T y;
+};
+
+}
diff --git a/libs/python/pyste/tests/templates.pyste b/libs/python/pyste/tests/templates.pyste
new file mode 100644
index 000000000..77eaceaa3
--- /dev/null
+++ b/libs/python/pyste/tests/templates.pyste
@@ -0,0 +1,8 @@
+Point = Template('templates::Point', 'templates.h')
+rename(Point.x, 'i')
+rename(Point.y, 'j')
+IPoint = Point('int')
+FPoint = Point('double', 'FPoint')
+rename(IPoint, 'IPoint')
+rename(IPoint.x, 'x')
+rename(IPoint.y, 'y')
diff --git a/libs/python/pyste/tests/templatesUT.py b/libs/python/pyste/tests/templatesUT.py
new file mode 100644
index 000000000..0c4b08b50
--- /dev/null
+++ b/libs/python/pyste/tests/templatesUT.py
@@ -0,0 +1,30 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _templates import *
+
+class TemplatesTest(unittest.TestCase):
+
+ def testIt(self):
+ fp = FPoint()
+ fp.i = 3.0
+ fp.j = 4.0
+ ip = IPoint()
+ ip.x = 10
+ ip.y = 3
+
+ self.assertEqual(fp.i, 3.0)
+ self.assertEqual(fp.j, 4.0)
+ self.assertEqual(ip.x, 10)
+ self.assertEqual(ip.y, 3)
+ self.assertEqual(type(fp.i), float)
+ self.assertEqual(type(fp.j), float)
+ self.assertEqual(type(ip.x), int)
+ self.assertEqual(type(ip.y), int)
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/test_all.py b/libs/python/pyste/tests/test_all.py
new file mode 100644
index 000000000..ba3c54dee
--- /dev/null
+++ b/libs/python/pyste/tests/test_all.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import os
+import glob
+import shutil
+import sys
+import time
+
+#=============================================================================
+# win32 configuration
+#=============================================================================
+if sys.platform == 'win32':
+
+ includes = '-ID:/programming/libraries/boost-cvs/boost -ID:/Bin/Python/include'
+ build_pyste_cmd = 'python ../src/Pyste/pyste.py --pyste-ns=pyste --cache-dir=cache %s ' % includes
+ compile_single_cmd = 'cl /nologo /GR /GX -c %s -I. ' % includes
+ link_single_cmd = 'link /nologo /DLL '\
+ '/libpath:D:/programming/libraries/boost-cvs/lib /libpath:D:/Bin/Python/libs '\
+ 'boost_python.lib python24.lib /out:_%s.dll '
+ obj_ext = 'obj'
+
+#=============================================================================
+# linux configuration
+#=============================================================================
+elif sys.platform == 'linux2':
+
+ build_pyste_cmd = 'python ../src/Pyste/pyste.py -I. '
+ compile_single_cmd = 'g++ -shared -c -I. -I/usr/include/python2.4 '
+ link_single_cmd = 'g++ -shared -o _%s.so -lboost_python '
+ obj_ext = 'o'
+
+
+
+def build_pyste(multiple, module):
+ rest = '%s --module=_%s %s.pyste' % (multiple, module, module)
+ execute(build_pyste_cmd + rest)
+
+
+def compile_single(module):
+ module_obj = ''
+ if os.path.isfile(module+'.cpp'):
+ execute(compile_single_cmd + module+'.cpp')
+ module_obj = module + '.' + obj_ext
+ execute(compile_single_cmd + ('_%s.cpp' % module))
+ link = link_single_cmd % module
+ execute(link + ('_%s.%s ' % (module, obj_ext)) + module_obj)
+
+
+def compile_multiple(module):
+ module_obj = ''
+ if os.path.isfile(module+'.cpp'):
+ execute(compile_single_cmd + module+'.cpp')
+ module_obj = module + '.' + obj_ext
+ files = glob.glob('_%s/*.cpp' % module)
+ for f in files:
+ execute(compile_single_cmd + f)
+ def basename(name):
+ return os.path.basename(os.path.splitext(name)[0])
+ objs = [basename(x) + '.' + obj_ext for x in files]
+ objs.append(module_obj)
+ execute((link_single_cmd % module) + ' '.join(objs))
+
+
+def execute(cmd):
+ os.system(cmd)
+
+
+def run_tests():
+ if os.system('python runtests.py') != 0:
+ raise RuntimeError, 'tests failed'
+
+
+def cleanup():
+ modules = get_modules()
+ extensions = '*.dll *.pyc *.obj *.exp *.lib *.o *.so'
+ files = []
+ for module in modules:
+ files.append('_' + module + '.cpp')
+ for ext in extensions.split():
+ files += glob.glob(ext)
+ files.append('build.log')
+ for file in files:
+ try:
+ os.remove(file)
+ except OSError: pass
+
+ for module in modules:
+ try:
+ shutil.rmtree('_' + module)
+ except OSError: pass
+
+
+def main(multiple, module=None):
+ if module is None:
+ modules = get_modules()
+ else:
+ modules = [module]
+
+ start = time.clock()
+ for module in modules:
+ build_pyste(multiple, module)
+ print '-'*50
+ print 'Building pyste files: %0.2f seconds' % (time.clock()-start)
+ print
+
+ start = time.clock()
+ for module in modules:
+ if multiple:
+ compile_multiple(module)
+ else:
+ compile_single(module)
+ print '-'*50
+ print 'Compiling files: %0.2f seconds' % (time.clock()-start)
+ print
+ if len(modules) == 1:
+ os.system('python %sUT.py' % modules[0])
+ else:
+ run_tests()
+ #cleanup()
+
+
+def get_modules():
+ def getname(file):
+ return os.path.splitext(os.path.basename(file))[0]
+ return [getname(x) for x in glob.glob('*.pyste')]
+
+if __name__ == '__main__':
+ if len(sys.argv) > 1:
+ module = sys.argv[1]
+ else:
+ module = None
+ try:
+# main('--multiple', module)
+ main('', module)
+ except RuntimeError, e:
+ print e
diff --git a/libs/python/pyste/tests/vars.cpp b/libs/python/pyste/tests/vars.cpp
new file mode 100644
index 000000000..e2abcd332
--- /dev/null
+++ b/libs/python/pyste/tests/vars.cpp
@@ -0,0 +1,12 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "vars.h"
+
+const Color black = Color(0, 0, 0);
+const Color red = Color(255, 0, 0);
+const Color green = Color(0, 255, 0);
+const Color blue = Color(0, 0, 255);
+Color in_use = black;
diff --git a/libs/python/pyste/tests/vars.h b/libs/python/pyste/tests/vars.h
new file mode 100644
index 000000000..24e87d802
--- /dev/null
+++ b/libs/python/pyste/tests/vars.h
@@ -0,0 +1,24 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+struct Color
+{
+ Color(int r_ = 0, int g_ = 0, int b_ = 0):
+ r(r_), g(g_), b(b_)
+ {}
+ Color( const Color &c):
+ r(c.r), g(c.g), b(c.b)
+ {}
+ int r;
+ int g;
+ int b;
+};
+
+extern const Color black;
+extern const Color red;
+extern const Color green;
+extern const Color blue;
+extern Color in_use;
diff --git a/libs/python/pyste/tests/vars.pyste b/libs/python/pyste/tests/vars.pyste
new file mode 100644
index 000000000..3fd9d689d
--- /dev/null
+++ b/libs/python/pyste/tests/vars.pyste
@@ -0,0 +1 @@
+AllFromHeader('vars.h')
diff --git a/libs/python/pyste/tests/varsUT.py b/libs/python/pyste/tests/varsUT.py
new file mode 100644
index 000000000..4c32cbb2f
--- /dev/null
+++ b/libs/python/pyste/tests/varsUT.py
@@ -0,0 +1,22 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+import _vars
+
+
+class VarsTest(unittest.TestCase):
+
+ def testIt(self):
+ def testColor(c, r, g, b):
+ self.assertEqual(c.r, r)
+ self.assertEqual(c.g, g)
+ self.assertEqual(c.b, b)
+ testColor(_vars.black, 0, 0, 0)
+ testColor(_vars.red, 255, 0, 0)
+ testColor(_vars.green, 0, 255, 0)
+ testColor(_vars.blue, 0, 0, 255)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/virtual.cpp b/libs/python/pyste/tests/virtual.cpp
new file mode 100644
index 000000000..070d9d346
--- /dev/null
+++ b/libs/python/pyste/tests/virtual.cpp
@@ -0,0 +1,75 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+// Includes ====================================================================
+#include <boost/python.hpp>
+#include <virtual.h>
+
+// Using =======================================================================
+using namespace boost::python;
+
+// Declarations ================================================================
+
+
+namespace {
+
+
+struct virtual_C_Wrapper: virtual_::C
+{
+ virtual_C_Wrapper(PyObject* self_, const virtual_::C & p0):
+ virtual_::C(p0), self(self_) {}
+
+ virtual_C_Wrapper(PyObject* self_):
+ virtual_::C(), self(self_) {}
+
+ int f() {
+ return call_method< int >(self, "f");
+ }
+
+ int default_f() {
+ return virtual_::C::f();
+ }
+
+ void bar(int p0) {
+ call_method< void >(self, "bar", p0);
+ }
+
+ void default_bar(int p0) {
+ virtual_::C::bar(p0);
+ }
+
+ void bar(char * p0) {
+ call_method< void >(self, "bar", p0);
+ }
+
+ void default_bar(char * p0) {
+ virtual_::C::bar(p0);
+ }
+
+ int f_abs() {
+ return call_method< int >(self, "f_abs");
+ }
+
+ PyObject* self;
+};
+
+
+
+}// namespace
+
+
+// Module ======================================================================
+BOOST_PYTHON_MODULE(virtual)
+{
+ class_< virtual_::C, boost::noncopyable, virtual_C_Wrapper >("C", init< >())
+ .def("get_name", &virtual_::C::get_name)
+ .def("f", &virtual_::C::f, &virtual_C_Wrapper::default_f)
+ .def("bar", (void (virtual_::C::*)(int) )&virtual_::C::bar, (void (virtual_C_Wrapper::*)(int))&virtual_C_Wrapper::default_bar)
+ .def("bar", (void (virtual_::C::*)(char *) )&virtual_::C::bar, (void (virtual_C_Wrapper::*)(char *))&virtual_C_Wrapper::default_bar)
+ ;
+
+ def("call_f", &virtual_::call_f);
+}
diff --git a/libs/python/pyste/tests/virtual.h b/libs/python/pyste/tests/virtual.h
new file mode 100644
index 000000000..d0bb194a1
--- /dev/null
+++ b/libs/python/pyste/tests/virtual.h
@@ -0,0 +1,41 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+namespace virtual_ {
+
+struct C
+{
+public:
+ virtual int f()
+ {
+ return f_abs();
+ }
+
+ virtual void bar(int) {}
+ virtual void bar(char*) {}
+
+ const char* get_name()
+ {
+ return name();
+ }
+ virtual int dummy() { return 0; }
+
+protected:
+ virtual int f_abs() = 0;
+
+private:
+ virtual const char* name() { return "C"; }
+};
+
+struct D
+{
+ virtual int dummy() { return 0; }
+};
+
+inline int call_f(C& c) { return c.f(); }
+inline int call_dummy(C* c) { return c->dummy(); }
+inline int call_dummy(D* d) { return d->dummy(); }
+
+}
diff --git a/libs/python/pyste/tests/virtual.pyste b/libs/python/pyste/tests/virtual.pyste
new file mode 100644
index 000000000..ef9664124
--- /dev/null
+++ b/libs/python/pyste/tests/virtual.pyste
@@ -0,0 +1,6 @@
+C = Class('virtual_::C', 'virtual.h')
+final(C.dummy)
+D = Class('virtual_::D', 'virtual.h')
+final(D.dummy)
+Function('virtual_::call_f', 'virtual.h')
+Function('virtual_::call_dummy', 'virtual.h')
diff --git a/libs/python/pyste/tests/virtual2.h b/libs/python/pyste/tests/virtual2.h
new file mode 100644
index 000000000..a6677ad16
--- /dev/null
+++ b/libs/python/pyste/tests/virtual2.h
@@ -0,0 +1,34 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+namespace virtual2 {
+
+struct A
+{
+ virtual int f() { return 0; }
+ virtual int f1() { return 10; }
+ virtual A* make_new() { return new A; }
+};
+
+struct B: A
+{
+ virtual int f() { return 1; }
+ virtual int f2() { return 20; }
+ virtual A* make_new() { return new B; }
+};
+
+inline int call_fs(A*a)
+{
+ int r = a->f1();
+ B* b = dynamic_cast<B*>(a);
+ return r + b->f2();
+}
+
+inline int call_f(A* a)
+{
+ return a->f();
+}
+}
diff --git a/libs/python/pyste/tests/virtual2.pyste b/libs/python/pyste/tests/virtual2.pyste
new file mode 100644
index 000000000..785b819c8
--- /dev/null
+++ b/libs/python/pyste/tests/virtual2.pyste
@@ -0,0 +1,6 @@
+A = Class('virtual2::A', 'virtual2.h')
+set_policy(A.make_new, return_value_policy(manage_new_object))
+B = Class('virtual2::B', 'virtual2.h')
+set_policy(B.make_new, return_value_policy(manage_new_object))
+Function('virtual2::call_fs', 'virtual2.h')
+Function('virtual2::call_f', 'virtual2.h')
diff --git a/libs/python/pyste/tests/virtual2UT.py b/libs/python/pyste/tests/virtual2UT.py
new file mode 100644
index 000000000..312277d26
--- /dev/null
+++ b/libs/python/pyste/tests/virtual2UT.py
@@ -0,0 +1,40 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import unittest
+from _virtual2 import *
+
+class Virtual2Test(unittest.TestCase):
+
+ def testIt(self):
+ a = A()
+ self.assertEqual(a.f1(), 10)
+ b = B()
+ self.assertEqual(b.f1(), 10)
+ self.assertEqual(b.f2(), 20)
+ self.assertEqual(call_fs(b), 30)
+ self.assertEqual(call_f(a), 0)
+ self.assertEqual(call_f(b), 1)
+ nb = b.make_new()
+ na = a.make_new()
+ self.assertEqual(na.f1(), 10)
+ self.assertEqual(nb.f1(), 10)
+ self.assertEqual(nb.f2(), 20)
+ self.assertEqual(call_fs(nb), 30)
+ self.assertEqual(call_f(na), 0)
+ self.assertEqual(call_f(nb), 1)
+ class C(B):
+ def f1(self): return 1
+ def f2(self): return 2
+ def f(self): return 100
+
+ c = C()
+ self.assertEqual(call_fs(c), 3)
+ self.assertEqual(call_fs(c), 3)
+ self.assertEqual(call_f(c), 100)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/virtualUT.py b/libs/python/pyste/tests/virtualUT.py
new file mode 100644
index 000000000..deff68189
--- /dev/null
+++ b/libs/python/pyste/tests/virtualUT.py
@@ -0,0 +1,55 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _virtual import *
+
+class VirtualTest(unittest.TestCase):
+
+ def testIt(self):
+
+ class E(C):
+ def f_abs(self):
+ return 3
+ def dummy(self):
+ # override should not work
+ return 100
+
+ class F(C):
+ def f(self):
+ return 10
+ def name(self):
+ return 'F'
+
+ class G(D):
+ def dummy(self):
+ # override should not work
+ return 100
+
+ e = E()
+ f = F()
+
+ self.assertEqual(e.f(), 3)
+ self.assertEqual(call_f(e), 3)
+ self.assertEqual(f.f(), 10)
+ self.assertEqual(call_f(f), 10)
+ self.assertEqual(e.get_name(), 'C')
+ #self.assertEqual(e.get_name(), 'E') check this later
+
+ c = C()
+ c.bar(1) # ok
+ c.bar('a') # ok
+ self.assertRaises(TypeError, c.bar, 1.0)
+
+ # test no_overrides
+ d = G()
+ self.assertEqual(e.dummy(), 100)
+ self.assertEqual(call_dummy(e), 0)
+ self.assertEqual(d.dummy(), 100)
+ self.assertEqual(call_dummy(d), 0)
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/wrappertest.h b/libs/python/pyste/tests/wrappertest.h
new file mode 100644
index 000000000..2304fd843
--- /dev/null
+++ b/libs/python/pyste/tests/wrappertest.h
@@ -0,0 +1,51 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef WRAPPER_TEST
+#define WRAPPER_TEST
+
+
+#include <vector>
+
+namespace wrappertest {
+
+inline std::vector<int> Range(int count)
+{
+ std::vector<int> v;
+ v.reserve(count);
+ for (int i = 0; i < count; ++i){
+ v.push_back(i);
+ }
+ return v;
+}
+
+
+struct C
+{
+ C() {}
+
+ std::vector<int> Mul(int value)
+ {
+ std::vector<int> res;
+ res.reserve(value);
+ std::vector<int>::const_iterator it;
+ std::vector<int> v(Range(value));
+ for (it = v.begin(); it != v.end(); ++it){
+ res.push_back(*it * value);
+ }
+ return res;
+ }
+};
+
+
+struct A
+{
+ virtual int f() { return 1; };
+};
+
+inline int call_foo(A* a){ return a->f(); }
+}
+#endif
+
diff --git a/libs/python/pyste/tests/wrappertest.pyste b/libs/python/pyste/tests/wrappertest.pyste
new file mode 100644
index 000000000..12ba47b6b
--- /dev/null
+++ b/libs/python/pyste/tests/wrappertest.pyste
@@ -0,0 +1,21 @@
+Include('wrappertest_wrappers.h')
+
+f = Function('wrappertest::Range', 'wrappertest.h')
+set_wrapper(f, 'RangeWrapper')
+
+mul = Wrapper('MulWrapper',
+'''
+list MulWrapper(wrappertest::C& c, int value){
+ return VectorToList(c.Mul(value));
+}
+'''
+)
+
+C = Class('wrappertest::C', 'wrappertest.h')
+set_wrapper(C.Mul, mul)
+
+
+A = Class('wrappertest::A', 'wrappertest.h')
+set_wrapper(A.f, 'f_wrapper')
+
+Function('wrappertest::call_foo', 'wrappertest.h')
diff --git a/libs/python/pyste/tests/wrappertestUT.py b/libs/python/pyste/tests/wrappertestUT.py
new file mode 100644
index 000000000..d770408b7
--- /dev/null
+++ b/libs/python/pyste/tests/wrappertestUT.py
@@ -0,0 +1,24 @@
+# Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+# distribution is subject to the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+from _wrappertest import *
+
+class WrapperTest(unittest.TestCase):
+
+ def testIt(self):
+ self.assertEqual(Range(10), range(10))
+ self.assertEqual(C().Mul(10), [x*10 for x in range(10)])
+
+ a = A()
+ self.assertEqual(a.f(), 10)
+ self.assertEqual(call_foo(a), 10)
+ class D(A):
+ def f(self): return 2
+ d = D()
+ self.assertEqual(d.f(), 2)
+ self.assertEqual(call_foo(d), 2)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libs/python/pyste/tests/wrappertest_wrappers.h b/libs/python/pyste/tests/wrappertest_wrappers.h
new file mode 100644
index 000000000..31570a051
--- /dev/null
+++ b/libs/python/pyste/tests/wrappertest_wrappers.h
@@ -0,0 +1,33 @@
+/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and
+ distribution is subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef WRAPPER_TEST_WRAPPERS
+#define WRAPPER_TEST_WRAPPERS
+
+#include <vector>
+#include <boost/python.hpp>
+#include "wrappertest.h"
+
+using namespace boost::python;
+
+template <class T>
+list VectorToList(const std::vector<T> & v)
+{
+ list res;
+ typename std::vector<T>::const_iterator it;
+ for(it = v.begin(); it != v.end(); ++it){
+ res.append(*it);
+ }
+ Py_XINCREF(res.ptr());
+ return res;
+}
+
+inline list RangeWrapper(int count){
+ return VectorToList(wrappertest::Range(count));
+}
+
+inline int f_wrapper(wrappertest::A*) { return 10; }
+
+#endif
diff --git a/libs/python/release_notes.txt b/libs/python/release_notes.txt
new file mode 100644
index 000000000..1fd0f1b14
--- /dev/null
+++ b/libs/python/release_notes.txt
@@ -0,0 +1,223 @@
+.. Copyright David Abrahams 2006. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+These are old release notes for Boost.Python v1
+
+2000-11-22 10:00
+ Ullrich fixed bug in operator_dispatcher<op_long>.
+
+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"
+ <rwgk@cci.lbl.gov>
+
+ Added a specialization of Callback<const char*> 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<T>) 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"
+ <rwgk@cci.lbl.gov>
+
+ 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
+ <koethe@informatik.uni-hamburg.de> 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
+ (<mark.evans@clarisay.com>)
+
+ const-ify ClassBase::getattr()
+
+ Add repr() function to Class<T>
+
+ Add to_python/from_python conversions for PyPtr<T>
+
+ 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"
+ <rwgk@cci.lbl.gov>
+
+ Fix a bug in the code of example1.html
diff --git a/libs/python/src/converter/arg_to_python_base.cpp b/libs/python/src/converter/arg_to_python_base.cpp
new file mode 100644
index 000000000..d872314a7
--- /dev/null
+++ b/libs/python/src/converter/arg_to_python_base.cpp
@@ -0,0 +1,28 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/converter/arg_to_python_base.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/handle.hpp>
+#include <boost/python/refcount.hpp>
+
+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/libs/python/src/converter/builtin_converters.cpp b/libs/python/src/converter/builtin_converters.cpp
new file mode 100644
index 000000000..9900602b7
--- /dev/null
+++ b/libs/python/src/converter/builtin_converters.cpp
@@ -0,0 +1,570 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/handle.hpp>
+#include <boost/python/type_id.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/refcount.hpp>
+
+#include <boost/python/detail/config.hpp>
+#include <boost/python/detail/wrap_python.hpp>
+
+#include <boost/python/converter/builtin_converters.hpp>
+#include <boost/python/converter/rvalue_from_python_data.hpp>
+#include <boost/python/converter/registry.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/converter/shared_ptr_deleter.hpp>
+#include <boost/python/converter/pytype_function.hpp>
+
+#include <boost/cast.hpp>
+#include <string>
+#include <complex>
+
+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.
+#if PY_VERSION_HEX < 0x03000000
+ void* convert_to_cstring(PyObject* obj)
+ {
+ return PyString_Check(obj) ? PyString_AsString(obj) : 0;
+ }
+#else
+ void* convert_to_cstring(PyObject* obj)
+ {
+ return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
+ }
+#endif
+
+ // 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 <class T, class SlotPolicy>
+ struct slot_rvalue_from_python
+ {
+ public:
+ slot_rvalue_from_python()
+ {
+ registry::insert(
+ &slot_rvalue_from_python<T,SlotPolicy>::convertible
+ , &slot_rvalue_from_python<T,SlotPolicy>::construct
+ , type_id<T>()
+ , &SlotPolicy::get_pytype
+ );
+ }
+
+ 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<unaryfunc*>(data->convertible);
+ handle<> intermediate(creator(obj));
+
+ // Get the location in which to construct
+ void* storage = ((rvalue_from_python_storage<T>*)data)->storage.bytes;
+# ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4244)
+# endif
+ new (storage) T( SlotPolicy::extract(intermediate.get()) );
+
+# ifdef _MSC_VER
+# pragma warning(pop)
+# endif
+ // record successful construction
+ data->convertible = storage;
+ }
+ };
+
+ // 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;
+
+#if PY_VERSION_HEX >= 0x03000000
+ // As in Python 3 there is only one integer type, we can have much
+ // simplified logic.
+ // XXX(bhy) maybe the code will work with 2.6 or even 2.5?
+ struct int_rvalue_from_python_base
+ {
+ static unaryfunc* get_slot(PyObject* obj)
+ {
+ return PyLong_Check(obj) ? &py_object_identity : 0;
+ }
+ static PyTypeObject const* get_pytype() {return &PyLong_Type;}
+ };
+
+ template <class T>
+ struct signed_int_rvalue_from_python : int_rvalue_from_python_base
+ {
+ static T extract(PyObject* intermediate)
+ {
+ long x = PyLong_AsLong(intermediate);
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return numeric_cast<T>(x);
+ }
+ };
+
+ template <class T>
+ struct unsigned_int_rvalue_from_python : int_rvalue_from_python_base
+ {
+ static T extract(PyObject* intermediate)
+ {
+ unsigned long x = PyLong_AsUnsignedLong(intermediate);
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return numeric_cast<T>(x);
+ }
+ };
+#else // PY_VERSION_HEX >= 0x03000000
+ // 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 (
+#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
+ !PyBool_Check(obj) &&
+#endif
+ (PyInt_Check(obj) || PyLong_Check(obj)))
+
+ ? &number_methods->nb_int : 0;
+ }
+ static PyTypeObject const* get_pytype() { return &PyInt_Type;}
+ };
+
+ template <class T>
+ 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<T>(x);
+ }
+ };
+
+ // 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 (
+#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
+ !PyBool_Check(obj) &&
+#endif
+ (PyInt_Check(obj) || PyLong_Check(obj)))
+ ? &py_object_identity : 0;
+ }
+ static PyTypeObject const* get_pytype() { return &PyInt_Type;}
+ };
+
+ template <class T>
+ struct unsigned_int_rvalue_from_python : unsigned_int_rvalue_from_python_base
+ {
+ static T extract(PyObject* intermediate)
+ {
+ if (PyLong_Check(intermediate)) {
+ // PyLong_AsUnsignedLong() checks for negative overflow, so no
+ // need to check it here.
+ unsigned long result = PyLong_AsUnsignedLong(intermediate);
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return numeric_cast<T>(result);
+ } else {
+ // None of PyInt_AsUnsigned*() functions check for negative
+ // overflow, so use PyInt_AS_LONG instead and check if number is
+ // negative, issuing the exception appropriately.
+ long result = PyInt_AS_LONG(intermediate);
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ if (result < 0) {
+ PyErr_SetString(PyExc_OverflowError, "can't convert negative"
+ " value to unsigned");
+ throw_error_already_set();
+ }
+ return numeric_cast<T>(result);
+ }
+ }
+ };
+#endif // PY_VERSION_HEX >= 0x03000000
+
+// 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)
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyLong_Check(obj) ? &py_object_identity : 0;
+#else
+ 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;
+#endif
+ }
+ static PyTypeObject const* get_pytype() { return &PyLong_Type;}
+ };
+
+ struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
+ {
+ static BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
+ {
+#if PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check(intermediate))
+ {
+ return PyInt_AS_LONG(intermediate);
+ }
+ else
+#endif
+ {
+ 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 PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check(intermediate))
+ {
+ return numeric_cast<unsigned BOOST_PYTHON_LONG_LONG>(PyInt_AS_LONG(intermediate));
+ }
+ else
+#endif
+ {
+ 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)
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ return obj == Py_None || PyLong_Check(obj) ? &py_object_identity : 0;
+#elif PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
+ return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
+#else
+ return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
+#endif
+ }
+
+ static bool extract(PyObject* intermediate)
+ {
+ return PyObject_IsTrue(intermediate);
+ }
+
+ static PyTypeObject const* get_pytype()
+ {
+#if PY_VERSION_HEX >= 0x02030000
+ return &PyBool_Type;
+#else
+ return &PyInt_Type;
+#endif
+ }
+ };
+
+ // 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 PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check(obj))
+ return &number_methods->nb_int;
+#endif
+
+ return (PyLong_Check(obj) || PyFloat_Check(obj))
+ ? &number_methods->nb_float : 0;
+ }
+
+ static double extract(PyObject* intermediate)
+ {
+#if PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check(intermediate))
+ {
+ return PyInt_AS_LONG(intermediate);
+ }
+ else
+#endif
+ {
+ return PyFloat_AS_DOUBLE(intermediate);
+ }
+ }
+ static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
+ };
+
+#if PY_VERSION_HEX >= 0x03000000
+ unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
+#endif
+
+ // 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)
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc :
+ PyBytes_Check(obj) ? &py_object_identity : 0;
+#else
+ return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0;
+
+#endif
+ };
+
+ // Remember that this will be used to construct the result object
+#if PY_VERSION_HEX >= 0x03000000
+ static std::string extract(PyObject* intermediate)
+ {
+ return std::string(PyBytes_AsString(intermediate),PyBytes_Size(intermediate));
+ }
+ static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
+#else
+ static std::string extract(PyObject* intermediate)
+ {
+ return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
+ }
+ static PyTypeObject const* get_pytype() { return &PyString_Type;}
+#endif
+ };
+
+#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
+ // encode_string_unaryfunc/py_encode_string -- manufacture a unaryfunc
+ // "slot" which encodes a Python string using the default encoding
+ extern "C" PyObject* encode_string_unaryfunc(PyObject* x)
+ {
+ return PyUnicode_FromEncodedObject( x, 0, 0 );
+ }
+ unaryfunc py_encode_string = encode_string_unaryfunc;
+
+ // A SlotPolicy for extracting C++ strings from Python objects.
+ struct wstring_rvalue_from_python
+ {
+ // If the underlying object is "string-able" this will succeed
+ static unaryfunc* get_slot(PyObject* obj)
+ {
+ return PyUnicode_Check(obj)
+ ? &py_object_identity
+#if PY_VERSION_HEX >= 0x03000000
+ : PyBytes_Check(obj)
+#else
+ : PyString_Check(obj)
+#endif
+ ? &py_encode_string
+ : 0;
+ };
+
+ // Remember that this will be used to construct the result object
+ static std::wstring extract(PyObject* intermediate)
+ {
+ std::wstring result(::PyObject_Length(intermediate), L' ');
+ if (!result.empty())
+ {
+ int err = PyUnicode_AsWideChar(
+#if PY_VERSION_HEX < 0x03020000
+ (PyUnicodeObject *)
+#endif
+ intermediate
+ , &result[0]
+ , result.size());
+
+ if (err == -1)
+ throw_error_already_set();
+ }
+ return result;
+ }
+ static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
+ };
+#endif
+
+ 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<double> extract(PyObject* intermediate)
+ {
+ if (PyComplex_Check(intermediate))
+ {
+ return std::complex<double>(
+ PyComplex_RealAsDouble(intermediate)
+ , PyComplex_ImagAsDouble(intermediate));
+ }
+#if PY_VERSION_HEX < 0x03000000
+ else if (PyInt_Check(intermediate))
+ {
+ return PyInt_AS_LONG(intermediate);
+ }
+#endif
+ else
+ {
+ return PyFloat_AS_DOUBLE(intermediate);
+ }
+ }
+ static PyTypeObject const* get_pytype() { return &PyComplex_Type;}
+ };
+}
+
+BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_FromStringAndSize(&x, 1);
+#else
+ return PyString_FromStringAndSize(&x, 1);
+#endif
+}
+
+BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ return x ? PyUnicode_FromString(x) : boost::python::detail::none();
+#else
+ return x ? PyString_FromString(x) : boost::python::detail::none();
+#endif
+}
+
+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<signedness U> \
+ >()
+
+#define REGISTER_INT_CONVERTERS2(U) \
+ REGISTER_INT_CONVERTERS(signed, U); \
+ REGISTER_INT_CONVERTERS(unsigned, U)
+
+void initialize_builtin_converters()
+{
+ // booleans
+ slot_rvalue_from_python<bool,bool_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<signed BOOST_PYTHON_LONG_LONG,long_long_rvalue_from_python>();
+ slot_rvalue_from_python<unsigned BOOST_PYTHON_LONG_LONG,unsigned_long_long_rvalue_from_python>();
+# endif
+
+ // floating types
+ slot_rvalue_from_python<float,float_rvalue_from_python>();
+ slot_rvalue_from_python<double,float_rvalue_from_python>();
+ slot_rvalue_from_python<long double,float_rvalue_from_python>();
+
+ slot_rvalue_from_python<std::complex<float>,complex_rvalue_from_python>();
+ slot_rvalue_from_python<std::complex<double>,complex_rvalue_from_python>();
+ slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
+
+ // Add an lvalue converter for char which gets us char const*
+#if PY_VERSION_HEX < 0x03000000
+ registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
+#else
+ registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyUnicode_Type>::get_pytype);
+#endif
+
+ // Register by-value converters to std::string, std::wstring
+#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
+ slot_rvalue_from_python<std::wstring, wstring_rvalue_from_python>();
+# endif
+ slot_rvalue_from_python<std::string, string_rvalue_from_python>();
+
+}
+
+}}} // namespace boost::python::converter
diff --git a/libs/python/src/converter/from_python.cpp b/libs/python/src/converter/from_python.cpp
new file mode 100644
index 000000000..9678be1cb
--- /dev/null
+++ b/libs/python/src/converter/from_python.cpp
@@ -0,0 +1,303 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/converter/from_python.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/converter/rvalue_from_python_data.hpp>
+
+#include <boost/python/object/find_instance.hpp>
+
+#include <boost/python/handle.hpp>
+#include <boost/python/detail/raw_pyobject.hpp>
+#include <boost/python/cast.hpp>
+
+#include <vector>
+#include <algorithm>
+
+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<T>,
+// 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, converters.is_shared_ptr);
+ data.construct = 0;
+ if (!data.convertible)
+ {
+ 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<T> object, where T is the
+// target type of the conversion.
+//
+// Requires: data.convertible == &registered<T>::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<registration const*>(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(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
+ "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<rvalue_from_python_chain const*> 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(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
+ "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(
+#if PY_VERSION_HEX >= 0x3000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
+ "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<PyObject>(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/libs/python/src/converter/registry.cpp b/libs/python/src/converter/registry.cpp
new file mode 100644
index 000000000..aa20c3f68
--- /dev/null
+++ b/libs/python/src/converter/registry.cpp
@@ -0,0 +1,306 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/converter/registry.hpp>
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/converter/builtin_converters.hpp>
+
+#include <set>
+#include <stdexcept>
+
+#if defined(__APPLE__) && defined(__MACH__) && defined(__GNUC__) \
+ && __GNUC__ == 3 && __GNUC_MINOR__ <= 4 && !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 <iostream>
+#endif
+
+namespace boost { namespace python { namespace converter {
+BOOST_PYTHON_DECL PyTypeObject const* registration::expected_from_python_type() const
+{
+ if (this->m_class_object != 0)
+ return this->m_class_object;
+
+ std::set<PyTypeObject const*> pool;
+
+ for(rvalue_from_python_chain* r = rvalue_chain; r ; r=r->next)
+ if(r->expected_pytype)
+ pool.insert(r->expected_pytype());
+
+ //for now I skip the search for common base
+ if (pool.size()==1)
+ return *pool.begin();
+
+ return 0;
+
+}
+
+BOOST_PYTHON_DECL PyTypeObject const* registration::to_python_target_type() const
+{
+ if (this->m_class_object != 0)
+ return this->m_class_object;
+
+ if (this->m_to_python_target_type != 0)
+ return this->m_to_python_target_type();
+
+ return 0;
+}
+
+BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
+{
+ if (this->m_class_object == 0)
+ {
+ ::PyErr_Format(
+ PyExc_TypeError
+ , const_cast<char*>("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(
+#if PY_VERSION_HEX >= 0x3000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
+ "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<void*>(source));
+}
+
+namespace
+{
+ template< typename T >
+ void delete_node( T* node )
+ {
+ if( !!node && !!node->next )
+ delete_node( node->next );
+ delete node;
+ }
+}
+
+registration::~registration()
+{
+ delete_node(lvalue_chain);
+ delete_node(rvalue_chain);
+}
+
+
+namespace // <unnamed>
+{
+ typedef registration entry;
+
+ typedef std::set<entry> 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, bool is_shared_ptr = false)
+ {
+# 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<registry_t::const_iterator,bool> pos_ins
+ = entries().insert(entry(type,is_shared_ptr));
+
+# if __MWERKS__ >= 0x3000
+ // do a little invariant checking if a change was made
+ if ( pos_ins.second )
+ assert(entries().invariants());
+# endif
+ return const_cast<entry*>(&*pos_ins.first);
+ }
+} // namespace <unnamed>
+
+namespace registry
+{
+ void insert(to_python_function_t f, type_info source_t, PyTypeObject const* (*to_python_target_type)())
+ {
+# ifdef BOOST_PYTHON_TRACE_REGISTRY
+ std::cout << "inserting to_python " << source_t << "\n";
+# endif
+ entry* slot = get(source_t);
+
+ assert(slot->m_to_python == 0); // we have a problem otherwise
+ if (slot->m_to_python != 0)
+ {
+ std::string msg = (
+ std::string("to-Python converter for ")
+ + source_t.name()
+ + " already registered; second conversion method ignored."
+ );
+
+ if ( ::PyErr_Warn( NULL, const_cast<char*>(msg.c_str()) ) )
+ {
+ throw_error_already_set();
+ }
+ }
+ slot->m_to_python = f;
+ slot->m_to_python_target_type = to_python_target_type;
+ }
+
+ // Insert an lvalue from_python converter
+ void insert(convertible_function convert, type_info key, PyTypeObject const* (*exp_pytype)())
+ {
+# 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,exp_pytype);
+ }
+
+ // Insert an rvalue from_python converter
+ void insert(convertible_function convertible
+ , constructor_function construct
+ , type_info key
+ , PyTypeObject const* (*exp_pytype)())
+ {
+# 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->expected_pytype = exp_pytype;
+ registration->next = found->rvalue_chain;
+ found->rvalue_chain = registration;
+ }
+
+ // Insert an rvalue from_python converter
+ void push_back(convertible_function convertible
+ , constructor_function construct
+ , type_info key
+ , PyTypeObject const* (*exp_pytype)())
+ {
+# 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->expected_pytype = exp_pytype;
+ registration->next = 0;
+ *found = registration;
+ }
+
+ registration const& lookup(type_info key)
+ {
+ return *get(key);
+ }
+
+ registration const& lookup_shared_ptr(type_info key)
+ {
+ return *get(key, true);
+ }
+
+ 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/libs/python/src/converter/type_id.cpp b/libs/python/src/converter/type_id.cpp
new file mode 100644
index 000000000..c6a8bf7a0
--- /dev/null
+++ b/libs/python/src/converter/type_id.cpp
@@ -0,0 +1,212 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/type_id.hpp>
+#include <boost/python/detail/decorated_type_id.hpp>
+#include <utility>
+#include <vector>
+#include <algorithm>
+#include <memory>
+#include <cstdlib>
+#include <cstring>
+
+#if defined(__QNXNTO__)
+# include <ostream>
+#else /* defined(__QNXNTO__) */
+
+#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT || __EDG_VERSION__
+# include <ostream>
+#else
+# include <ostream.h>
+#endif
+
+# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
+# if defined(__GNUC__) && __GNUC__ >= 3
+
+// http://lists.debian.org/debian-gcc/2003/09/msg00055.html notes
+// that, in cxxabi.h of gcc-3.x for x < 4, this type is used before it
+// is declared.
+# if __GNUC__ == 3 && __GNUC_MINOR__ < 4
+class __class_type_info;
+# endif
+
+# include <cxxabi.h>
+# endif
+# endif
+#endif /* defined(__QNXNTO__) */
+
+namespace boost { namespace python {
+
+# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
+
+# if defined(__QNXNTO__)
+namespace cxxabi {
+extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
+}
+# else /* defined(__QNXNTO__) */
+
+# ifdef __GNUC__
+# if __GNUC__ < 3
+
+namespace cxxabi = :: ;
+extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
+# else
+
+namespace cxxabi = ::abi; // GCC 3.1 and later
+
+# if __GNUC__ == 3 && __GNUC_MINOR__ == 0
+namespace abi
+{
+ extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
+}
+# endif /* __GNUC__ == 3 && __GNUC_MINOR__ == 0 */
+# endif /* __GNUC__ < 3 */
+# endif /* __GNUC__ */
+# endif /* defined(__QNXNTO__) */
+
+namespace
+{
+ struct compare_first_cstring
+ {
+ template <class T>
+ 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;
+ };
+}
+
+bool cxxabi_cxa_demangle_is_broken()
+{
+ static bool was_tested = false;
+ static bool is_broken = false;
+ if (!was_tested) {
+ int status;
+ free_mem keeper(cxxabi::__cxa_demangle("b", 0, 0, &status));
+ was_tested = true;
+ if (status == -2 || strcmp(keeper.p, "bool") != 0) {
+ is_broken = true;
+ }
+ }
+ return is_broken;
+}
+
+namespace detail
+{
+ BOOST_PYTHON_DECL char const* gcc_demangle(char const* mangled)
+ {
+ typedef std::vector<
+ std::pair<char const*, char const*>
+ > 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;
+
+ // Ult Mundane, 2005 Aug 17
+ // Contributed under the Boost Software License, Version 1.0.
+ // (See accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+ // The __cxa_demangle function is supposed to translate
+ // builtin types from their one-character mangled names,
+ // but it doesn't in gcc 3.3.5 and gcc 3.4.x.
+ if (cxxabi_cxa_demangle_is_broken()
+ && status == -2 && strlen(mangled) == 1)
+ {
+ // list from
+ // http://www.codesourcery.com/cxx-abi/abi.html
+ switch (mangled[0])
+ {
+ case 'v': demangled = "void"; break;
+ case 'w': demangled = "wchar_t"; break;
+ case 'b': demangled = "bool"; break;
+ case 'c': demangled = "char"; break;
+ case 'a': demangled = "signed char"; break;
+ case 'h': demangled = "unsigned char"; break;
+ case 's': demangled = "short"; break;
+ case 't': demangled = "unsigned short"; break;
+ case 'i': demangled = "int"; break;
+ case 'j': demangled = "unsigned int"; break;
+ case 'l': demangled = "long"; break;
+ case 'm': demangled = "unsigned long"; break;
+ case 'x': demangled = "long long"; break;
+ case 'y': demangled = "unsigned long long"; break;
+ case 'n': demangled = "__int128"; break;
+ case 'o': demangled = "unsigned __int128"; break;
+ case 'f': demangled = "float"; break;
+ case 'd': demangled = "double"; break;
+ case 'e': demangled = "long double"; break;
+ case 'g': demangled = "__float128"; break;
+ case 'z': demangled = "..."; break;
+ }
+ }
+
+ 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/libs/python/src/dict.cpp b/libs/python/src/dict.cpp
new file mode 100644
index 000000000..77d840d45
--- /dev/null
+++ b/libs/python/src/dict.cpp
@@ -0,0 +1,184 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/dict.hpp>
+#include <boost/python/extract.hpp>
+
+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, const_cast<char*>("(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<bool>(this->contains(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")());
+ }
+}
+
+static struct register_dict_pytype_ptr
+{
+ register_dict_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::dict>())
+ ).m_class_object = &PyDict_Type;
+ }
+}register_dict_pytype_ptr_;
+
+}}} // namespace boost::python
diff --git a/libs/python/src/errors.cpp b/libs/python/src/errors.cpp
new file mode 100644
index 000000000..34ea22f43
--- /dev/null
+++ b/libs/python/src/errors.cpp
@@ -0,0 +1,105 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PYTHON_SOURCE
+# define BOOST_PYTHON_SOURCE
+#endif
+
+#include <boost/python/errors.hpp>
+#include <boost/cast.hpp>
+#include <boost/python/detail/exception_handler.hpp>
+
+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<void> 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::out_of_range& x)
+ {
+ PyErr_SetString(PyExc_IndexError, x.what());
+ }
+ catch(const std::invalid_argument& x)
+ {
+ PyErr_SetString(PyExc_ValueError, 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<void> 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/libs/python/src/exec.cpp b/libs/python/src/exec.cpp
new file mode 100644
index 000000000..9fe1b23b7
--- /dev/null
+++ b/libs/python/src/exec.cpp
@@ -0,0 +1,108 @@
+// Copyright Stefan Seefeld 2005.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/exec.hpp>
+#include <boost/python/borrowed.hpp>
+#include <boost/python/dict.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/handle.hpp>
+
+namespace boost
+{
+namespace python
+{
+
+object BOOST_PYTHON_DECL eval(str string, object global, object local)
+{
+ // Set suitable default values for global and local dicts.
+ if (global.is_none())
+ {
+ if (PyObject *g = PyEval_GetGlobals())
+ global = object(detail::borrowed_reference(g));
+ else
+ global = dict();
+ }
+ if (local.is_none()) local = global;
+ // should be 'char const *' but older python versions don't use 'const' yet.
+ char *s = python::extract<char *>(string);
+ PyObject* result = PyRun_String(s, Py_eval_input, global.ptr(), local.ptr());
+ if (!result) throw_error_already_set();
+ return object(detail::new_reference(result));
+}
+
+object BOOST_PYTHON_DECL exec(str string, object global, object local)
+{
+ // Set suitable default values for global and local dicts.
+ if (global.is_none())
+ {
+ if (PyObject *g = PyEval_GetGlobals())
+ global = object(detail::borrowed_reference(g));
+ else
+ global = dict();
+ }
+ if (local.is_none()) local = global;
+ // should be 'char const *' but older python versions don't use 'const' yet.
+ char *s = python::extract<char *>(string);
+ PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
+ if (!result) throw_error_already_set();
+ return object(detail::new_reference(result));
+}
+
+object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
+{
+ // Set suitable default values for global and local dicts.
+ if (global.is_none())
+ {
+ if (PyObject *g = PyEval_GetGlobals())
+ global = object(detail::borrowed_reference(g));
+ else
+ global = dict();
+ }
+ if (local.is_none()) local = global;
+ // should be 'char const *' but older python versions don't use 'const' yet.
+ char *s = python::extract<char *>(string);
+ PyObject* result = PyRun_String(s, Py_single_input, global.ptr(), local.ptr());
+ if (!result) throw_error_already_set();
+ return object(detail::new_reference(result));
+}
+
+// Execute python source code from file filename.
+// global and local are the global and local scopes respectively,
+// used during execution.
+object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
+{
+ // Set suitable default values for global and local dicts.
+ if (global.is_none())
+ {
+ if (PyObject *g = PyEval_GetGlobals())
+ global = object(detail::borrowed_reference(g));
+ else
+ global = dict();
+ }
+ if (local.is_none()) local = global;
+ // should be 'char const *' but older python versions don't use 'const' yet.
+ char *f = python::extract<char *>(filename);
+#if PY_VERSION_HEX >= 0x03000000
+ // TODO(bhy) temporary workaround for Python 3.
+ // should figure out a way to avoid binary incompatibilities as the Python 2
+ // version did.
+ FILE *fs = fopen(f, "r");
+#else
+ // Let python open the file to avoid potential binary incompatibilities.
+ PyObject *pyfile = PyFile_FromString(f, const_cast<char*>("r"));
+ if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
+ python::handle<> file(pyfile);
+ FILE *fs = PyFile_AsFile(file.get());
+#endif
+ PyObject* result = PyRun_File(fs,
+ f,
+ Py_file_input,
+ global.ptr(), local.ptr());
+ if (!result) throw_error_already_set();
+ return object(detail::new_reference(result));
+}
+
+} // namespace boost::python
+} // namespace boost
diff --git a/libs/python/src/import.cpp b/libs/python/src/import.cpp
new file mode 100644
index 000000000..0add79eea
--- /dev/null
+++ b/libs/python/src/import.cpp
@@ -0,0 +1,25 @@
+// Copyright Stefan Seefeld 2005.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/import.hpp>
+#include <boost/python/borrowed.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/handle.hpp>
+
+namespace boost
+{
+namespace python
+{
+
+object BOOST_PYTHON_DECL import(str name)
+{
+ // should be 'char const *' but older python versions don't use 'const' yet.
+ char *n = python::extract<char *>(name);
+ python::handle<> module(PyImport_ImportModule(n));
+ return python::object(module);
+}
+
+} // namespace boost::python
+} // namespace boost
diff --git a/libs/python/src/list.cpp b/libs/python/src/list.cpp
new file mode 100644
index 000000000..77e616881
--- /dev/null
+++ b/libs/python/src/list.cpp
@@ -0,0 +1,170 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/list.hpp>
+#include <boost/python/ssize_t.hpp>
+
+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, const_cast<char*>("(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));
+#if PY_VERSION_HEX >= 0x03000000
+ ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
+#else
+ long result = PyInt_AsLong(result_obj.ptr());
+#endif
+ if (result == -1)
+ throw_error_already_set();
+ return result;
+}
+
+void list_base::insert(ssize_t 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)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ ssize_t index_ = PyLong_AsSsize_t(index.ptr());
+#else
+ long index_ = PyInt_AsLong(index.ptr());
+#endif
+ 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(ssize_t 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")();
+ }
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+void list_base::sort(args_proxy const &args,
+ kwds_proxy const &kwds)
+{
+ this->attr("sort")(args, kwds);
+}
+#else
+void list_base::sort(object_cref cmpfunc)
+{
+ this->attr("sort")(cmpfunc);
+}
+#endif
+
+// For some reason, moving this to the end of the TU suppresses an ICE
+// with vc6.
+ssize_t list_base::count(object_cref value) const
+{
+ object result_obj(this->attr("count")(value));
+#if PY_VERSION_HEX >= 0x03000000
+ ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
+#else
+ long result = PyInt_AsLong(result_obj.ptr());
+#endif
+ if (result == -1)
+ throw_error_already_set();
+ return result;
+}
+
+static struct register_list_pytype_ptr
+{
+ register_list_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::list>())
+ ).m_class_object = &PyList_Type;
+ }
+}register_list_pytype_ptr_;
+
+}}} // namespace boost::python
diff --git a/libs/python/src/long.cpp b/libs/python/src/long.cpp
new file mode 100644
index 000000000..1ec8ebc01
--- /dev/null
+++ b/libs/python/src/long.cpp
@@ -0,0 +1,39 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/long.hpp>
+
+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, const_cast<char*>("(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, const_cast<char*>("(OO)"),
+ arg_.ptr(), base.ptr());
+}
+
+long_base::long_base()
+ : object(
+ detail::new_reference(
+ PyObject_CallFunction((PyObject*)&PyLong_Type, const_cast<char*>("()")))
+ )
+{}
+
+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/libs/python/src/module.cpp b/libs/python/src/module.cpp
new file mode 100644
index 000000000..962848199
--- /dev/null
+++ b/libs/python/src/module.cpp
@@ -0,0 +1,73 @@
+// (C) Copyright David Abrahams 2000.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// The author gratefully acknowleges the support of Dragon Systems, Inc., in
+// producing this work.
+
+#include <boost/python/scope.hpp>
+#include <boost/python/object/add_to_namespace.hpp>
+
+namespace boost { namespace python { namespace detail {
+
+namespace
+{
+ PyObject* init_module_in_scope(PyObject* m, void(*init_function)())
+ {
+ if (m != 0)
+ {
+ // Create the current module scope
+ object m_obj(((borrowed_reference_t*)m));
+ scope current_module(m_obj);
+
+ handle_exception(init_function);
+ }
+
+ return m;
+ }
+}
+
+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);
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+
+BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef& moduledef, void(*init_function)())
+{
+ return init_module_in_scope(
+ PyModule_Create(&moduledef),
+ init_function);
+}
+
+#else
+
+namespace
+{
+ PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
+}
+
+BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*init_function)())
+{
+ return init_module_in_scope(
+ Py_InitModule(const_cast<char*>(name), initial_methods),
+ init_function);
+}
+
+#endif
+
+}}} // namespace boost::python::detail
+
+namespace boost { namespace python {
+
+namespace detail
+{
+ BOOST_PYTHON_DECL PyObject* current_scope = 0;
+}
+
+}}
diff --git a/libs/python/src/numeric.cpp b/libs/python/src/numeric.cpp
new file mode 100644
index 000000000..c8a5f071d
--- /dev/null
+++ b/libs/python/src/numeric.cpp
@@ -0,0 +1,325 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/numeric.hpp>
+#include <boost/python/handle.hpp>
+#include <boost/python/cast.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/detail/raw_pyobject.hpp>
+#include <boost/python/extract.hpp>
+
+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<char*>(type_name.c_str()));
+
+ if (type && PyType_Check(type))
+ {
+ array_type = handle<>(type);
+ PyObject* function = ::PyObject_GetAttrString(module, const_cast<char*>("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 : "" ;
+}
+
+std::string array::get_module_name()
+{
+ load(false);
+ return module_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<PyTypeObject>(array_type.get()), obj));
+ }
+
+ PyTypeObject const* array_object_manager_traits::get_pytype()
+ {
+ load(false);
+ if(!array_type) return 0;
+ return downcast<PyTypeObject>(array_type.get());
+ }
+
+# 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<bool>(attr("is_c_array")());
+ }
+
+ bool array_base::isbyteswapped() const
+ {
+ return extract<bool>(attr("isbyteswapped")());
+ }
+
+ array array_base::new_(object type) const
+ {
+ return extract<array>(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<char>(attr("typecode")());
+ }
+
+ object array_base::factory(
+ object const& sequence
+ , object const& typecode
+ , bool copy
+ , bool savespace
+ , object type
+ , object shape
+ )
+ {
+ return attr("factory")(sequence, typecode, copy, savespace, type, shape);
+ }
+
+ object array_base::getflat() const
+ {
+ return attr("getflat")();
+ }
+
+ long array_base::getrank() const
+ {
+ return extract<long>(attr("getrank")());
+ }
+
+ object array_base::getshape() const
+ {
+ return attr("getshape")();
+ }
+
+ bool array_base::isaligned() const
+ {
+ return extract<bool>(attr("isaligned")());
+ }
+
+ bool array_base::iscontiguous() const
+ {
+ return extract<bool>(attr("iscontiguous")());
+ }
+
+ long array_base::itemsize() const
+ {
+ return extract<long>(attr("itemsize")());
+ }
+
+ long array_base::nelements() const
+ {
+ return extract<long>(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/libs/python/src/object/class.cpp b/libs/python/src/object/class.cpp
new file mode 100644
index 000000000..aeef688e2
--- /dev/null
+++ b/libs/python/src/object/class.cpp
@@ -0,0 +1,764 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/detail/prefix.hpp>
+#include <boost/mpl/lambda.hpp> // #including this first is an intel6 workaround
+
+#include <boost/python/object/class.hpp>
+#include <boost/python/object/instance.hpp>
+#include <boost/python/object/class_detail.hpp>
+#include <boost/python/scope.hpp>
+#include <boost/python/converter/registry.hpp>
+#include <boost/python/object/find_instance.hpp>
+#include <boost/python/object/pickle_support.hpp>
+#include <boost/python/detail/map_entry.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/object_protocol.hpp>
+#include <boost/detail/binary_search.hpp>
+#include <boost/python/self.hpp>
+#include <boost/python/dict.hpp>
+#include <boost/python/str.hpp>
+#include <boost/python/ssize_t.hpp>
+#include <functional>
+#include <vector>
+#include <cstddef>
+#include <new>
+#include <structmember.h>
+
+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;
+ int getter_doc;
+ } propertyobject;
+
+ // Copied from Python source and removed the part for setting docstring,
+ // since we don't have a setter for __doc__ and trying to set it will
+ // cause the init fail.
+ static int property_init(PyObject *self, PyObject *args, PyObject *kwds)
+ {
+ PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
+ static const char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
+ propertyobject *prop = (propertyobject *)self;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
+ const_cast<char **>(kwlist), &get, &set, &del, &doc))
+ return -1;
+
+ if (get == Py_None)
+ get = NULL;
+ if (set == Py_None)
+ set = NULL;
+ if (del == Py_None)
+ del = NULL;
+
+ Py_XINCREF(get);
+ Py_XINCREF(set);
+ Py_XINCREF(del);
+ Py_XINCREF(doc);
+
+ prop->prop_get = get;
+ prop->prop_set = set;
+ prop->prop_del = del;
+ prop->prop_doc = doc;
+ prop->getter_doc = 0;
+
+ return 0;
+ }
+
+
+ static PyObject *
+ static_data_descr_get(PyObject *self, PyObject * /*obj*/, PyObject * /*type*/)
+ {
+ propertyobject *gs = (propertyobject *)self;
+
+ return PyObject_CallFunction(gs->prop_get, const_cast<char*>("()"));
+ }
+
+ 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, const_cast<char*>("()"));
+ else
+ res = PyObject_CallFunction(func, const_cast<char*>("(O)"), value);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+ }
+}
+
+static PyTypeObject static_data_object = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ const_cast<char*>("Boost.Python.StaticProperty"),
+ sizeof(propertyobject),
+ 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 */
+ property_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, // filled in with type_new /* tp_new */
+ 0, // filled in with __PyObject_GC_Del /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+};
+
+namespace objects
+{
+#if PY_VERSION_HEX < 0x03000000
+ // XXX Not sure why this run into compiling error in Python 3
+ extern "C"
+ {
+ // This declaration needed due to broken Python 2.2 headers
+ extern DL_IMPORT(PyTypeObject) PyProperty_Type;
+ }
+#endif
+
+ BOOST_PYTHON_DECL PyObject* static_data()
+ {
+ if (static_data_object.tp_dict == 0)
+ {
+ Py_TYPE(&static_data_object) = &PyType_Type;
+ static_data_object.tp_base = &PyProperty_Type;
+ if (PyType_Ready(&static_data_object))
+ return 0;
+ }
+ return upcast<PyObject>(&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<PyTypeObject>(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 Py_TYPE(a)->tp_descr_set(a, obj, value);
+ else
+ return PyType_Type.tp_setattro(obj, name, value);
+ }
+}
+
+static PyTypeObject class_metatype_object = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ const_cast<char*>("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 */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+};
+
+// Install the instance data for a C++ object into a Python instance
+// object.
+void instance_holder::install(PyObject* self) throw()
+{
+ assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self)), &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)
+ {
+ Py_TYPE(&class_metatype_object) = &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<void*>(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);
+
+ Py_TYPE(inst)->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, const_cast<char*>("__instance_size__"));
+
+ ssize_t instance_size = instance_size_obj ?
+#if PY_VERSION_HEX >= 0x03000000
+ PyLong_AsSsize_t(instance_size_obj) : 0;
+#else
+ PyInt_AsLong(instance_size_obj) : 0;
+#endif
+
+ 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.
+#if PY_VERSION_HEX >= 0x02060000
+ Py_SIZE(result) =
+#else
+ result->ob_size =
+#endif
+ -(static_cast<int>(offsetof(instance<>,storage) + instance_size));
+ }
+ return (PyObject*)result;
+ }
+
+ static PyObject* instance_get_dict(PyObject* op, void*)
+ {
+ instance<>* inst = downcast<instance<> >(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<instance<> >(op);
+ python::xdecref(inst->dict);
+ inst->dict = python::incref(dict);
+ return 0;
+ }
+
+ }
+
+
+ static PyGetSetDef instance_getsets[] = {
+ {const_cast<char*>("__dict__"), instance_get_dict, instance_set_dict, NULL, 0},
+ {0, 0, 0, 0, 0}
+ };
+
+
+ static PyMemberDef instance_members[] = {
+ {const_cast<char*>("__weakref__"), T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
+ {0, 0, 0, 0, 0}
+ };
+
+ static PyTypeObject class_type_object = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ const_cast<char*>("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 */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+ };
+
+ BOOST_PYTHON_DECL type_handle class_type()
+ {
+ if (class_type_object.tp_dict == 0)
+ {
+ Py_TYPE(&class_type_object) = 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, bool null_shared_ptr_only)
+ {
+ if (!Py_TYPE(Py_TYPE(inst)) ||
+ !PyType_IsSubtype(Py_TYPE(Py_TYPE(inst)), &class_metatype_object))
+ return 0;
+
+ instance<>* self = reinterpret_cast<instance<>*>(inst);
+
+ for (instance_holder* match = self->objects; match != 0; match = match->next())
+ {
+ void* const found = match->holds(type, null_shared_ptr_only);
+ if (found)
+ return found;
+ }
+ return 0;
+ }
+
+ object module_prefix()
+ {
+ return object(
+ PyObject_IsInstance(scope().ptr(), upcast<PyObject>(&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.
+ ssize_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
+ handle<> bases(PyTuple_New(num_bases));
+
+ for (ssize_t i = 1; i <= num_bases; ++i)
+ {
+ type_handle c = (i >= static_cast<ssize_t>(num_types)) ? class_type() : get_class(types[i]);
+ // PyTuple_SET_ITEM steals this reference
+ PyTuple_SET_ITEM(bases.get(), static_cast<ssize_t>(i - 1), upcast<PyObject>(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(Py_TYPE(result.ptr()), &PyType_Type));
+
+ if (scope().ptr() != Py_None)
+ scope().attr(name) = result;
+
+ // For pickle. Will lead to informative error messages if pickling
+ // is not enabled.
+ result.attr("__reduce__") = object(make_instance_reduce_function());
+
+ 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::registration&>(
+ 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::registration&>(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, char const* docstr)
+ {
+ object property(
+ (python::detail::new_reference)
+ PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
+
+ this->setattr(name, property);
+ }
+
+ void class_base::add_property(
+ char const* name, object const& fget, object const& fset, char const* docstr)
+ {
+ object property(
+ (python::detail::new_reference)
+ PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
+
+ 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(), const_cast<char*>("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(), const_cast<char*>("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<char*>(name), x.ptr()) < 0)
+ throw_error_already_set();
+ }
+
+ namespace
+ {
+ extern "C" PyObject* no_init(PyObject*, PyObject*)
+ {
+ ::PyErr_SetString(::PyExc_RuntimeError, const_cast<char*>("This class cannot be instantiated from Python"));
+ return NULL;
+ }
+ static ::PyMethodDef no_init_def = {
+ const_cast<char*>("__init__"), no_init, METH_VARARGS,
+ const_cast<char*>("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("__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
+ , const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
+ , Py_TYPE(callable)->tp_name
+ );
+
+ throw_error_already_set();
+ return 0;
+ }
+ }
+
+ void class_base::make_method_static(const char * method_name)
+ {
+ PyTypeObject* self = downcast<PyTypeObject>(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(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
+ objects::instance<>* self = (objects::instance<>*)self_;
+
+ int total_size_needed = holder_offset + holder_size;
+
+ if (-Py_SIZE(self) >= 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
+ Py_SIZE(self) = 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(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
+ objects::instance<>* self = (objects::instance<>*)self_;
+ if (storage != (char*)self + Py_SIZE(self))
+ {
+ PyMem_Free(storage);
+ }
+}
+
+}} // namespace boost::python
diff --git a/libs/python/src/object/enum.cpp b/libs/python/src/object/enum.cpp
new file mode 100644
index 000000000..3063320cb
--- /dev/null
+++ b/libs/python/src/object/enum.cpp
@@ -0,0 +1,246 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/object/enum_base.hpp>
+#include <boost/python/cast.hpp>
+#include <boost/python/scope.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/dict.hpp>
+#include <boost/python/str.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/object_protocol.hpp>
+#include <structmember.h>
+
+namespace boost { namespace python { namespace objects {
+
+struct enum_object
+{
+#if PY_VERSION_HEX >= 0x03000000
+ PyLongObject base_object;
+#else
+ PyIntObject base_object;
+#endif
+ PyObject* name;
+};
+
+static PyMemberDef enum_members[] = {
+ {const_cast<char*>("name"), T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
+ {0, 0, 0, 0, 0}
+};
+
+
+extern "C"
+{
+ static PyObject* enum_repr(PyObject* self_)
+ {
+ // XXX(bhy) Potentional memory leak here since PyObject_GetAttrString returns a new reference
+ // const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
+ PyObject *mod = PyObject_GetAttrString( self_, "__module__");
+ enum_object* self = downcast<enum_object>(self_);
+ if (!self->name)
+ {
+ return
+#if PY_VERSION_HEX >= 0x03000000
+ PyUnicode_FromFormat("%S.%s(%ld)", mod, self_->ob_type->tp_name, PyLong_AsLong(self_));
+#else
+ PyString_FromFormat("%s.%s(%ld)", PyString_AsString(mod), self_->ob_type->tp_name, PyInt_AS_LONG(self_));
+#endif
+ }
+ else
+ {
+ PyObject* name = self->name;
+ if (name == 0)
+ return 0;
+
+ return
+#if PY_VERSION_HEX >= 0x03000000
+ PyUnicode_FromFormat("%S.%s.%S", mod, self_->ob_type->tp_name, name);
+#else
+ PyString_FromFormat("%s.%s.%s",
+ PyString_AsString(mod), self_->ob_type->tp_name, PyString_AsString(name));
+#endif
+ }
+ }
+
+ static PyObject* enum_str(PyObject* self_)
+ {
+ enum_object* self = downcast<enum_object>(self_);
+ if (!self->name)
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyLong_Type.tp_str(self_);
+#else
+ return PyInt_Type.tp_str(self_);
+#endif
+ }
+ else
+ {
+ return incref(self->name);
+ }
+ }
+}
+
+static PyTypeObject enum_type_object = {
+ PyVarObject_HEAD_INIT(NULL, 0) // &PyType_Type
+ const_cast<char*>("Boost.Python.enum"),
+ sizeof(enum_object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* 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
+#if PY_VERSION_HEX < 0x03000000
+ | Py_TPFLAGS_CHECKTYPES
+#endif
+ | 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 */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+};
+
+object module_prefix();
+
+namespace
+{
+ object new_enum_type(char const* name, char const *doc)
+ {
+ if (enum_type_object.tp_dict == 0)
+ {
+ Py_TYPE(&enum_type_object) = incref(&PyType_Type);
+#if PY_VERSION_HEX >= 0x03000000
+ enum_type_object.tp_base = &PyLong_Type;
+#else
+ enum_type_object.tp_base = &PyInt_Type;
+#endif
+ 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();
+ d["names"] = dict();
+
+ object module_name = module_prefix();
+ if (module_name)
+ d["__module__"] = module_name;
+ if (doc)
+ d["__doc__"] = doc;
+
+ object result = (object(metatype))(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
+ , char const *doc
+ )
+ : object(new_enum_type(name, doc))
+{
+ converter::registration& converters
+ = const_cast<converter::registration&>(
+ converter::registry::lookup(id));
+
+ converters.m_class_object = downcast<PyTypeObject>(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<dict>(this->attr("values"))();
+ d[value] = x;
+
+ // Set the name field in the new enum instanec
+ enum_object* p = downcast<enum_object>(x.ptr());
+ Py_XDECREF(p->name);
+ p->name = incref(name.ptr());
+
+ dict names_dict = extract<dict>(this->attr("names"))();
+ names_dict[x.attr("name")] = x;
+}
+
+void enum_base::export_values()
+{
+ dict d = extract<dict>(this->attr("names"))();
+ list items = d.items();
+ scope current;
+
+ for (unsigned i = 0, max = len(items); i < max; ++i)
+ api::setattr(current, items[i][0], items[i][1]);
+ }
+
+PyObject* enum_base::to_python(PyTypeObject* type_, long x)
+{
+ object type((type_handle(borrowed(type_))));
+
+ dict d = extract<dict>(type.attr("values"))();
+ object v = d.get(x, object());
+ return incref(
+ (v == object() ? type(x) : v).ptr());
+}
+
+}}} // namespace boost::python::object
diff --git a/libs/python/src/object/function.cpp b/libs/python/src/object/function.cpp
new file mode 100644
index 000000000..5c59cc779
--- /dev/null
+++ b/libs/python/src/object/function.cpp
@@ -0,0 +1,793 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/docstring_options.hpp>
+#include <boost/python/object/function_object.hpp>
+#include <boost/python/object/function_handle.hpp>
+#include <boost/python/object/function_doc_signature.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/str.hpp>
+#include <boost/python/object_attributes.hpp>
+#include <boost/python/args.hpp>
+#include <boost/python/refcount.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/list.hpp>
+#include <boost/python/ssize_t.hpp>
+
+#include <boost/python/detail/signature.hpp>
+#include <boost/python/detail/none.hpp>
+#include <boost/mpl/vector/vector10.hpp>
+
+#include <boost/bind.hpp>
+
+#include <algorithm>
+#include <cstring>
+
+#if BOOST_PYTHON_DEBUG_ERROR_MESSAGES
+# include <cstdio>
+#endif
+
+namespace boost { namespace python {
+ volatile bool docstring_options::show_user_defined_ = true;
+ volatile bool docstring_options::show_cpp_signatures_ = true;
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ volatile bool docstring_options::show_py_signatures_ = true;
+#else
+ volatile bool docstring_options::show_py_signatures_ = false;
+#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;
+
+
+ ssize_t 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 (Py_TYPE(&function_type) == 0)
+ {
+ Py_TYPE(&function_type) = &PyType_Type;
+ ::PyType_Ready(&function_type);
+ }
+
+ (void)( // warning suppression for GCC
+ 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.is_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
+ assert(max_arity <= static_cast<std::size_t>(ssize_t_max));
+ inner_args = handle<>(
+ PyTuple_New(static_cast<ssize_t>(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;
+}
+
+object function::signature(bool show_return_type) const
+{
+ py_function const& impl = m_fn;
+
+ python::detail::signature_element const* return_type = impl.signature();
+ python::detail::signature_element const* s = return_type + 1;
+
+ list formal_params;
+ if (impl.max_arity() == 0)
+ formal_params.append("void");
+
+ for (unsigned n = 0; n < impl.max_arity(); ++n)
+ {
+ if (s[n].basename == 0)
+ {
+ formal_params.append("...");
+ break;
+ }
+
+ str param(s[n].basename);
+ if (s[n].lvalue)
+ param += " {lvalue}";
+
+ if (m_arg_names) // None or empty tuple will test false
+ {
+ object kv(m_arg_names[n]);
+ if (kv)
+ {
+ char const* const fmt = len(kv) > 1 ? " %s=%r" : " %s";
+ param += fmt % kv;
+ }
+ }
+
+ formal_params.append(param);
+ }
+
+ if (show_return_type)
+ return "%s(%s) -> %s" % make_tuple(
+ m_name, str(", ").join(formal_params), return_type->basename);
+ return "%s(%s)" % make_tuple(
+ m_name, str(", ").join(formal_params));
+}
+
+object function::signatures(bool show_return_type) const
+{
+ list result;
+ for (function const* f = this; f; f = f->m_overloads.get()) {
+ result.append(f->signature(show_return_type));
+ }
+ return result;
+}
+
+void function::argument_error(PyObject* args, PyObject* /*keywords*/) const
+{
+ static handle<> exception(
+ PyErr_NewException(const_cast<char*>("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_args;
+ for (ssize_t i = 0; i < PyTuple_Size(args); ++i)
+ {
+ char const* name = PyTuple_GetItem(args, i)->ob_type->tp_name;
+ actual_args.append(str(name));
+ }
+ message += str(", ").join(actual_args);
+ message += ")\ndid not match C++ signature:\n ";
+ message += str("\n ").join(signatures());
+
+#if BOOST_PYTHON_DEBUG_ERROR_MESSAGES
+ std::printf("\n--------\n%s\n--------\n", extract<const char*>(message)());
+#endif
+ PyErr_SetObject(exception.get(), message.ptr());
+ throw_error_already_set();
+}
+
+void function::add_overload(handle<function> 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<function> not_implemented_function()
+ {
+
+ static object keeper(
+ function_object(
+ py_function(&not_implemented, mpl::vector1<void>(), 2)
+ , python::detail::keyword_range())
+ );
+ return handle<function>(borrowed(downcast<function>(keeper.ptr())));
+ }
+}
+
+void function::add_to_namespace(
+ object const& name_space, char const* name_, object const& attribute)
+{
+ add_to_namespace(name_space, name_, attribute, 0);
+}
+
+namespace detail
+{
+ extern char py_signature_tag[];
+ extern char cpp_signature_tag[];
+}
+
+void function::add_to_namespace(
+ object const& name_space, char const* name_, object const& attribute, char const* doc)
+{
+ str const name(name_);
+ PyObject* const ns = name_space.ptr();
+
+ if (attribute.ptr()->ob_type == &function_type)
+ {
+ function* new_func = downcast<function>(attribute.ptr());
+ handle<> dict;
+
+#if PY_VERSION_HEX < 0x03000000
+ // Old-style class gone in Python 3
+ if (PyClass_Check(ns))
+ dict = handle<>(borrowed(((PyClassObject*)ns)->cl_dict));
+ else
+#endif
+ if (PyType_Check(ns))
+ dict = handle<>(borrowed(((PyTypeObject*)ns)->tp_dict));
+ else
+ dict = handle<>(PyObject_GetAttrString(ns, const_cast<char*>("__dict__")));
+
+ if (dict == 0)
+ throw_error_already_set();
+
+ handle<> existing(allow_null(::PyObject_GetItem(dict.get(), name.ptr())));
+
+ if (existing)
+ {
+ if (existing->ob_type == &function_type)
+ {
+ new_func->add_overload(
+ handle<function>(
+ borrowed(
+ downcast<function>(existing.get())
+ )
+ )
+ );
+ }
+ else if (existing->ob_type == &PyStaticMethod_Type)
+ {
+ char const* name_space_name = extract<char const*>(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().is_none())
+ new_func->m_name = name;
+
+ handle<> name_space_name(
+ allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__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();
+
+ object mutable_attribute(attribute);
+/*
+ if (doc != 0 && docstring_options::show_user_defined_)
+ {
+ // Accumulate documentation
+
+ if (
+ PyObject_HasAttrString(mutable_attribute.ptr(), "__doc__")
+ && mutable_attribute.attr("__doc__"))
+ {
+ mutable_attribute.attr("__doc__") += "\n\n";
+ mutable_attribute.attr("__doc__") += doc;
+ }
+ else {
+ mutable_attribute.attr("__doc__") = doc;
+ }
+ }
+
+ if (docstring_options::show_signatures_)
+ {
+ if ( PyObject_HasAttrString(mutable_attribute.ptr(), "__doc__")
+ && mutable_attribute.attr("__doc__")) {
+ mutable_attribute.attr("__doc__") += (
+ mutable_attribute.attr("__doc__")[-1] != "\n" ? "\n\n" : "\n");
+ }
+ else {
+ mutable_attribute.attr("__doc__") = "";
+ }
+ function* f = downcast<function>(attribute.ptr());
+ mutable_attribute.attr("__doc__") += str("\n ").join(make_tuple(
+ "C++ signature:", f->signature(true)));
+ }
+ */
+ str _doc;
+
+ if (docstring_options::show_py_signatures_)
+ {
+ _doc += str(const_cast<const char*>(detail::py_signature_tag));
+ }
+ if (doc != 0 && docstring_options::show_user_defined_)
+ _doc += doc;
+
+ if (docstring_options::show_cpp_signatures_)
+ {
+ _doc += str(const_cast<const char*>(detail::cpp_signature_tag));
+ }
+ if(_doc)
+ {
+ object mutable_attribute(attribute);
+ mutable_attribute.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, 0);
+}
+
+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 PY_VERSION_HEX >= 0x03000000
+ // The implement is different in Python 3 because of the removal of unbound method
+ if (obj == Py_None || obj == NULL) {
+ Py_INCREF(func);
+ return func;
+ }
+ return PyMethod_New(func, obj);
+#else
+ if (obj == Py_None)
+ obj = NULL;
+ return PyMethod_New(func, obj, type_);
+#endif
+ }
+
+ static void
+ function_dealloc(PyObject* p)
+ {
+ delete static_cast<function*>(p);
+ }
+
+ static PyObject *
+ function_call(PyObject *func, PyObject *args, PyObject *kw)
+ {
+ PyObject* result = 0;
+ handle_exception(bind_return(result, static_cast<function*>(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<function>(op);
+ list signatures = function_doc_signature_generator::function_doc_signatures(f);
+ if(!signatures) return python::detail::none();
+ signatures.reverse();
+ return python::incref( str("\n").join(signatures).ptr());
+ }
+
+ static int function_set_doc(PyObject* op, PyObject* doc, void*)
+ {
+ function* f = downcast<function>(op);
+ f->doc(doc ? object(python::detail::borrowed_reference(doc)) : object());
+ return 0;
+ }
+
+ static PyObject* function_get_name(PyObject* op, void*)
+ {
+ function* f = downcast<function>(op);
+ if (f->name().is_none())
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_InternFromString("<unnamed Boost.Python function>");
+#else
+ return PyString_InternFromString("<unnamed Boost.Python function>");
+#endif
+ else
+ return python::incref(f->name().ptr());
+ }
+
+ // We add a dummy __class__ attribute in order to fool PyDoc into
+ // treating these as built-in functions and scanning their
+ // documentation
+ static PyObject* function_get_class(PyObject* /*op*/, void*)
+ {
+ return python::incref(upcast<PyObject>(&PyCFunction_Type));
+ }
+
+ static PyObject* function_get_module(PyObject* op, void*)
+ {
+ function* f = downcast<function>(op);
+ object const& ns = f->get_namespace();
+ if (!ns.is_none()) {
+ return python::incref(ns.ptr());
+ }
+ PyErr_SetString(
+ PyExc_AttributeError, const_cast<char*>(
+ "Boost.Python function __module__ unknown."));
+ return 0;
+ }
+}
+
+static PyGetSetDef function_getsetlist[] = {
+ {const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
+ {const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
+ {const_cast<char*>("__module__"), (getter)function_get_module, 0, 0, 0 },
+ {const_cast<char*>("func_module"), (getter)function_get_module, 0, 0, 0 },
+ {const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
+ {const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
+ {const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
+ {NULL, 0, 0, 0, 0} /* Sentinel */
+};
+
+PyTypeObject function_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ const_cast<char*>("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, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+};
+
+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, const_cast<char*>("Pure virtual function called"));
+ throw_error_already_set();
+ }
+}
+
+}} // namespace boost::python
diff --git a/libs/python/src/object/function_doc_signature.cpp b/libs/python/src/object/function_doc_signature.cpp
new file mode 100644
index 000000000..41695285a
--- /dev/null
+++ b/libs/python/src/object/function_doc_signature.cpp
@@ -0,0 +1,344 @@
+// Copyright Nikolay Mladenov 2007.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// boost::python::make_tuple below are for gcc 4.4 -std=c++0x compatibility
+// (Intel C++ 10 and 11 with -std=c++0x don't need the full qualification).
+
+#include <boost/python/converter/registrations.hpp>
+#include <boost/python/object/function_doc_signature.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/str.hpp>
+#include <boost/python/args.hpp>
+#include <boost/python/tuple.hpp>
+
+#include <boost/python/detail/signature.hpp>
+
+#include <vector>
+
+namespace boost { namespace python { namespace objects {
+
+ bool function_doc_signature_generator::arity_cmp( function const *f1, function const *f2 )
+ {
+ return f1->m_fn.max_arity() < f2->m_fn.max_arity();
+ }
+
+ bool function_doc_signature_generator::are_seq_overloads( function const *f1, function const *f2 , bool check_docs)
+ {
+ py_function const & impl1 = f1->m_fn;
+ py_function const & impl2 = f2->m_fn;
+
+ //the number of parameters differs by 1
+ if (impl2.max_arity()-impl1.max_arity() != 1)
+ return false;
+
+ // if check docs then f1 shold not have docstring or have the same docstring as f2
+ if (check_docs && f2->doc() != f1->doc() && f1->doc())
+ return false;
+
+ python::detail::signature_element const* s1 = impl1.signature();
+ python::detail::signature_element const* s2 = impl2.signature();
+
+ unsigned size = impl1.max_arity()+1;
+
+ for (unsigned i = 0; i != size; ++i)
+ {
+ //check if the argument types are the same
+ if (s1[i].basename != s2[i].basename)
+ return false;
+
+ //return type
+ if (!i) continue;
+
+ //check if the argument default values are the same
+ bool f1_has_names = bool(f1->m_arg_names);
+ bool f2_has_names = bool(f2->m_arg_names);
+ if ( (f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1])
+ || (f1_has_names && !f2_has_names)
+ || (!f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object())
+ )
+ return false;
+ }
+ return true;
+ }
+
+ std::vector<function const*> function_doc_signature_generator::flatten(function const *f)
+ {
+ object name = f->name();
+
+ std::vector<function const*> res;
+
+ while (f) {
+
+ //this if takes out the not_implemented_function
+ if (f->name() == name)
+ res.push_back(f);
+
+ f=f->m_overloads.get();
+ }
+
+ //std::sort(res.begin(),res.end(), &arity_cmp);
+
+ return res;
+ }
+ std::vector<function const*> function_doc_signature_generator::split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change)
+ {
+ std::vector<function const*> res;
+
+ std::vector<function const*>::const_iterator fi = funcs.begin();
+
+ function const * last = *fi;
+
+ while (++fi != funcs.end()){
+
+ //check if fi starts a new chain of overloads
+ if (!are_seq_overloads( last, *fi, split_on_doc_change ))
+ res.push_back(last);
+
+ last = *fi;
+ }
+
+ if (last)
+ res.push_back(last);
+
+ return res;
+ }
+
+ str function_doc_signature_generator::raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
+ {
+ str res("object");
+
+ res = str("%s %s(%s)" % make_tuple( res, f->m_name, str("tuple args, dict kwds")) );
+
+ return res;
+ }
+
+ const char * function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
+ {
+ if (s.basename==std::string("void")){
+ static const char * none = "None";
+ return none;
+ }
+
+ PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
+ if ( py_type )
+ return py_type->tp_name;
+ else{
+ static const char * object = "object";
+ return object;
+ }
+ }
+
+ str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
+ {
+ str param;
+
+ python::detail::signature_element const * s = f.signature();
+ if (cpp_types)
+ {
+ if(!n)
+ s = &f.get_return_type();
+ if (s[n].basename == 0)
+ {
+ return str("...");
+ }
+
+ param = str(s[n].basename);
+
+ if (s[n].lvalue)
+ param += " {lvalue}";
+
+ }
+ else
+ {
+ if (n) //we are processing an argument and trying to come up with a name for it
+ {
+ object kv;
+ if ( arg_names && (kv = arg_names[n-1]) )
+ param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
+ else
+ param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
+ }
+ else //we are processing the return type
+ param = py_type_str(f.get_return_type());
+ }
+
+ //an argument - check for default value and append it
+ if(n && arg_names)
+ {
+ object kv(arg_names[n-1]);
+ if (kv && len(kv) == 2)
+ {
+ param = str("%s=%r" % make_tuple(param, kv[1]));
+ }
+ }
+ return param;
+ }
+
+ str function_doc_signature_generator::pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
+ {
+ py_function
+ const& impl = f->m_fn;
+ ;
+
+
+ unsigned arity = impl.max_arity();
+
+ if(arity == unsigned(-1))// is this the proper raw function test?
+ {
+ return raw_function_pretty_signature(f,n_overloads,cpp_types);
+ }
+
+ list formal_params;
+
+ size_t n_extra_default_args=0;
+
+ for (unsigned n = 0; n <= arity; ++n)
+ {
+ str param;
+
+ formal_params.append(
+ parameter_string(impl, n, f->m_arg_names, cpp_types)
+ );
+
+ // find all the arguments with default values preceeding the arity-n_overloads
+ if (n && f->m_arg_names)
+ {
+ object kv(f->m_arg_names[n-1]);
+
+ if (kv && len(kv) == 2)
+ {
+ //default argument preceeding the arity-n_overloads
+ if( n <= arity-n_overloads)
+ ++n_extra_default_args;
+ }
+ else
+ //argument without default, preceeding the arity-n_overloads
+ if( n <= arity-n_overloads)
+ n_extra_default_args = 0;
+ }
+ }
+
+ n_overloads+=n_extra_default_args;
+
+ if (!arity && cpp_types)
+ formal_params.append("void");
+
+ str ret_type (formal_params.pop(0));
+ if (cpp_types )
+ {
+ return str(
+ "%s %s(%s%s%s%s)"
+ % boost::python::make_tuple // workaround, see top
+ ( ret_type
+ , f->m_name
+ , str(",").join(formal_params.slice(0,arity-n_overloads))
+ , n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
+ , str(" [,").join(formal_params.slice(arity-n_overloads,arity))
+ , std::string(n_overloads,']')
+ ));
+ }else{
+ return str(
+ "%s(%s%s%s%s) -> %s"
+ % boost::python::make_tuple // workaround, see top
+ ( f->m_name
+ , str(",").join(formal_params.slice(0,arity-n_overloads))
+ , n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
+ , str(" [,").join(formal_params.slice(arity-n_overloads,arity))
+ , std::string(n_overloads,']')
+ , ret_type
+ ));
+ }
+
+ return str(
+ "%s %s(%s%s%s%s) %s"
+ % boost::python::make_tuple // workaround, see top
+ ( cpp_types?ret_type:str("")
+ , f->m_name
+ , str(",").join(formal_params.slice(0,arity-n_overloads))
+ , n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
+ , str(" [,").join(formal_params.slice(arity-n_overloads,arity))
+ , std::string(n_overloads,']')
+ , cpp_types?str(""):ret_type
+ ));
+
+ }
+
+ namespace detail {
+ char py_signature_tag[] = "PY signature :";
+ char cpp_signature_tag[] = "C++ signature :";
+ }
+
+ list function_doc_signature_generator::function_doc_signatures( function const * f)
+ {
+ list signatures;
+ std::vector<function const*> funcs = flatten( f);
+ std::vector<function const*> split_funcs = split_seq_overloads( funcs, true);
+ std::vector<function const*>::const_iterator sfi=split_funcs.begin(), fi;
+ size_t n_overloads=0;
+ for (fi=funcs.begin(); fi!=funcs.end(); ++fi)
+ {
+ if(*sfi == *fi){
+ if((*fi)->doc())
+ {
+ str func_doc = str((*fi)->doc());
+
+ int doc_len = len(func_doc);
+
+ bool show_py_signature = doc_len >= int(sizeof(detail::py_signature_tag)/sizeof(char)-1)
+ && str(detail::py_signature_tag) == func_doc.slice(0, int(sizeof(detail::py_signature_tag)/sizeof(char))-1);
+ if(show_py_signature)
+ {
+ func_doc = str(func_doc.slice(int(sizeof(detail::py_signature_tag)/sizeof(char))-1, _));
+ doc_len = len(func_doc);
+ }
+
+ bool show_cpp_signature = doc_len >= int(sizeof(detail::cpp_signature_tag)/sizeof(char)-1)
+ && str(detail::cpp_signature_tag) == func_doc.slice( 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char)), _);
+
+ if(show_cpp_signature)
+ {
+ func_doc = str(func_doc.slice(_, 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char))));
+ doc_len = len(func_doc);
+ }
+
+ str res="\n";
+ str pad = "\n";
+
+ if(show_py_signature)
+ {
+ str sig = pretty_signature(*fi, n_overloads,false);
+ res+=sig;
+ if(doc_len || show_cpp_signature )res+=" :";
+ pad+= str(" ");
+ }
+
+ if(doc_len)
+ {
+ if(show_py_signature)
+ res+=pad;
+ res+= pad.join(func_doc.split("\n"));
+ }
+
+ if( show_cpp_signature)
+ {
+ if(len(res)>1)
+ res+="\n"+pad;
+ res+=detail::cpp_signature_tag+pad+" "+pretty_signature(*fi, n_overloads,true);
+ }
+
+ signatures.append(res);
+ }
+ ++sfi;
+ n_overloads = 0;
+ }else
+ ++n_overloads ;
+ }
+
+ return signatures;
+ }
+
+
+}}}
+
diff --git a/libs/python/src/object/inheritance.cpp b/libs/python/src/object/inheritance.cpp
new file mode 100644
index 000000000..7dc9db1cd
--- /dev/null
+++ b/libs/python/src/object/inheritance.cpp
@@ -0,0 +1,495 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/object/inheritance.hpp>
+#include <boost/python/type_id.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#if _MSC_FULL_VER >= 13102171 && _MSC_FULL_VER <= 13102179
+# include <boost/graph/reverse_graph.hpp>
+#endif
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/reverse_graph.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <boost/bind.hpp>
+#include <boost/integer_traits.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <queue>
+#include <vector>
+#include <functional>
+
+//
+// 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 };
+ template <class T> inline void unused_variable(const T&) { }
+}
+
+// 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<vecS,vecS, bidirectionalS, no_property
+
+ // edge index property allows us to look up edges in the connectivity matrix
+ , property<edge_index_t,std::size_t
+
+ // The function which casts a void* from the edge's source type
+ // to its destination type.
+ , property<edge_cast_t,cast_function> > >
+#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<std::size_t>::const_iterator node_distance_map;
+
+ typedef std::pair<cast_graph::out_edge_iterator
+ , cast_graph::out_edge_iterator> 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<std::size_t>::max)());
+ m_known_vertices = n;
+ }
+
+ std::vector<std::size_t>::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<cast_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; }
+
+ smart_graph()
+ : m_known_vertices(0)
+ {}
+
+ private:
+ cast_graph m_topology;
+ mutable std::vector<std::size_t> 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<index_entry> type_index_t;
+
+
+ type_index_t& type_index()
+ {
+ static type_index_t x;
+ return x;
+ }
+
+ template <class Tuple>
+ 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<bool>(std::less<class_id>()
+ , boost::bind<class_id>(select1st<entry>(), _1)
+ , boost::bind<class_id>(select1st<entry>(), _2)));
+ }
+
+ inline index_entry* seek_type(class_id type)
+ {
+ type_index_t::iterator p = type_position(type);
+ if (p == type_index().end() || tuples::get<ksrc_static_t>(*p) != type)
+ return 0;
+ else
+ return &*p;
+ }
+
+ // Get the entry for a type, inserting if necessary
+ 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<ksrc_static_t>(*p) == type)
+ return p;
+
+ vertex_t v = add_vertex(full_graph().topology());
+ vertex_t v2 = add_vertex(up_graph().topology());
+ unused_variable(v2);
+ 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 necessary
+ typedef std::pair<type_index_t::iterator, type_index_t::iterator>
+ 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<std::size_t>::max)())
+ return 0;
+
+ typedef property_map<cast_graph,edge_cast_t>::const_type cast_map;
+ cast_map casts = get(edge_cast, g.topology());
+
+ typedef std::pair<vertex_t,void*> search_state;
+ typedef std::vector<search_state> visited_t;
+ visited_t visited;
+ std::priority_queue<q_elt> 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<std::ptrdiff_t>::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_element> 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<kdynamic_id>(*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<kvertex>(*src_p)
+ , tuples::get<kvertex>(*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<kvertex>(*types.first);
+ vertex_t dst = tuples::get<kvertex>(*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<kdynamic_id>(*demand_type(static_id)) = get_dynamic_id;
+}
+
+}}} // namespace boost::python::objects
diff --git a/libs/python/src/object/iterator.cpp b/libs/python/src/object/iterator.cpp
new file mode 100644
index 000000000..3f6c4adac
--- /dev/null
+++ b/libs/python/src/object/iterator.cpp
@@ -0,0 +1,39 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/object/iterator_core.hpp>
+#include <boost/python/object/function_object.hpp>
+#include <boost/bind.hpp>
+#include <boost/mpl/vector/vector10.hpp>
+
+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<PyObject*,PyObject*>())
+ )
+ );
+ return result;
+}
+
+void stop_iteration_error()
+{
+ PyErr_SetObject(PyExc_StopIteration, Py_None);
+ throw_error_already_set();
+}
+
+}}} // namespace boost::python::objects
diff --git a/libs/python/src/object/life_support.cpp b/libs/python/src/object/life_support.cpp
new file mode 100644
index 000000000..b7e9aa861
--- /dev/null
+++ b/libs/python/src/object/life_support.cpp
@@ -0,0 +1,121 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/object/life_support.hpp>
+#include <boost/python/detail/none.hpp>
+#include <boost/python/refcount.hpp>
+
+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 ::boost::python::detail::none();
+ }
+}
+
+PyTypeObject life_support_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)//(&PyType_Type)
+ const_cast<char*>("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, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+};
+
+PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient)
+{
+ if (nurse == Py_None || nurse == patient)
+ return nurse;
+
+ if (Py_TYPE(&life_support_type) == 0)
+ {
+ Py_TYPE(&life_support_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/libs/python/src/object/pickle_support.cpp b/libs/python/src/object/pickle_support.cpp
new file mode 100644
index 000000000..428c07b6c
--- /dev/null
+++ b/libs/python/src/object/pickle_support.cpp
@@ -0,0 +1,78 @@
+// (C) Copyright R.W. Grosse-Kunstleve 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/make_function.hpp>
+#include <boost/python/object/class.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/list.hpp>
+#include <boost/python/dict.hpp>
+#include <boost/python/str.hpp>
+
+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;
+ if (!getattr(instance_obj, "__safe_for_unpickling__", none))
+ {
+ str type_name(getattr(instance_class, "__name__"));
+ str module_name(getattr(instance_class, "__module__", object("")));
+ if (module_name)
+ module_name += ".";
+
+ PyErr_SetObject(
+ PyExc_RuntimeError,
+ ( "Pickling of \"%s\" instances is not enabled"
+ " (http://www.boost.org/libs/python/doc/v2/pickle.html)"
+ % (module_name+type_name)).ptr()
+ );
+
+ throw_error_already_set();
+ }
+ object getinitargs = getattr(instance_obj, "__getinitargs__", none);
+ tuple initargs;
+ if (!getinitargs.is_none()) {
+ 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.is_none()) {
+ len_instance_dict = len(instance_dict);
+ }
+ if (!getstate.is_none()) {
+ if (len_instance_dict > 0) {
+ object getstate_manages_dict = getattr(
+ instance_obj, "__getstate_manages_dict__", none);
+ if (getstate_manages_dict.is_none()) {
+ 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/libs/python/src/object/stl_iterator.cpp b/libs/python/src/object/stl_iterator.cpp
new file mode 100644
index 000000000..e32d32145
--- /dev/null
+++ b/libs/python/src/object/stl_iterator.cpp
@@ -0,0 +1,48 @@
+// Copyright Eric Niebler 2005.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Credits:
+// Andreas Kl\:ockner for fixing increment() to handle
+// error conditions.
+
+#include <boost/python/object.hpp>
+#include <boost/python/handle.hpp>
+#include <boost/python/object/stl_iterator_core.hpp>
+
+namespace boost { namespace python { namespace objects
+{
+
+stl_input_iterator_impl::stl_input_iterator_impl()
+ : it_()
+ , ob_()
+{
+}
+
+stl_input_iterator_impl::stl_input_iterator_impl(boost::python::object const &ob)
+ : it_(ob.attr("__iter__")())
+ , ob_()
+{
+ this->increment();
+}
+
+void stl_input_iterator_impl::increment()
+{
+ this->ob_ = boost::python::handle<>(
+ boost::python::allow_null(PyIter_Next(this->it_.ptr())));
+ if (PyErr_Occurred())
+ throw boost::python::error_already_set();
+}
+
+bool stl_input_iterator_impl::equal(stl_input_iterator_impl const &that) const
+{
+ return !this->ob_ == !that.ob_;
+}
+
+boost::python::handle<> const &stl_input_iterator_impl::current() const
+{
+ return this->ob_;
+}
+
+}}} // namespace boost::python::objects
diff --git a/libs/python/src/object_operators.cpp b/libs/python/src/object_operators.cpp
new file mode 100644
index 000000000..b993245fe
--- /dev/null
+++ b/libs/python/src/object_operators.cpp
@@ -0,0 +1,85 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/object_operators.hpp>
+#include <boost/python/detail/raw_pyobject.hpp>
+
+namespace boost { namespace python { namespace api {
+
+# define BOOST_PYTHON_COMPARE_OP(op, opid) \
+BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \
+{ \
+ return object( \
+ detail::new_reference( \
+ PyObject_RichCompare( \
+ l.ptr(), 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, 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)
+#if PY_VERSION_HEX >= 0x03000000
+// We choose FloorDivide instead of TrueDivide to keep the semantic
+// conform with C/C++'s '/' operator
+BOOST_PYTHON_BINARY_OPERATOR(/, FloorDivide)
+#else
+BOOST_PYTHON_BINARY_OPERATOR(/, Divide)
+#endif
+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)
+#if PY_VERSION_HEX >= 0x03000000
+// Same reason as above for choosing FloorDivide instead of TrueDivide
+BOOST_PYTHON_INPLACE_OPERATOR(/, FloorDivide)
+#else
+BOOST_PYTHON_INPLACE_OPERATOR(/, Divide)
+#endif
+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/libs/python/src/object_protocol.cpp b/libs/python/src/object_protocol.cpp
new file mode 100644
index 000000000..95c8c73ee
--- /dev/null
+++ b/libs/python/src/object_protocol.cpp
@@ -0,0 +1,197 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/object_protocol.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/ssize_t.hpp>
+
+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<char*>(key))
+ ));
+}
+
+BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_)
+{
+ PyObject* result = PyObject_GetAttrString(target.ptr(), const_cast<char*>(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<char*>(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<char*>(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] */
+ {
+#if PY_VERSION_HEX < 0x03000000
+ PyTypeObject *tp = u->ob_type;
+ PySequenceMethods *sq = tp->tp_as_sequence;
+
+ if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
+ ssize_t ilow = 0, ihigh = ssize_t_max;
+ if (!_PyEval_SliceIndex(v, &ilow))
+ return NULL;
+ if (!_PyEval_SliceIndex(w, &ihigh))
+ return NULL;
+ return PySequence_GetSlice(u, ilow, ihigh);
+ }
+ else
+#endif
+ {
+ 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 */
+ {
+#if PY_VERSION_HEX < 0x03000000
+ PyTypeObject *tp = u->ob_type;
+ PySequenceMethods *sq = tp->tp_as_sequence;
+
+ if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
+ ssize_t ilow = 0, ihigh = ssize_t_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
+#endif
+ {
+ 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/libs/python/src/slice.cpp b/libs/python/src/slice.cpp
new file mode 100644
index 000000000..ee55f9484
--- /dev/null
+++ b/libs/python/src/slice.cpp
@@ -0,0 +1,37 @@
+#include "boost/python/slice.hpp"
+
+// Copyright (c) 2004 Jonathan Brandmeyer
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+namespace boost { namespace python { namespace detail {
+
+slice_base::slice_base(PyObject* start, PyObject* stop, PyObject* step)
+ : object(detail::new_reference( PySlice_New(start, stop, step)))
+{
+}
+
+object
+slice_base::start() const
+{
+ return object( detail::borrowed_reference(
+ ((PySliceObject*)this->ptr())->start));
+}
+
+object
+slice_base::stop() const
+{
+ return object( detail::borrowed_reference(
+ ((PySliceObject*)this->ptr())->stop));
+}
+
+object
+slice_base::step() const
+{
+ return object( detail::borrowed_reference(
+ ((PySliceObject*)this->ptr())->step));
+}
+
+} } } // !namespace boost::python::detail
diff --git a/libs/python/src/str.cpp b/libs/python/src/str.cpp
new file mode 100644
index 000000000..0bc225aa2
--- /dev/null
+++ b/libs/python/src/str.cpp
@@ -0,0 +1,403 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/str.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/ssize_t.hpp>
+
+namespace boost { namespace python { namespace detail {
+
+detail::new_reference str_base::call(object const& arg_)
+{
+ return (detail::new_reference)PyObject_CallFunction(
+#if PY_VERSION_HEX >= 0x03000000
+ (PyObject*)&PyUnicode_Type,
+#else
+ (PyObject*)&PyString_Type,
+#endif
+ const_cast<char*>("(O)"),
+ arg_.ptr());
+}
+
+str_base::str_base()
+ : object(detail::new_reference(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromString("")
+#else
+ ::PyString_FromString("")
+#endif
+ ))
+{}
+
+str_base::str_base(const char* s)
+ : object(detail::new_reference(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromString(s)
+#else
+ ::PyString_FromString(s)
+#endif
+ ))
+{}
+
+namespace {
+
+ ssize_t str_size_as_py_ssize_t(std::size_t n)
+ {
+ if (n > static_cast<std::size_t>(ssize_t_max))
+ {
+ throw std::range_error("str size > ssize_t_max");
+ }
+ return static_cast<ssize_t>(n);
+ }
+
+} // namespace <anonymous>
+
+str_base::str_base(char const* start, char const* finish)
+ : object(
+ detail::new_reference(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromStringAndSize
+#else
+ ::PyString_FromStringAndSize
+#endif
+ (start, str_size_as_py_ssize_t(finish - start))
+ )
+ )
+{}
+
+str_base::str_base(char const* start, std::size_t length) // new str
+ : object(
+ detail::new_reference(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromStringAndSize
+#else
+ ::PyString_FromStringAndSize
+#endif
+ ( start, str_size_as_py_ssize_t(length) )
+ )
+ )
+{}
+
+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(), const_cast<char*>( #name ), \
+ const_cast<char*>( \
+ "(" 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<long>(this->attr("count")(sub));
+}
+
+long str_base::count(object_cref sub, object_cref start) const
+{
+ return extract<long>(this->attr("count")(sub,start));
+}
+
+long str_base::count(object_cref sub, object_cref start, object_cref end) const
+{
+ return extract<long>(this->attr("count")(sub,start,end));
+}
+
+#if PY_VERSION_HEX < 0x03000000
+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);
+}
+#endif
+
+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);
+}
+
+
+#if PY_VERSION_HEX >= 0x03000000
+ #define _BOOST_PYTHON_ASLONG PyLong_AsLong
+#else
+ #define _BOOST_PYTHON_ASLONG PyInt_AsLong
+#endif
+
+bool str_base::endswith(object_cref suffix) const
+{
+ bool result = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start,end).ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::isalnum() const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isalnum")().ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::isalpha() const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isalpha")().ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::isdigit() const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isdigit")().ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::islower() const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("islower")().ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::isspace() const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isspace")().ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::istitle() const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("istitle")().ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::isupper() const
+{
+ bool result = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_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 = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start,end).ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+#undef _BOOST_PYTHON_ASLONG
+
+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)
+
+static struct register_str_pytype_ptr
+{
+ register_str_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::str>())
+ )
+#if PY_VERSION_HEX >= 0x03000000
+ .m_class_object = &PyUnicode_Type;
+#else
+ .m_class_object = &PyString_Type;
+#endif
+ }
+}register_str_pytype_ptr_;
+
+}}} // namespace boost::python
diff --git a/libs/python/src/tuple.cpp b/libs/python/src/tuple.cpp
new file mode 100644
index 000000000..6719713b7
--- /dev/null
+++ b/libs/python/src/tuple.cpp
@@ -0,0 +1,35 @@
+// Copyright David Abrahams 2004.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/tuple.hpp>
+
+namespace boost { namespace python { namespace detail {
+
+detail::new_reference tuple_base::call(object const& arg_)
+{
+ return (detail::new_reference)PyObject_CallFunction(
+ (PyObject*)&PyTuple_Type, const_cast<char*>("(O)"),
+ arg_.ptr());
+}
+
+tuple_base::tuple_base()
+ : object(detail::new_reference(PyTuple_New(0)))
+{}
+
+tuple_base::tuple_base(object_cref sequence)
+ : object(call(sequence))
+{}
+
+static struct register_tuple_pytype_ptr
+{
+ register_tuple_pytype_ptr()
+ {
+ const_cast<converter::registration &>(
+ converter::registry::lookup(boost::python::type_id<boost::python::tuple>())
+ ).m_class_object = &PyTuple_Type;
+ }
+}register_tuple_pytype_ptr_;
+
+
+}}} // namespace boost::python
diff --git a/libs/python/src/wrapper.cpp b/libs/python/src/wrapper.cpp
new file mode 100644
index 000000000..f8feaef94
--- /dev/null
+++ b/libs/python/src/wrapper.cpp
@@ -0,0 +1,66 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/wrapper.hpp>
+
+namespace boost { namespace python {
+
+namespace detail
+{
+ override wrapper_base::get_override(
+ char const* name
+ , PyTypeObject* class_object
+ ) const
+ {
+ if (this->m_self)
+ {
+ if (handle<> m = handle<>(
+ python::allow_null(
+ ::PyObject_GetAttrString(
+ this->m_self, const_cast<char*>(name))))
+ )
+ {
+ PyObject* borrowed_f = 0;
+
+ if (
+ PyMethod_Check(m.get())
+ && ((PyMethodObject*)m.get())->im_self == this->m_self
+ && class_object->tp_dict != 0
+ )
+ {
+ borrowed_f = ::PyDict_GetItemString(
+ class_object->tp_dict, const_cast<char*>(name));
+
+
+ }
+ if (borrowed_f != ((PyMethodObject*)m.get())->im_func)
+ return override(m);
+ }
+ }
+ return override(handle<>(detail::none()));
+ }
+}
+
+#if 0
+namespace converter
+{
+ PyObject* BOOST_PYTHON_DECL do_polymorphic_ref_to_python(
+ python::detail::wrapper_base const volatile* x, type_info src
+ )
+ {
+ if (x == 0)
+ {
+ ::PyErr_Format(
+ PyExc_TypeError
+ , "Attempting to returning pointer or reference to instance of %s\n"
+ "for which no corresponding Python object exists. Wrap this function"
+ "with a return return value policy"
+ )
+ }
+ }
+
+}
+#endif
+
+}} // namespace boost::python::detail
diff --git a/libs/python/test/Jamfile.v2 b/libs/python/test/Jamfile.v2
new file mode 100644
index 000000000..552418800
--- /dev/null
+++ b/libs/python/test/Jamfile.v2
@@ -0,0 +1,236 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import python ;
+import os ;
+
+lib socket ;
+
+use-project /boost/python : ../build ;
+project /boost/python/test
+ : requirements
+ <toolset>gcc:<cxxflags>-Wextra
+ <target-os>qnxnto:<library>socket
+ ;
+
+local PY = ;
+if [ python.configured ]
+{
+ PY = /python//python ;
+}
+
+rule py-run ( sources * : input-file ? )
+{
+ return [ run $(sources) /boost/python//boost_python $(PY)
+ : # args
+ : $(input-file)
+ : #requirements
+ <define>BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
+
+ ] ;
+}
+
+rule py-compile ( sources * )
+{
+ return [ compile $(sources) /boost/python//boost_python ] ;
+}
+
+rule py-compile-fail ( sources * )
+{
+ return [ compile-fail $(sources) /boost/python//boost_python ] ;
+}
+
+rule require-windows ( properties * )
+{
+ if ! <target-os>windows in $(properties)
+ {
+ return <build>no ;
+ }
+}
+
+test-suite python
+ :
+
+ [
+ run exec.cpp /boost/python//boost_python/<link>static $(PY)
+ : # program args
+ : exec.py # input files
+ : # requirements
+ : # target-name
+ ]
+
+ [
+ run exec.cpp ../build//boost_python/<link>shared /python//python
+ : # program args
+ : exec.py
+ : # requirements
+ : exec-dynamic # target-name
+ ]
+
+# [
+# run import_.cpp ../build//boost_python /python//python
+# : # program args
+# : import_.py # input files
+# : # requirements
+# : # target-name
+# ]
+
+[
+bpl-test crossmod_exception
+ : crossmod_exception.py crossmod_exception_a.cpp crossmod_exception_b.cpp
+]
+
+[ bpl-test injected ]
+[ bpl-test properties ]
+[ bpl-test return_arg ]
+[ bpl-test staticmethod ]
+[ bpl-test shared_ptr ]
+[ bpl-test enable_shared_from_this ]
+[ bpl-test andreas_beyer ]
+[ bpl-test wrapper_held_type ]
+
+[ bpl-test polymorphism2_auto_ptr
+ : polymorphism2_auto_ptr.py polymorphism2.py polymorphism2_auto_ptr.cpp
+]
+
+[ bpl-test polymorphism ]
+[ bpl-test polymorphism2 ]
+
+[ bpl-test auto_ptr ]
+
+[ bpl-test minimal ]
+[ bpl-test args ]
+[ bpl-test raw_ctor ]
+[ bpl-test numpy : printer.py numeric_tests.py numarray_tests.py numpy.py numpy.cpp ]
+[ 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 const_argument ]
+[ bpl-test keywords : keywords.cpp keywords_test.py ]
+
+
+[ python-extension builtin_converters_ext : test_builtin_converters.cpp /boost/python//boost_python ]
+[ bpl-test builtin_converters : test_builtin_converters.py builtin_converters_ext ]
+
+ [ bpl-test test_pointer_adoption ]
+ [ bpl-test operators ]
+ [ bpl-test operators_wrapper ]
+ [ bpl-test callbacks ]
+ [ bpl-test defaults ]
+
+[ bpl-test object ]
+[ bpl-test class ]
+[ bpl-test list ]
+[ bpl-test long ]
+[ bpl-test dict ]
+[ bpl-test tuple ]
+[ bpl-test str ]
+[ bpl-test slice ]
+
+[ 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 ]
+
+[ bpl-test multi_arg_constructor
+ : # files
+ : # requirements
+ # 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
+ <toolset>intel-win:<debug-symbols>off
+]
+
+[ bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ]
+
+[ bpl-test stl_iterator : stl_iterator.py stl_iterator.cpp ]
+
+[ bpl-test extract ]
+
+[
+bpl-test crossmod_opaque
+ : crossmod_opaque.py crossmod_opaque_a.cpp crossmod_opaque_b.cpp
+]
+[ bpl-test opaque ]
+[ bpl-test voidptr ]
+
+[ bpl-test pickle1 ]
+[ bpl-test pickle2 ]
+[ bpl-test pickle3 ]
+[ bpl-test pickle4 ]
+
+[ bpl-test nested ]
+
+[ bpl-test docstring ]
+[ bpl-test pytype_function ]
+
+[ bpl-test vector_indexing_suite ]
+
+[ bpl-test pointer_vector
+ : # files
+ : # requirements
+ # Turn off this test on HP CXX, as the test hangs when executing.
+ # Whenever the cause for the failure of the polymorphism test is found
+ # and fixed, this should be retested.
+ <toolset>hp_cxx:<build>no ]
+
+[ python-extension map_indexing_suite_ext
+ : map_indexing_suite.cpp int_map_indexing_suite.cpp a_map_indexing_suite.cpp
+ /boost/python//boost_python ]
+[ bpl-test
+ map_indexing_suite : map_indexing_suite.py map_indexing_suite_ext ]
+
+[ run import_.cpp /boost/python//boost_python $(PY) : : import_.py ]
+
+# if $(TEST_BIENSTMAN_NON_BUGS)
+# {
+# bpl-test bienstman4 ;
+# bpl-test bienstman5 ;
+# }
+
+[ bpl-test calling_conventions : : <conditional>@require-windows ]
+[ bpl-test calling_conventions_mf : : <conditional>@require-windows ]
+
+# --- unit tests of library components ---
+
+[ compile indirect_traits_test.cpp ]
+[ run destroy_test.cpp ]
+[ py-run pointer_type_id_test.cpp ]
+[ py-run bases.cpp ]
+[ run if_else.cpp ]
+[ py-run pointee.cpp ]
+[ run result.cpp ]
+
+[ compile string_literal.cpp ]
+[ py-compile borrowed.cpp ]
+[ py-compile object_manager.cpp ]
+[ py-compile copy_ctor_mutates_rhs.cpp ]
+
+[ py-run upcast.cpp ]
+
+[ py-compile select_holder.cpp ]
+
+[ run select_from_python_test.cpp ../src/converter/type_id.cpp
+ :
+ :
+ : <define>BOOST_PYTHON_STATIC_LIB
+ <use>$(PY)
+
+]
+
+ [ py-compile select_arg_to_python_test.cpp ]
+
+[ py-compile-fail ./raw_pyobject_fail1.cpp ]
+[ py-compile-fail ./raw_pyobject_fail2.cpp ]
+[ py-compile-fail ./as_to_python_function.cpp ]
+[ py-compile-fail ./object_fail1.cpp ]
+
+ ;
diff --git a/libs/python/test/a_map_indexing_suite.cpp b/libs/python/test/a_map_indexing_suite.cpp
new file mode 100644
index 000000000..07a0a6b97
--- /dev/null
+++ b/libs/python/test/a_map_indexing_suite.cpp
@@ -0,0 +1,92 @@
+// Copyright Joel de Guzman 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/suite/indexing/map_indexing_suite.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/implicit.hpp>
+
+using namespace boost::python;
+
+struct A
+{
+ int value;
+ A() : value(0){};
+ A(int v) : value(v) {};
+};
+
+bool operator==(const A& v1, const A& v2)
+{
+ return (v1.value == v2.value);
+}
+
+struct B
+{
+ A a;
+};
+
+// Converter from A to python int
+struct AToPython
+{
+ static PyObject* convert(const A& s)
+ {
+ return boost::python::incref(boost::python::object((int)s.value).ptr());
+ }
+};
+
+// Conversion from python int to A
+struct AFromPython
+{
+ AFromPython()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id< A >());
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+#if PY_VERSION_HEX >= 0x03000000
+ if (!PyLong_Check(obj_ptr)) return 0;
+#else
+ if (!PyInt_Check(obj_ptr)) return 0;
+#endif
+ return obj_ptr;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage< A >*)
+ data)-> storage.bytes;
+
+#if PY_VERSION_HEX >= 0x03000000
+ new (storage) A((int)PyLong_AsLong(obj_ptr));
+#else
+ new (storage) A((int)PyInt_AsLong(obj_ptr));
+#endif
+ data->convertible = storage;
+ }
+};
+
+void a_map_indexing_suite()
+{
+
+ to_python_converter< A , AToPython >();
+ AFromPython();
+
+ class_< std::map<int, A> >("AMap")
+ .def(map_indexing_suite<std::map<int, A>, true >())
+ ;
+
+ class_< B >("B")
+ .add_property("a", make_getter(&B::a, return_value_policy<return_by_value>()),
+ make_setter(&B::a, return_value_policy<return_by_value>()))
+ ;
+}
+
+
diff --git a/libs/python/test/andreas_beyer.cpp b/libs/python/test/andreas_beyer.cpp
new file mode 100644
index 000000000..b28b15660
--- /dev/null
+++ b/libs/python/test/andreas_beyer.cpp
@@ -0,0 +1,61 @@
+// Copyright David Abrahams 2006. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+
+using namespace boost;
+
+class A : public enable_shared_from_this<A> {
+ public:
+ A() : val(0) {};
+ int val;
+ typedef shared_ptr<A> A_ptr;
+ A_ptr self() {
+ A_ptr self;
+ self = shared_from_this();
+ return self;
+ }
+
+};
+
+class B {
+ public:
+ B() {
+ a = A::A_ptr(new A());
+ }
+ void set(A::A_ptr _a) {
+ this->a = _a;
+ }
+ A::A_ptr get() {
+ return a;
+ }
+ A::A_ptr a;
+};
+
+template <class T>
+void hold_python(shared_ptr<T>& x)
+{
+ x = python::extract<shared_ptr<T> >( python::object(x) );
+}
+
+A::A_ptr get_b_a(shared_ptr<B> b)
+{
+ hold_python(b->a);
+ return b->get();
+}
+
+BOOST_PYTHON_MODULE(andreas_beyer_ext) {
+ python::class_<A, noncopyable> ("A")
+ .def("self", &A::self)
+ .def_readwrite("val", &A::val)
+ ;
+ python::register_ptr_to_python< A::A_ptr >();
+
+ python::class_<B>("B")
+ .def("set", &B::set)
+// .def("get", &B::get)
+ .def("get", get_b_a)
+ ;
+}
diff --git a/libs/python/test/andreas_beyer.py b/libs/python/test/andreas_beyer.py
new file mode 100644
index 000000000..84a54fbd9
--- /dev/null
+++ b/libs/python/test/andreas_beyer.py
@@ -0,0 +1,24 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+ >>> from andreas_beyer_ext import *
+ >>> b=B()
+ >>> a=b.get() # let b create an A
+ >>> a2=b.get()
+ >>> assert id(a) == id(a2)
+'''
+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/libs/python/test/args.cpp b/libs/python/test/args.cpp
new file mode 100644
index 000000000..592a8e505
--- /dev/null
+++ b/libs/python/test/args.cpp
@@ -0,0 +1,99 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include "test_class.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/raw_function.hpp>
+#include <boost/python/return_internal_reference.hpp>
+
+using namespace boost::python;
+
+#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+# define make_tuple boost::python::make_tuple
+#endif
+
+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, (arg("x")=1, arg("y")=4.25, arg("z")="wow")
+ , "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>("Y", init<int>(args("value"), "Y's docstring"))
+ .def("value", &Y::value)
+ .def("raw", raw_function(raw_func))
+ ;
+
+ class_<X>("X", "This is X's docstring", init<>(args("self")))
+ .def(init<int, optional<int> >(args("self", "a0", "a1")))
+ .def("f", &X::f
+ , "This is X.f's docstring"
+ , args("self","x", "y", "z"))
+
+ // Just to prove that all the different argument combinations work
+ .def("inner0", &X::inner, return_internal_reference<>(), args("self", "n"), "docstring")
+ .def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("self", "n"))
+
+ .def("inner2", &X::inner, args("self", "n"), return_internal_reference<>(), "docstring")
+ .def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("self", "n"))
+
+ .def("inner4", &X::inner, args("self", "n"), "docstring", return_internal_reference<>())
+ .def("inner5", &X::inner, "docstring", args("self", "n"), return_internal_reference<>())
+
+ .def("f1", &X::f, X_f_overloads(args("self", "x", "y", "z")))
+ .def("f2", &X::f, X_f_overloads(args("self", "x", "y", "z"), "f2's docstring"))
+ .def("f2", &X::f, X_f_overloads(args("x", "y", "z"), "f2's docstring"))
+ ;
+
+ def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>());
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/args.py b/libs/python/test/args.py
new file mode 100644
index 000000000..44a9cd252
--- /dev/null
+++ b/libs/python/test/args.py
@@ -0,0 +1,147 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> 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')
+>>> q.f2.__doc__.splitlines()[1]
+'f2( (X)self [, (int)x [, (float)y [, (str)z]]]) -> tuple :'
+
+>>> q.f2.__doc__.splitlines()[2]
+" f2's docstring"
+
+>>> X.f.__doc__.splitlines()[1:5]
+['f( (X)self, (int)x, (float)y, (str)z) -> tuple :', " This is X.f's docstring", '', ' C++ signature :']
+
+>>> 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__.splitlines()[1:5]
+1 1 0 ['inner0( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
+1 1 0 ['inner1( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
+1 1 0 ['inner2( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
+1 1 0 ['inner3( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
+1 1 0 ['inner4( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
+1 1 0 ['inner5( (X)self, (bool)n) -> Y :', ' docstring', '', ' C++ signature :']
+
+>>> 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."
+ import args_ext
+ help(args_ext)
+ sys.exit(status)
+
+
+
diff --git a/libs/python/test/as_to_python_function.cpp b/libs/python/test/as_to_python_function.cpp
new file mode 100644
index 000000000..cc083890a
--- /dev/null
+++ b/libs/python/test/as_to_python_function.cpp
@@ -0,0 +1,13 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/converter/as_to_python_function.hpp>
+
+struct hopefully_illegal
+{
+ static PyObject* convert(int&);
+};
+
+PyObject* x = boost::python::converter::as_to_python_function<int, hopefully_illegal>::convert(0);
diff --git a/libs/python/test/auto_ptr.cpp b/libs/python/test/auto_ptr.cpp
new file mode 100644
index 000000000..0f61e96dc
--- /dev/null
+++ b/libs/python/test/auto_ptr.cpp
@@ -0,0 +1,90 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include "test_class.hpp"
+#include <boost/python/class.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/implicit.hpp>
+
+#include <boost/detail/workaround.hpp>
+
+#include <memory>
+
+using namespace boost::python;
+
+typedef test_class<> X;
+
+struct Y : X
+{
+ Y(int n) : X(n) {};
+};
+
+int look(std::auto_ptr<X> const& x)
+{
+ return (x.get()) ? x->value() : -1;
+}
+
+int steal(std::auto_ptr<X> x)
+{
+ return x->value();
+}
+
+int maybe_steal(std::auto_ptr<X>& x, bool doit)
+{
+ int n = x->value();
+ if (doit)
+ x.release();
+ return n;
+}
+
+std::auto_ptr<X> make()
+{
+ return std::auto_ptr<X>(new X(77));
+}
+
+std::auto_ptr<X> callback(object f)
+{
+ std::auto_ptr<X> x(new X(77));
+ return call<std::auto_ptr<X> >(f.ptr(), x);
+}
+
+std::auto_ptr<X> extract_(object o)
+{
+ return extract<std::auto_ptr<X>&>(o)
+#if BOOST_MSVC <= 1300
+ ()
+#endif
+ ;
+}
+
+BOOST_PYTHON_MODULE(auto_ptr_ext)
+{
+ class_<X, std::auto_ptr<X>, boost::noncopyable>("X", init<int>())
+ .def("value", &X::value)
+ ;
+
+ class_<Y, std::auto_ptr<Y>, bases<X>, boost::noncopyable>("Y", init<int>())
+ ;
+
+ // 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<Y>, std::auto_ptr<X> >();
+#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/libs/python/test/auto_ptr.py b/libs/python/test/auto_ptr.py
new file mode 100644
index 000000000..2e4bed61d
--- /dev/null
+++ b/libs/python/test/auto_ptr.py
@@ -0,0 +1,100 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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'
+
+>>> print look.__doc__.splitlines()[1]
+look( (X)arg1) -> int :
+
+>>> print steal.__doc__.splitlines()[1]
+steal( (X)arg1) -> int :
+
+>>> print maybe_steal.__doc__.splitlines()[1]
+maybe_steal( (X)arg1, (bool)arg2) -> int :
+
+>>> print make.__doc__.splitlines()[1]
+make() -> X :
+
+>>> print callback.__doc__.splitlines()[1]
+callback( (object)arg1) -> X :
+
+>>> print extract.__doc__.splitlines()[1]
+extract( (object)arg1) -> X :
+
+'''
+
+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/libs/python/test/back_reference.cpp b/libs/python/test/back_reference.cpp
new file mode 100644
index 000000000..266ed2912
--- /dev/null
+++ b/libs/python/test/back_reference.cpp
@@ -0,0 +1,112 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/has_back_reference.hpp>
+#include <boost/python/back_reference.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+#include <memory>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+#include <boost/python/copy_const_reference.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/mpl/bool.hpp>
+
+// 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() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
+
+ void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
+ int value() const { BOOST_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), self(self) {}
+ 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), self(self) {}
+ 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<Y>
+ : mpl::true_
+ {
+ };
+
+ template <>
+ struct has_back_reference<Z>
+ : mpl::true_
+ {
+ };
+}}
+
+// prove that back_references get initialized with the right PyObject*
+object y_identity(back_reference<Y const&> y)
+{
+ return y.source();
+}
+
+// prove that back_references contain the right value
+bool y_equality(back_reference<Y const&> y1, Y const& y2)
+{
+ return &y1.get() == &y2;
+}
+
+BOOST_PYTHON_MODULE(back_reference_ext)
+{
+ def("copy_Y", copy_Y, return_value_policy<copy_const_reference>());
+ def("copy_Z", copy_Z, return_value_policy<copy_const_reference>());
+ def("x_instances", &X::count);
+
+ class_<Y>("Y", init<int>())
+ .def("value", &Y::value)
+ .def("set", &Y::set)
+ ;
+
+ class_<Z,std::auto_ptr<Z> >("Z", init<int>())
+ .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/libs/python/test/back_reference.py b/libs/python/test/back_reference.py
new file mode 100644
index 000000000..6705ee7b7
--- /dev/null
+++ b/libs/python/test/back_reference.py
@@ -0,0 +1,37 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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
+
+>>> print y_identity.__doc__.splitlines()[1]
+y_identity( (Y)arg1) -> object :
+'''
+
+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/libs/python/test/bases.cpp b/libs/python/test/bases.cpp
new file mode 100644
index 000000000..84beb0612
--- /dev/null
+++ b/libs/python/test/bases.cpp
@@ -0,0 +1,62 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/bases.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/same_traits.hpp>
+
+struct A;
+struct B;
+
+template <class X, class Y, class Z>
+struct choose_bases
+ : boost::python::detail::select_bases<
+ X
+ , typename boost::python::detail::select_bases<
+ Y
+ , typename boost::python::detail::select_bases<Z>::type
+ >::type>
+{
+
+};
+
+int main()
+{
+ BOOST_STATIC_ASSERT((boost::python::detail::specifies_bases<
+ boost::python::bases<A,B> >::value));
+
+ BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases<
+ boost::python::bases<A,B>& >::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<char*>::type > collected1;
+
+ BOOST_STATIC_ASSERT((boost::is_same<collected1::type,boost::python::bases<> >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<choose_bases<int,char*,long>::type,boost::python::bases<> >::value));
+
+ typedef boost::python::detail::select_bases<
+ int
+ , boost::python::detail::select_bases<
+ boost::python::bases<A,B>
+ , boost::python::detail::select_bases<
+ A
+ >::type
+ >::type
+ > collected2;
+
+ BOOST_STATIC_ASSERT((boost::is_same<collected2::type,boost::python::bases<A,B> >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<choose_bases<int,boost::python::bases<A,B>,long>::type,boost::python::bases<A,B> >::value));
+
+ return 0;
+}
diff --git a/libs/python/test/ben_scott1.cpp b/libs/python/test/ben_scott1.cpp
new file mode 100644
index 000000000..5a675e230
--- /dev/null
+++ b/libs/python/test/ben_scott1.cpp
@@ -0,0 +1,54 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python.hpp>
+#include <iostream>
+using namespace boost::python;
+using namespace boost;
+
+struct Product {};
+typedef shared_ptr<Product> 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<ProductPtr>(mSelf, "create"); }
+ PyObject* mSelf;
+};
+
+BOOST_PYTHON_MODULE(ben_scott1_ext)
+{
+ class_<Product, ProductPtr>("Product");
+
+ class_<Creator, CreatorWrap, noncopyable>("Creator")
+ .def("create", &CreatorWrap::create)
+ ;
+
+ class_<Factory>("Factory")
+ .def("reg", &Factory::reg, with_custodian_and_ward<1,2>())
+ .def("create", &Factory::create)
+ ;
+}
+
+#include "../test/module_tail.cpp"
diff --git a/libs/python/test/ben_scott1.py b/libs/python/test/ben_scott1.py
new file mode 100644
index 000000000..79130757a
--- /dev/null
+++ b/libs/python/test/ben_scott1.py
@@ -0,0 +1,17 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+# This regression test checks that call_method<T>(...) 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/libs/python/test/bienstman1.cpp b/libs/python/test/bienstman1.cpp
new file mode 100644
index 000000000..dc0065784
--- /dev/null
+++ b/libs/python/test/bienstman1.cpp
@@ -0,0 +1,40 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/reference_existing_object.hpp>
+#include <boost/python/return_value_policy.hpp>
+
+struct A {};
+
+struct V
+{
+ virtual ~V() {}; // silence compiler warningsa
+ 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>("A");
+
+ class_<V, boost::noncopyable>("V", no_init)
+ .def("inside", &V::inside,
+ return_value_policy<reference_existing_object>())
+ .def("outside", outside,
+ return_value_policy<reference_existing_object>())
+ ;
+}
+
diff --git a/libs/python/test/bienstman1.py b/libs/python/test/bienstman1.py
new file mode 100644
index 000000000..06f0fff8c
--- /dev/null
+++ b/libs/python/test/bienstman1.py
@@ -0,0 +1,23 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+# 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/libs/python/test/bienstman2.cpp b/libs/python/test/bienstman2.cpp
new file mode 100644
index 000000000..10f99923d
--- /dev/null
+++ b/libs/python/test/bienstman2.cpp
@@ -0,0 +1,28 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+
+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>("C");
+ class_<D>("D");
+ class_<E>("E")
+ .def("fe", &E::fe) // this compiles.
+ .def("fe2", &E::fe2) // this doesn't... well, now it does ;-)
+ ;
+}
diff --git a/libs/python/test/bienstman2.py b/libs/python/test/bienstman2.py
new file mode 100644
index 000000000..359987d19
--- /dev/null
+++ b/libs/python/test/bienstman2.py
@@ -0,0 +1,20 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/bienstman3.cpp b/libs/python/test/bienstman3.cpp
new file mode 100644
index 000000000..d765b303d
--- /dev/null
+++ b/libs/python/test/bienstman3.cpp
@@ -0,0 +1,26 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+
+struct V
+{
+ virtual ~V() {}; // silence compiler warningsa
+ virtual void f() = 0;
+};
+
+struct B
+{
+ B(const V&) {}
+};
+
+BOOST_PYTHON_MODULE(bienstman3_ext)
+{
+ using namespace boost::python;
+
+ class_<V, boost::noncopyable>("V", no_init);
+ class_<B>("B", init<const V&>());
+
+}
diff --git a/libs/python/test/bienstman3.py b/libs/python/test/bienstman3.py
new file mode 100644
index 000000000..4f3e87114
--- /dev/null
+++ b/libs/python/test/bienstman3.py
@@ -0,0 +1,30 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/bienstman4.cpp b/libs/python/test/bienstman4.cpp
new file mode 100644
index 000000000..34b9e211f
--- /dev/null
+++ b/libs/python/test/bienstman4.cpp
@@ -0,0 +1,39 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/implicit.hpp>
+#include <boost/mpl/list.hpp>
+
+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<Type1,Term>();
+
+ class_<Expression>("Expression")
+ .def("add", &Expression::add)
+ ;
+
+ class_<Type1>("T1")
+ ;
+
+ class_<Term>("Term", init<Type1&>())
+ ;
+
+ Type1 t1;
+ Expression e;
+ e.add(t1);
+}
+
diff --git a/libs/python/test/bienstman4.py b/libs/python/test/bienstman4.py
new file mode 100644
index 000000000..e2a5b0659
--- /dev/null
+++ b/libs/python/test/bienstman4.py
@@ -0,0 +1,23 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/bienstman5.cpp b/libs/python/test/bienstman5.cpp
new file mode 100644
index 000000000..657dadd12
--- /dev/null
+++ b/libs/python/test/bienstman5.cpp
@@ -0,0 +1,23 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/mpl/list.hpp>
+
+#include <complex>
+
+struct M {M(const std::complex<double>&) {} };
+
+BOOST_PYTHON_MODULE(bienstman5_ext)
+{
+ using namespace boost::python;
+
+ class_<M>("M", init<std::complex<double> const&>())
+ ;
+}
+
+
diff --git a/libs/python/test/bienstman5.py b/libs/python/test/bienstman5.py
new file mode 100644
index 000000000..59a9bc93f
--- /dev/null
+++ b/libs/python/test/bienstman5.py
@@ -0,0 +1,21 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/borrowed.cpp b/libs/python/test/borrowed.cpp
new file mode 100644
index 000000000..2c1bd1b7a
--- /dev/null
+++ b/libs/python/test/borrowed.cpp
@@ -0,0 +1,33 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/detail/wrap_python.hpp>
+#include <boost/python/borrowed.hpp>
+#include <boost/static_assert.hpp>
+
+using namespace boost::python;
+
+template <class T>
+void assert_borrowed_ptr(T const&)
+{
+ BOOST_STATIC_ASSERT(boost::python::detail::is_borrowed_ptr<T>::value);
+}
+
+template <class T>
+void assert_not_borrowed_ptr(T const&)
+{
+ BOOST_STATIC_ASSERT(!boost::python::detail::is_borrowed_ptr<T>::value);
+}
+
+int main()
+{
+ assert_borrowed_ptr(borrowed((PyObject*)0));
+ assert_borrowed_ptr(borrowed((PyTypeObject*)0));
+ assert_borrowed_ptr((detail::borrowed<PyObject> const*)0);
+ assert_borrowed_ptr((detail::borrowed<PyObject> volatile*)0);
+ assert_borrowed_ptr((detail::borrowed<PyObject> const volatile*)0);
+ assert_not_borrowed_ptr((PyObject*)0);
+ assert_not_borrowed_ptr(0);
+ return 0;
+}
diff --git a/libs/python/test/callbacks.cpp b/libs/python/test/callbacks.cpp
new file mode 100644
index 000000000..66bd35240
--- /dev/null
+++ b/libs/python/test/callbacks.cpp
@@ -0,0 +1,150 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/ref.hpp>
+#include <boost/python/ptr.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/reference_existing_object.hpp>
+#include <boost/python/call.hpp>
+#include <boost/python/object.hpp>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+
+using namespace boost::python;
+BOOST_STATIC_ASSERT(converter::is_object_manager<handle<> >::value);
+
+int apply_int_int(PyObject* f, int x)
+{
+ return call<int>(f, x);
+}
+
+void apply_void_int(PyObject* f, int x)
+{
+ call<void>(f, x);
+}
+
+struct X
+{
+ explicit X(int x) : x(x), magic(7654321) { ++counter; }
+ X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; }
+ ~X() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
+
+ void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
+ int value() const { BOOST_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<X>(f, x);
+}
+
+void apply_void_X_ref(PyObject* f, X& x)
+{
+ call<void>(f, boost::ref(x));
+}
+
+X& apply_X_ref_handle(PyObject* f, handle<> obj)
+{
+ return call<X&>(f, obj);
+}
+
+X* apply_X_ptr_handle_cref(PyObject* f, handle<> const& obj)
+{
+ return call<X*>(f, obj);
+}
+
+void apply_void_X_cref(PyObject* f, X const& x)
+{
+ call<void>(f, boost::cref(x));
+}
+
+void apply_void_X_ptr(PyObject* f, X* x)
+{
+ call<void>(f, ptr(x));
+}
+
+void apply_void_X_deep_ptr(PyObject* f, X* x)
+{
+ call<void>(f, x);
+}
+
+char const* apply_cstring_cstring(PyObject* f, char const* s)
+{
+ return call<char const*>(f, s);
+}
+
+char const* apply_cstring_pyobject(PyObject* f, PyObject* s)
+{
+ return call<char const*>(f, borrowed(s));
+}
+
+char apply_char_char(PyObject* f, char c)
+{
+ return call<char>(f, c);
+}
+
+char const* apply_to_string_literal(PyObject* f)
+{
+ return call<char const*>(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<T>.
+ return call<handle<> >(x.get(), type_handle(borrowed(x->ob_type)));
+}
+
+object apply_object_object(PyObject* f, object x)
+{
+ return call<object>(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<reference_existing_object>());
+
+ def("apply_X_ref_handle", apply_X_ref_handle
+ , return_value_policy<reference_existing_object>());
+
+ 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>("X", init<int>())
+ .def(init<X const&>())
+ .def("value", &X::value)
+ .def("set", &X::set)
+ ;
+
+ def("x_count", &X::count);
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/callbacks.py b/libs/python/test/callbacks.py
new file mode 100644
index 000000000..640eb1551
--- /dev/null
+++ b/libs/python/test/callbacks.py
@@ -0,0 +1,147 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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<wink>:
+
+>>> 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/libs/python/test/calling_conventions.cpp b/libs/python/test/calling_conventions.cpp
new file mode 100644
index 000000000..54f49aebc
--- /dev/null
+++ b/libs/python/test/calling_conventions.cpp
@@ -0,0 +1,158 @@
+//
+// adapted from bind_stdcall_test.cpp - test for bind.hpp + __stdcall (free functions)
+// The purpose of this simple test is to determine if a function can be
+// called from Python with the various existing calling conventions
+//
+// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#if !defined(TEST_INCLUDE_RECURSION)
+
+#define TEST_INCLUDE_RECURSION
+
+//------------------------------------------------------------------------------
+// this section is the main body of the test extension module
+
+#define BOOST_PYTHON_ENABLE_CDECL
+#define BOOST_PYTHON_ENABLE_STDCALL
+#define BOOST_PYTHON_ENABLE_FASTCALL
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/python.hpp>
+using namespace boost::python;
+
+// first define test functions for every calling convention
+
+#define TEST_DECLARE_FUNCTIONS
+
+#define TESTED_CALLING_CONVENTION __cdecl
+#include "calling_conventions.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __stdcall
+#include "calling_conventions.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __fastcall
+#include "calling_conventions.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#undef TEST_DECLARE_FUNCTIONS
+
+// then create a module wrapping the defined functions for every calling convention
+
+BOOST_PYTHON_MODULE( calling_conventions_ext )
+{
+
+#define TEST_WRAP_FUNCTIONS
+
+#define TESTED_CALLING_CONVENTION __cdecl
+#include "calling_conventions.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __stdcall
+#include "calling_conventions.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __fastcall
+#include "calling_conventions.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#undef TEST_WRAP_FUNCTIONS
+
+}
+
+#else // !defined(TEST_INCLUDE_RECURSION)
+
+//------------------------------------------------------------------------------
+// this section defines the functions to be wrapped
+
+# if defined(TEST_DECLARE_FUNCTIONS)
+
+# if !defined(TESTED_CALLING_CONVENTION)
+# error "One calling convention must be defined"
+# endif // !defined(TESTED_CALLING_CONVENTION)
+
+namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) {
+
+ long TESTED_CALLING_CONVENTION f_0()
+ {
+ return 17041L;
+ }
+
+ long TESTED_CALLING_CONVENTION f_1(long a)
+ {
+ return a;
+ }
+
+ long TESTED_CALLING_CONVENTION f_2(long a, long b)
+ {
+ return a + 10 * b;
+ }
+
+ long TESTED_CALLING_CONVENTION f_3(long a, long b, long c)
+ {
+ return a + 10 * b + 100 * c;
+ }
+
+ long TESTED_CALLING_CONVENTION f_4(long a, long b, long c, long d)
+ {
+ return a + 10 * b + 100 * c + 1000 * d;
+ }
+
+ long TESTED_CALLING_CONVENTION f_5(long a, long b, long c, long d, long e)
+ {
+ return a + 10 * b + 100 * c + 1000 * d + 10000 * e;
+ }
+
+ long TESTED_CALLING_CONVENTION f_6(long a, long b, long c, long d, long e, long f)
+ {
+ return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f;
+ }
+
+ long TESTED_CALLING_CONVENTION f_7(long a, long b, long c, long d, long e, long f, long g)
+ {
+ return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g;
+ }
+
+ long TESTED_CALLING_CONVENTION f_8(long a, long b, long c, long d, long e, long f, long g, long h)
+ {
+ return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h;
+ }
+
+ long TESTED_CALLING_CONVENTION f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i)
+ {
+ return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i;
+ }
+
+} // namespace test##TESTED_CALLING_CONVENTION
+
+# endif // defined(TEST_DECLARE_FUNCTIONS)
+
+//------------------------------------------------------------------------------
+// this section wraps the functions
+
+# if defined(TEST_WRAP_FUNCTIONS)
+
+# if !defined(TESTED_CALLING_CONVENTION)
+# error "One calling convention must be defined"
+# endif // !defined(TESTED_CALLING_CONVENTION)
+
+ def("f_0" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_0);
+ def("f_1" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_1);
+ def("f_2" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_2);
+ def("f_3" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_3);
+ def("f_4" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_4);
+ def("f_5" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_5);
+ def("f_6" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_6);
+ def("f_7" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_7);
+ def("f_8" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_8);
+ def("f_9" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION), &BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::f_9);
+
+# endif // defined(TEST_WRAP_FUNCTIONS)
+
+#endif // !defined(TEST_INCLUDE_RECURSION)
diff --git a/libs/python/test/calling_conventions.py b/libs/python/test/calling_conventions.py
new file mode 100644
index 000000000..ce74a8433
--- /dev/null
+++ b/libs/python/test/calling_conventions.py
@@ -0,0 +1,81 @@
+# Copyright Nicolas Lelong, 2010. Distributed under the Boost
+# Software License, Version 1.0 (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> from calling_conventions_ext import *
+>>> f_0__cdecl()
+17041
+>>> f_1__cdecl(1)
+1
+>>> f_2__cdecl(1, 2)
+21
+>>> f_3__cdecl(1, 2, 3)
+321
+>>> f_4__cdecl(1, 2, 3, 4)
+4321
+>>> f_5__cdecl(1, 2, 3, 4, 5)
+54321
+>>> f_6__cdecl(1, 2, 3, 4, 5, 6)
+654321
+>>> f_7__cdecl(1, 2, 3, 4, 5, 6, 7)
+7654321
+>>> f_8__cdecl(1, 2, 3, 4, 5, 6, 7, 8)
+87654321
+>>> f_9__cdecl(1, 2, 3, 4, 5, 6, 7, 8, 9)
+987654321
+>>> f_0__stdcall()
+17041
+>>> f_1__stdcall(1)
+1
+>>> f_2__stdcall(1, 2)
+21
+>>> f_3__stdcall(1, 2, 3)
+321
+>>> f_4__stdcall(1, 2, 3, 4)
+4321
+>>> f_5__stdcall(1, 2, 3, 4, 5)
+54321
+>>> f_6__stdcall(1, 2, 3, 4, 5, 6)
+654321
+>>> f_7__stdcall(1, 2, 3, 4, 5, 6, 7)
+7654321
+>>> f_8__stdcall(1, 2, 3, 4, 5, 6, 7, 8)
+87654321
+>>> f_9__stdcall(1, 2, 3, 4, 5, 6, 7, 8, 9)
+987654321
+>>> f_0__fastcall()
+17041
+>>> f_1__fastcall(1)
+1
+>>> f_2__fastcall(1, 2)
+21
+>>> f_3__fastcall(1, 2, 3)
+321
+>>> f_4__fastcall(1, 2, 3, 4)
+4321
+>>> f_5__fastcall(1, 2, 3, 4, 5)
+54321
+>>> f_6__fastcall(1, 2, 3, 4, 5, 6)
+654321
+>>> f_7__fastcall(1, 2, 3, 4, 5, 6, 7)
+7654321
+>>> f_8__fastcall(1, 2, 3, 4, 5, 6, 7, 8)
+87654321
+>>> f_9__fastcall(1, 2, 3, 4, 5, 6, 7, 8, 9)
+987654321
+"""
+
+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/libs/python/test/calling_conventions_mf.cpp b/libs/python/test/calling_conventions_mf.cpp
new file mode 100644
index 000000000..80ccc4068
--- /dev/null
+++ b/libs/python/test/calling_conventions_mf.cpp
@@ -0,0 +1,159 @@
+//
+// adapted from bind_stdcall_mf_test.cpp - test for bind.hpp + __stdcall (free functions)
+// The purpose of this simple test is to determine if a function can be
+// called from Python with the various existing calling conventions
+//
+// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#if !defined(TEST_INCLUDE_RECURSION)
+
+#define TEST_INCLUDE_RECURSION
+
+//------------------------------------------------------------------------------
+// this section is the main body of the test extension module
+
+#define BOOST_PYTHON_ENABLE_CDECL
+#define BOOST_PYTHON_ENABLE_STDCALL
+#define BOOST_PYTHON_ENABLE_FASTCALL
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <boost/python.hpp>
+using namespace boost::python;
+
+// first define test functions for every calling convention
+
+#define TEST_DECLARE_FUNCTIONS
+
+#define TESTED_CALLING_CONVENTION __cdecl
+#include "calling_conventions_mf.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __stdcall
+#include "calling_conventions_mf.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __fastcall
+#include "calling_conventions_mf.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#undef TEST_DECLARE_FUNCTIONS
+
+// then create a module wrapping the defined functions for every calling convention
+
+BOOST_PYTHON_MODULE( calling_conventions_mf_ext )
+{
+
+#define TEST_WRAP_FUNCTIONS
+
+#define TESTED_CALLING_CONVENTION __cdecl
+#include "calling_conventions_mf.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __stdcall
+#include "calling_conventions_mf.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#define TESTED_CALLING_CONVENTION __fastcall
+#include "calling_conventions_mf.cpp"
+#undef TESTED_CALLING_CONVENTION
+
+#undef TEST_WRAP_FUNCTIONS
+
+}
+
+#else // !defined(TEST_INCLUDE_RECURSION)
+
+//------------------------------------------------------------------------------
+// this section defines the functions to be wrapped
+
+# if defined(TEST_DECLARE_FUNCTIONS)
+
+# if !defined(TESTED_CALLING_CONVENTION)
+# error "One calling convention must be defined"
+# endif // !defined(TESTED_CALLING_CONVENTION)
+
+namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION) {
+
+struct X
+{
+ mutable unsigned int hash;
+
+ X(): hash(0) {}
+
+ void TESTED_CALLING_CONVENTION f0() { f1(17); }
+ void TESTED_CALLING_CONVENTION g0() const { g1(17); }
+
+ void TESTED_CALLING_CONVENTION f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
+ void TESTED_CALLING_CONVENTION g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
+
+ void TESTED_CALLING_CONVENTION f2(int a1, int a2) { f1(a1); f1(a2); }
+ void TESTED_CALLING_CONVENTION g2(int a1, int a2) const { g1(a1); g1(a2); }
+
+ void TESTED_CALLING_CONVENTION f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
+ void TESTED_CALLING_CONVENTION g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
+
+ void TESTED_CALLING_CONVENTION f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
+ void TESTED_CALLING_CONVENTION g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
+
+ void TESTED_CALLING_CONVENTION f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
+ void TESTED_CALLING_CONVENTION g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
+
+ void TESTED_CALLING_CONVENTION f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
+ void TESTED_CALLING_CONVENTION g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
+
+ void TESTED_CALLING_CONVENTION f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
+ void TESTED_CALLING_CONVENTION g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
+
+ void TESTED_CALLING_CONVENTION f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
+ void TESTED_CALLING_CONVENTION g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
+};
+
+} // namespace BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)
+
+# endif // defined(TEST_DECLARE_FUNCTIONS)
+
+//------------------------------------------------------------------------------
+// this section wraps the functions
+
+# if defined(TEST_WRAP_FUNCTIONS)
+
+# if !defined(TESTED_CALLING_CONVENTION)
+# error "One calling convention must be defined"
+# endif // !defined(TESTED_CALLING_CONVENTION)
+
+{
+
+ typedef BOOST_PP_CAT(test, TESTED_CALLING_CONVENTION)::X X;
+
+ class_<X>("X" BOOST_PP_STRINGIZE(TESTED_CALLING_CONVENTION))
+ .def("f0", &X::f0)
+ .def("g0", &X::g0)
+ .def("f1", &X::f1)
+ .def("g1", &X::g1)
+ .def("f2", &X::f2)
+ .def("g2", &X::g2)
+ .def("f3", &X::f3)
+ .def("g3", &X::g3)
+ .def("f4", &X::f4)
+ .def("g4", &X::g4)
+ .def("f5", &X::f5)
+ .def("g5", &X::g5)
+ .def("f6", &X::f6)
+ .def("g6", &X::g6)
+ .def("f7", &X::f7)
+ .def("g7", &X::g7)
+ .def("f8", &X::f8)
+ .def("g8", &X::g8)
+ .def_readonly("hash", &X::hash)
+ ;
+
+}
+
+# endif // defined(TEST_WRAP_FUNCTIONS)
+
+#endif // !defined(TEST_INCLUDE_RECURSION)
diff --git a/libs/python/test/calling_conventions_mf.py b/libs/python/test/calling_conventions_mf.py
new file mode 100644
index 000000000..1ec9c2b6c
--- /dev/null
+++ b/libs/python/test/calling_conventions_mf.py
@@ -0,0 +1,84 @@
+# Copyright Nicolas Lelong, 2010. Distributed under the Boost
+# Software License, Version 1.0 (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> from calling_conventions_mf_ext import *
+>>> x = X__cdecl()
+>>> x.f0()
+>>> x.g0()
+>>> x.f1(1)
+>>> x.g1(1)
+>>> x.f2(1, 2)
+>>> x.g2(1, 2)
+>>> x.f3(1, 2, 3)
+>>> x.g3(1, 2, 3)
+>>> x.f4(1, 2, 3, 4)
+>>> x.g4(1, 2, 3, 4)
+>>> x.f5(1, 2, 3, 4, 5)
+>>> x.g5(1, 2, 3, 4, 5)
+>>> x.f6(1, 2, 3, 4, 5, 6)
+>>> x.g6(1, 2, 3, 4, 5, 6)
+>>> x.f7(1, 2, 3, 4, 5, 6, 7)
+>>> x.g7(1, 2, 3, 4, 5, 6, 7)
+>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
+>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
+>>> x.hash
+2155
+>>> x = X__stdcall()
+>>> x.f0()
+>>> x.g0()
+>>> x.f1(1)
+>>> x.g1(1)
+>>> x.f2(1, 2)
+>>> x.g2(1, 2)
+>>> x.f3(1, 2, 3)
+>>> x.g3(1, 2, 3)
+>>> x.f4(1, 2, 3, 4)
+>>> x.g4(1, 2, 3, 4)
+>>> x.f5(1, 2, 3, 4, 5)
+>>> x.g5(1, 2, 3, 4, 5)
+>>> x.f6(1, 2, 3, 4, 5, 6)
+>>> x.g6(1, 2, 3, 4, 5, 6)
+>>> x.f7(1, 2, 3, 4, 5, 6, 7)
+>>> x.g7(1, 2, 3, 4, 5, 6, 7)
+>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
+>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
+>>> x.hash
+2155
+>>> x = X__fastcall()
+>>> x.f0()
+>>> x.g0()
+>>> x.f1(1)
+>>> x.g1(1)
+>>> x.f2(1, 2)
+>>> x.g2(1, 2)
+>>> x.f3(1, 2, 3)
+>>> x.g3(1, 2, 3)
+>>> x.f4(1, 2, 3, 4)
+>>> x.g4(1, 2, 3, 4)
+>>> x.f5(1, 2, 3, 4, 5)
+>>> x.g5(1, 2, 3, 4, 5)
+>>> x.f6(1, 2, 3, 4, 5, 6)
+>>> x.g6(1, 2, 3, 4, 5, 6)
+>>> x.f7(1, 2, 3, 4, 5, 6, 7)
+>>> x.g7(1, 2, 3, 4, 5, 6, 7)
+>>> x.f8(1, 2, 3, 4, 5, 6, 7, 8)
+>>> x.g8(1, 2, 3, 4, 5, 6, 7, 8)
+>>> x.hash
+2155
+"""
+
+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/libs/python/test/class.cpp b/libs/python/test/class.cpp
new file mode 100644
index 000000000..078bebdf6
--- /dev/null
+++ b/libs/python/test/class.cpp
@@ -0,0 +1,28 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/class.hpp>
+
+using namespace boost::python;
+
+struct X
+{
+ int x;
+ X(int n) : x(n) { }
+};
+
+int x_function(X& x)
+{ return x.x;
+}
+
+
+BOOST_PYTHON_MODULE(class_ext)
+{
+ class_<X>("X", init<int>());
+ def("x_function", x_function);
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/class.py b/libs/python/test/class.py
new file mode 100755
index 000000000..d68ff4378
--- /dev/null
+++ b/libs/python/test/class.py
@@ -0,0 +1,40 @@
+# Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from class_ext import *
+
+Ensure sanity:
+
+ >>> x = X(42)
+ >>> x_function(x)
+ 42
+
+Demonstrate extraction in the presence of metaclass changes:
+
+ >>> class MetaX(X.__class__):
+ ... def __new__(cls, *args):
+ ... return super(MetaX, cls).__new__(cls, *args)
+ >>> class XPlusMetatype(X):
+ ... __metaclass__ = MetaX
+ >>> x = XPlusMetatype(42)
+ >>> x_function(x)
+ 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/libs/python/test/cltree.cpp b/libs/python/test/cltree.cpp
new file mode 100644
index 000000000..518ae37fe
--- /dev/null
+++ b/libs/python/test/cltree.cpp
@@ -0,0 +1,74 @@
+// Copyright David Abrahams 2005. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/utility.hpp>
+
+/* 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>("basic")
+ .def("__repr__",&basic::repr)
+ ;
+
+ boost::python::class_<constant, boost::python::bases<basic>, boost::noncopyable>("constant")
+ ;
+
+
+ boost::python::class_<symbol, symbol_wrapper, boost::noncopyable>("symbol")
+ ;
+
+ boost::python::class_<variable, boost::python::bases<basic>, variable_wrapper>("variable")
+ ;
+}
+
+#include "module_tail.cpp"
+
diff --git a/libs/python/test/complicated.hpp b/libs/python/test/complicated.hpp
new file mode 100644
index 000000000..5ff19aea0
--- /dev/null
+++ b/libs/python/test/complicated.hpp
@@ -0,0 +1,38 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef COMPLICATED_DWA20011215_HPP
+# define COMPLICATED_DWA20011215_HPP
+# include <iostream>
+
+# 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/libs/python/test/const_argument.cpp b/libs/python/test/const_argument.cpp
new file mode 100644
index 000000000..6c5a89456
--- /dev/null
+++ b/libs/python/test/const_argument.cpp
@@ -0,0 +1,30 @@
+/* Copyright 2004 Jonathan Brandmeyer
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * The purpose of this test is to determine if a function can be called from
+ * Python with a const value type as an argument, and whether or not the
+ * presence of a prototype without the cv-qualifier will work around the
+ * compiler's bug.
+ */
+#include <boost/python.hpp>
+#include <boost/type_traits/broken_compiler_spec.hpp>
+using namespace boost::python;
+
+BOOST_TT_BROKEN_COMPILER_SPEC( object )
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
+bool accept_const_arg( object );
+#endif
+
+bool accept_const_arg( const object )
+{
+ return true;
+}
+
+
+BOOST_PYTHON_MODULE( const_argument_ext )
+{
+ def( "accept_const_arg", accept_const_arg );
+}
diff --git a/libs/python/test/const_argument.py b/libs/python/test/const_argument.py
new file mode 100644
index 000000000..15e87e802
--- /dev/null
+++ b/libs/python/test/const_argument.py
@@ -0,0 +1,23 @@
+# Copyright Jonathan Brandmeyer, 2004. Distributed under the Boost
+# Software License, Version 1.0 (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> from const_argument_ext import *
+>>> accept_const_arg(1)
+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/libs/python/test/copy_ctor_mutates_rhs.cpp b/libs/python/test/copy_ctor_mutates_rhs.cpp
new file mode 100644
index 000000000..41eac495e
--- /dev/null
+++ b/libs/python/test/copy_ctor_mutates_rhs.cpp
@@ -0,0 +1,23 @@
+// Copyright David Abrahams 2003.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/detail/copy_ctor_mutates_rhs.hpp>
+#include <boost/static_assert.hpp>
+#include <memory>
+#include <string>
+
+struct foo
+{
+ operator std::auto_ptr<int>&() const;
+};
+
+int main()
+{
+ using namespace boost::python::detail;
+ BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<int>::value);
+ BOOST_STATIC_ASSERT(copy_ctor_mutates_rhs<std::auto_ptr<int> >::value);
+ BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<std::string>::value);
+ BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs<foo>::value);
+ return 0;
+}
diff --git a/libs/python/test/crossmod_exception.py b/libs/python/test/crossmod_exception.py
new file mode 100644
index 000000000..dd50dae27
--- /dev/null
+++ b/libs/python/test/crossmod_exception.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2003 Rational Discovery LLC. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+# at http://www.boost.org/LICENSE_1_0.txt)
+
+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/libs/python/test/crossmod_exception_a.cpp b/libs/python/test/crossmod_exception_a.cpp
new file mode 100644
index 000000000..9526129af
--- /dev/null
+++ b/libs/python/test/crossmod_exception_a.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2003 Rational Discovery LLC
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python.hpp>
+
+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/libs/python/test/crossmod_exception_b.cpp b/libs/python/test/crossmod_exception_b.cpp
new file mode 100644
index 000000000..e2ea491ca
--- /dev/null
+++ b/libs/python/test/crossmod_exception_b.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2003 Rational Discovery LLC
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python.hpp>
+
+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/libs/python/test/crossmod_opaque.py b/libs/python/test/crossmod_opaque.py
new file mode 100644
index 000000000..a7a3cf2cb
--- /dev/null
+++ b/libs/python/test/crossmod_opaque.py
@@ -0,0 +1,16 @@
+# -*- coding: latin-1 -*-
+# Copyright Gottfried Ganßauge 2006.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+if __name__ == '__main__':
+ print "running..."
+
+ import crossmod_opaque_a
+ import crossmod_opaque_b
+
+ crossmod_opaque_a.get()
+ crossmod_opaque_b.get()
+
+ print "Done."
diff --git a/libs/python/test/crossmod_opaque_a.cpp b/libs/python/test/crossmod_opaque_a.cpp
new file mode 100644
index 000000000..80283f47f
--- /dev/null
+++ b/libs/python/test/crossmod_opaque_a.cpp
@@ -0,0 +1,26 @@
+// Copyright Gottfried Ganßauge 2006.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+# include <boost/python/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; }
+
+BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
+
+namespace bpl = boost::python;
+
+BOOST_PYTHON_MODULE(crossmod_opaque_a)
+{
+ bpl::def (
+ "get",
+ &::get,
+ bpl::return_value_policy<bpl::return_opaque_pointer>());
+}
diff --git a/libs/python/test/crossmod_opaque_b.cpp b/libs/python/test/crossmod_opaque_b.cpp
new file mode 100644
index 000000000..1e3e18bcb
--- /dev/null
+++ b/libs/python/test/crossmod_opaque_b.cpp
@@ -0,0 +1,26 @@
+// Copyright Gottfried Ganßauge 2006.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+# include <boost/python/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; }
+
+BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
+
+namespace bpl = boost::python;
+
+BOOST_PYTHON_MODULE(crossmod_opaque_b)
+{
+ bpl::def (
+ "get",
+ &::get,
+ bpl::return_value_policy<bpl::return_opaque_pointer>());
+}
diff --git a/libs/python/test/data_members.cpp b/libs/python/test/data_members.cpp
new file mode 100644
index 000000000..6d2cc7bd4
--- /dev/null
+++ b/libs/python/test/data_members.cpp
@@ -0,0 +1,132 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/return_by_value.hpp>
+#include "test_class.hpp"
+
+#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
+# include <iostream> // 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; }
+ bool q;
+};
+
+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 boost_python_test
+{
+ struct trivial
+ {
+ trivial() : value(123) {}
+ double value;
+ };
+
+ struct Color3
+ {
+ static const Color3 black;
+ };
+
+ const Color3 Color3::black
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ = {}
+#endif
+ ;
+
+ void compilability_test()
+ {
+ class_<trivial>("trivial")
+ .add_property("property", make_getter(&trivial::value, return_value_policy<return_by_value>()))
+ .def_readonly("readonly", &trivial::value)
+ ;
+
+ class_< Color3 >("Color3", init< const Color3 & >())
+ .def_readonly("BLACK", &Color3::black) // line 17
+ ;
+ }
+}
+
+BOOST_PYTHON_MODULE(data_members_ext)
+{
+ using namespace boost_python_test;
+ class_<X>("X", init<int>())
+ .def("value", &X::value)
+ .def("set", &X::set)
+ .def_readonly("x", &X::x)
+ .add_property("fair_value", get_fair_value)
+ ;
+
+ class_<Y>("Y", init<int>())
+ .def("value", &Y::value)
+ .def("set", &Y::set)
+ .def_readwrite("x", &Y::x)
+ .def_readwrite("q", &Y::q)
+ ;
+
+ class_<Var>("Var", init<std::string>())
+ .def_readonly("name", &Var::name)
+ .def_readonly("name2", &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<return_by_value>())
+ .def("get_name2", &Var::get_name2, return_value_policy<return_by_value>())
+
+ .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/libs/python/test/data_members.py b/libs/python/test/data_members.py
new file mode 100644
index 000000000..70784853e
--- /dev/null
+++ b/libs/python/test/data_members.py
@@ -0,0 +1,215 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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)
+
+>>> y = Y(99)
+>>> y.q = True
+>>> y.q
+True
+>>> y.q = False
+>>> y.q
+False
+
+>>> 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/libs/python/test/defaults.cpp b/libs/python/test/defaults.cpp
new file mode 100644
index 000000000..6d87e5d6e
--- /dev/null
+++ b/libs/python/test/defaults.cpp
@@ -0,0 +1,173 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/def.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/list.hpp>
+#include <boost/python/overloads.hpp>
+#include <boost/python/return_internal_reference.hpp>
+
+#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
+# include <iostream> // works around a KCC intermediate code generation bug
+#endif
+
+using namespace boost::python;
+namespace bpl = 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 % bpl::make_tuple(a, b, c, d);
+}
+
+object
+bar(int a, char b, std::string c)
+{
+ return format % bpl::make_tuple(a, b, c, 0.0);
+}
+
+object
+bar(int a, char b)
+{
+ return format % bpl::make_tuple(a, b, "default", 0.0);
+}
+
+object
+bar(int a)
+{
+ return format % bpl::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 % bpl::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 % bpl::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 % bpl::make_tuple(a, b, c, d))
+ {}
+
+ X(std::string s, bool b)
+ : state("Got exactly two arguments from constructor: string(%s); bool(%s); " % bpl::make_tuple(s, b*1))
+ {}
+
+ object
+ bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const
+ {
+ return format % bpl::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); " % bpl::make_tuple(a, b*1);
+ }
+
+ object
+ foo(std::string a, bool b=false) const
+ {
+ return "string(%s); bool(%s); " % bpl::make_tuple(a, b*1);
+ }
+
+ object
+ foo(list a, list b, bool c=false) const
+ {
+ return "list(%s); list(%s); bool(%s); " % bpl::make_tuple(a, b, c*1);
+ }
+
+ 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>("Y", init<>("doc of Y init")) // this should work
+ .def("get_state", &Y::get_state)
+ ;
+
+ class_<X>("X",no_init)
+
+ .def(init<optional<int, char, std::string, double> >("doc of init", args("self", "a", "b", "c", "d")))
+ .def(init<std::string, bool>(args("self", "s", "b"))[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/libs/python/test/defaults.py b/libs/python/test/defaults.py
new file mode 100644
index 000000000..cd51a4a4d
--- /dev/null
+++ b/libs/python/test/defaults.py
@@ -0,0 +1,140 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> 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 selected_doc(obj, *args):
+... doc = obj.__doc__.splitlines()
+... return "\\n".join(["|"+doc[i] for i in args])
+
+>>> print selected_doc(X.__init__, 1, 2, 4, 7, 9)
+|__init__( (object)self [, (int)a [, (str)b [, (str)c [, (float)d]]]]) -> None :
+| doc of init
+| C++ signature :
+|__init__( (object)self, (str)s, (bool)b) -> None :
+| C++ signature :
+
+>>> print selected_doc(Y.__init__, 1, 2, 4)
+|__init__( (object)arg1) -> None :
+| doc of Y init
+| C++ signature :
+
+>>> print selected_doc(X.bar2, 1, 2, 4)
+|bar2( (X)arg1 [, (int)arg2 [, (str)arg3 [, (str)arg4 [, (float)arg5]]]]) -> Y :
+| doc of X::bar2
+| C++ signature :
+
+"""
+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/libs/python/test/destroy_test.cpp b/libs/python/test/destroy_test.cpp
new file mode 100644
index 000000000..cae95ae91
--- /dev/null
+++ b/libs/python/test/destroy_test.cpp
@@ -0,0 +1,59 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/detail/destroy.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+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;
+
+ // This used to cause compiler errors with MSVC 9.0.
+ foo& operator~();
+ foo& T();
+};
+
+void assert_destructions(int n)
+{
+ for (int i = 0; i < n; ++i)
+ BOOST_TEST(marks[i] == i);
+ BOOST_TEST(marks[n] == -1);
+}
+
+int main()
+{
+ assert_destructions(0);
+ typedef int a[2];
+
+ foo* f1 = new foo;
+ boost::python::detail::destroy_referent<foo const volatile&>(f1);
+ assert_destructions(1);
+
+ foo* f2 = new foo[2];
+ typedef foo x[2];
+
+ boost::python::detail::destroy_referent<x const&>(f2);
+ assert_destructions(3);
+
+ typedef foo y[2][2];
+ x* f3 = new y;
+ boost::python::detail::destroy_referent<y&>(f3);
+ assert_destructions(7);
+
+ return boost::report_errors();
+}
diff --git a/libs/python/test/dict.cpp b/libs/python/test/dict.cpp
new file mode 100644
index 000000000..375905d69
--- /dev/null
+++ b/libs/python/test/dict.cpp
@@ -0,0 +1,91 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/dict.hpp>
+#include <exception>
+#include <string>
+
+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.setdefault(3,"default"));
+
+ BOOST_ASSERT(!tmp.has_key(key));
+ //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);
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/dict.py b/libs/python/test/dict.py
new file mode 100644
index 000000000..a321beea9
--- /dev/null
+++ b/libs/python/test/dict.py
@@ -0,0 +1,45 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> 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) #doctest: +NORMALIZE_WHITESPACE
+a test string
+13
+None
+{1.5: 13, 1: 'a test string'}
+default
+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/libs/python/test/docstring.cpp b/libs/python/test/docstring.cpp
new file mode 100644
index 000000000..c6cc0252b
--- /dev/null
+++ b/libs/python/test/docstring.cpp
@@ -0,0 +1,116 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/operators.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/docstring_options.hpp>
+#include <boost/python/scope.hpp>
+#include <boost/python/manage_new_object.hpp>
+#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 <math.h>
+
+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>("X",
+ "A simple class wrapper around a C++ int\n"
+ "includes some error-checking"
+
+ , init<int>(
+ "this is the __init__ function\n"
+ "its documentation has two lines."
+ , args("self", "value")
+ )
+
+ )
+ .def("value", &X::value,
+ "gets the value of the object"
+ , args("self"))
+ .def( "value", &X::value,
+ "also gets the value of the object"
+ , args("self"))
+ ;
+
+ def("create", create, return_value_policy<manage_new_object>(),
+ "creates a new X object", args("value"));
+
+ def("fact", fact, "compute the factorial", args("n"));
+
+ {
+ docstring_options doc_options;
+ doc_options.disable_user_defined();
+ def("fact_usr_off_1", fact, "usr off 1", args("n"));
+ doc_options.enable_user_defined();
+ def("fact_usr_on_1", fact, "usr on 1", args("n"));
+ doc_options.disable_user_defined();
+ def("fact_usr_off_2", fact, "usr off 2", args("n"));
+ }
+ def("fact_usr_on_2", fact, "usr on 2", args("n"));
+
+ {
+ docstring_options doc_options(true, false);
+ def("fact_sig_off_1", fact, "sig off 1", args("n"));
+ doc_options.enable_signatures();
+ def("fact_sig_on_1", fact, "sig on 1", args("n"));
+ doc_options.disable_signatures();
+ def("fact_sig_off_2", fact, "sig off 2", args("n"));
+ }
+ def("fact_sig_on_2", fact, "sig on 2", args("n"));
+
+ {
+ docstring_options doc_options(false);
+ def("fact_usr_off_sig_off_1", fact, "usr off sig off 1", args("n"));
+ {
+ docstring_options nested_doc_options;
+ def("fact_usr_on_sig_on_1", fact, "usr on sig on 1", args("n"));
+ nested_doc_options.disable_all();
+ nested_doc_options.enable_user_defined();
+ def("fact_usr_on_sig_off_1", fact, "usr on sig off 1", args("n"));
+ nested_doc_options.enable_all();
+ def("fact_usr_on_sig_on_2", fact, "usr on sig on 2", args("n"));
+ }
+ def("fact_usr_off_sig_off_2", fact, "usr off sig off 2", args("n"));
+ }
+
+ {
+ docstring_options doc_options(true);
+ doc_options.disable_cpp_signatures();
+ def("fact_usr_on_psig_on_csig_off_1", fact, "usr on psig on csig off 1", args("n"));
+ doc_options.enable_cpp_signatures();
+ doc_options.disable_py_signatures();
+ def("fact_usr_on_psig_off_csig_on_1", fact, "usr on psig off csig on 1", args("n"));
+ doc_options.enable_py_signatures();
+ doc_options.disable_user_defined();
+ doc_options.disable_cpp_signatures();
+ def("fact_usr_off_psig_on_csig_off_1", fact, "usr off psig on csig off 1", args("n"));
+ doc_options.enable_cpp_signatures();
+ doc_options.disable_py_signatures();
+ def("fact_usr_off_psig_off_csig_on_1", fact, "usr off psig off csig on 1", args("n"));
+ }
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/docstring.py b/libs/python/test/docstring.py
new file mode 100644
index 000000000..528ce8456
--- /dev/null
+++ b/libs/python/test/docstring.py
@@ -0,0 +1,153 @@
+# Copyright David Abrahams & Ralf W. Grosse-Kunsteve 2004-2006.
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from docstring_ext import *
+
+>>> def selected_doc(obj, *args):
+... doc = obj.__doc__.splitlines()
+... return "\\n".join(["|"+doc[i] for i in args])
+
+>>> print selected_doc(X.__init__, 1, 2, 3, 4, 5)
+|__init__( (object)self, (int)value) -> None :
+| this is the __init__ function
+| its documentation has two lines.
+|
+| C++ signature :
+
+>>> print selected_doc(X.value, 1, 2, 4, 7, 8, 10)
+|value( (X)self) -> int :
+| gets the value of the object
+| C++ signature :
+|value( (X)self) -> int :
+| also gets the value of the object
+| C++ signature :
+
+>>> print selected_doc(create, 1, 2, 3, 4)
+|create( (int)value) -> X :
+| creates a new X object
+|
+| C++ signature :
+
+>>> print selected_doc(fact, 1, 2, 3, 4)
+|fact( (int)n) -> int :
+| compute the factorial
+|
+| C++ signature :
+
+>>> len(fact_usr_off_1.__doc__.splitlines())
+5
+>>> print selected_doc(fact_usr_off_1, 1, 3)
+|fact_usr_off_1( (int)n) -> int :
+| C++ signature :
+>>> len(fact_usr_on_1.__doc__.splitlines())
+6
+>>> print selected_doc(fact_usr_on_1, 1, 2, 4)
+|fact_usr_on_1( (int)n) -> int :
+| usr on 1
+| C++ signature :
+>>> len(fact_usr_off_2.__doc__.splitlines())
+5
+>>> print selected_doc(fact_usr_off_2, 1, 3)
+|fact_usr_off_2( (int)n) -> int :
+| C++ signature :
+>>> len(fact_usr_on_2.__doc__.splitlines())
+6
+>>> print selected_doc(fact_usr_on_2, 1, 2, 4)
+|fact_usr_on_2( (int)n) -> int :
+| usr on 2
+| C++ signature :
+
+
+>>> len(fact_sig_off_1.__doc__.splitlines())
+2
+>>> print selected_doc(fact_sig_off_1, 1)
+|sig off 1
+>>> len(fact_sig_on_1.__doc__.splitlines())
+6
+>>> print selected_doc(fact_sig_on_1, 1, 2, 4)
+|fact_sig_on_1( (int)n) -> int :
+| sig on 1
+| C++ signature :
+
+>>> len(fact_sig_off_2.__doc__.splitlines())
+2
+>>> print selected_doc(fact_sig_off_2, 1)
+|sig off 2
+>>> len(fact_sig_on_2.__doc__.splitlines())
+6
+>>> print selected_doc(fact_sig_on_2, 1, 2, 4)
+|fact_sig_on_2( (int)n) -> int :
+| sig on 2
+| C++ signature :
+
+
+>>> print fact_usr_off_sig_off_1.__doc__
+None
+>>> len(fact_usr_on_sig_on_1.__doc__.splitlines())
+6
+>>> print selected_doc(fact_usr_on_sig_on_1, 1, 2, 4)
+|fact_usr_on_sig_on_1( (int)n) -> int :
+| usr on sig on 1
+| C++ signature :
+
+>>> len(fact_usr_on_sig_off_1.__doc__.splitlines())
+2
+>>> print selected_doc(fact_usr_on_sig_off_1, 1)
+|usr on sig off 1
+>>> len(fact_usr_on_sig_on_2.__doc__.splitlines())
+6
+>>> print selected_doc(fact_usr_on_sig_on_2, 1, 2, 4)
+|fact_usr_on_sig_on_2( (int)n) -> int :
+| usr on sig on 2
+| C++ signature :
+
+>>> print selected_doc(fact_usr_on_psig_on_csig_off_1, 1, 2)
+|fact_usr_on_psig_on_csig_off_1( (int)n) -> int :
+| usr on psig on csig off 1
+
+>>> print selected_doc(fact_usr_on_psig_off_csig_on_1, 1, 3)
+|usr on psig off csig on 1
+|C++ signature :
+
+>>> print fact_usr_off_psig_on_csig_off_1.__doc__.splitlines()[1]
+fact_usr_off_psig_on_csig_off_1( (int)n) -> int
+
+>>> print selected_doc(fact_usr_off_psig_off_csig_on_1,1)
+|C++ signature :
+
+
+'''
+
+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/libs/python/test/enable_shared_from_this.cpp b/libs/python/test/enable_shared_from_this.cpp
new file mode 100644
index 000000000..c246284a1
--- /dev/null
+++ b/libs/python/test/enable_shared_from_this.cpp
@@ -0,0 +1,48 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/call_method.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/def.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include "test_class.hpp"
+
+#include <memory>
+
+using namespace boost::python;
+using boost::shared_ptr;
+
+class Test;
+typedef shared_ptr<Test> TestPtr;
+
+class Test : public boost::enable_shared_from_this<Test> {
+public:
+ static TestPtr construct() {
+ return TestPtr(new Test);
+ }
+
+ void act() {
+ TestPtr kungFuDeathGrip(shared_from_this());
+ }
+
+ void take(TestPtr t) {
+ }
+};
+
+BOOST_PYTHON_MODULE(enable_shared_from_this_ext)
+{
+ class_<Test, TestPtr, boost::noncopyable>("Test")
+ .def("construct", &Test::construct).staticmethod("construct")
+ .def("act", &Test::act)
+ .def("take", &Test::take)
+ ;
+}
+
+#include "module_tail.cpp"
+
+
diff --git a/libs/python/test/enable_shared_from_this.py b/libs/python/test/enable_shared_from_this.py
new file mode 100755
index 000000000..cca46ec81
--- /dev/null
+++ b/libs/python/test/enable_shared_from_this.py
@@ -0,0 +1,26 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from enable_shared_from_this_ext import *
+
+>>> x = Test.construct()
+>>> x.take(x)
+>>> x.act()
+'''
+
+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/libs/python/test/enum.cpp b/libs/python/test/enum.cpp
new file mode 100644
index 000000000..e5c4f4fa9
--- /dev/null
+++ b/libs/python/test/enum.cpp
@@ -0,0 +1,55 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/enum.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
+# include <boost/type_traits/is_enum.hpp>
+# include <boost/mpl/bool.hpp>
+#endif
+using namespace boost::python;
+
+enum color { red = 1, green = 2, blue = 4, blood = 1 };
+
+#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
+namespace boost // Pro7 has a hard time detecting enums
+{
+ template <> struct is_enum<color> : boost::mpl::true_ {};
+}
+#endif
+
+color identity_(color x) { return x; }
+
+struct colorized {
+ colorized() : x(red) {}
+ color x;
+};
+
+BOOST_PYTHON_MODULE(enum_ext)
+{
+ enum_<color>("color")
+ .value("red", red)
+ .value("green", green)
+ .value("blue", blue)
+ .value("blood", blood)
+ .export_values()
+ ;
+
+ def("identity", identity_);
+
+#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
+ color colorized::*px = &colorized::x;
+ class_<colorized>("colorized")
+ .def_readwrite("x", px)
+ ;
+#else
+ class_<colorized>("colorized")
+ .def_readwrite("x", &colorized::x)
+ ;
+#endif
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/enum.py b/libs/python/test/enum.py
new file mode 100644
index 000000000..c3ba3fe7e
--- /dev/null
+++ b/libs/python/test/enum.py
@@ -0,0 +1,85 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from enum_ext import *
+
+>>> identity(color.red) # in case of duplicated enums it always take the last enum
+enum_ext.color.blood
+
+>>> identity(color.green)
+enum_ext.color.green
+
+>>> identity(color.blue)
+enum_ext.color.blue
+
+>>> identity(color(1)) # in case of duplicated enums it always take the last enum
+enum_ext.color.blood
+
+>>> 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.blood
+
+>>> 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.blood
+>>> c.x = green
+>>> c.x
+enum_ext.color.green
+>>> red == blood
+True
+>>> red == green
+False
+>>> hash(red) == hash(blood)
+True
+>>> hash(red) == hash(green)
+False
+'''
+
+# pickling of enums only works with Python 2.3 or higher
+exercise_pickling = '''
+>>> import pickle
+>>> p = pickle.dumps(color.green, pickle.HIGHEST_PROTOCOL)
+>>> l = pickle.loads(p)
+>>> identity(l)
+enum_ext.color.green
+'''
+
+def run(args = None):
+ import sys
+ import doctest
+ import pickle
+
+ if args is not None:
+ sys.argv = args
+ self = sys.modules.get(__name__)
+ if (hasattr(pickle, "HIGHEST_PROTOCOL")):
+ self.__doc__ += exercise_pickling
+ return doctest.testmod(self)
+
+if __name__ == '__main__':
+ print "running..."
+ import sys
+ status = run()[0]
+ if (status == 0): print "Done."
+ sys.exit(status)
diff --git a/libs/python/test/exception_translator.cpp b/libs/python/test/exception_translator.cpp
new file mode 100644
index 000000000..1e91c9296
--- /dev/null
+++ b/libs/python/test/exception_translator.cpp
@@ -0,0 +1,28 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/exception_translator.hpp>
+
+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<error>(&translate);
+
+ def("throw_error", throw_error);
+}
+
diff --git a/libs/python/test/exception_translator.py b/libs/python/test/exception_translator.py
new file mode 100644
index 000000000..9537c6f6f
--- /dev/null
+++ b/libs/python/test/exception_translator.py
@@ -0,0 +1,27 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/exec.cpp b/libs/python/test/exec.cpp
new file mode 100644
index 000000000..9fb005ea5
--- /dev/null
+++ b/libs/python/test/exec.cpp
@@ -0,0 +1,193 @@
+// Copyright Stefan Seefeld 2005.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+
+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() {}
+ virtual std::string hello() { return "Hello from C++!";}
+};
+
+// Familiar Boost.Python wrapper class for Base
+struct BaseWrap : Base, python::wrapper<Base>
+{
+ virtual std::string hello()
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ // workaround for VC++ 6.x or 7.0, see
+ // http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
+ return python::call<std::string>(this->get_override("hello").ptr());
+#else
+ return this->get_override("hello")();
+#endif
+ }
+};
+
+// Pack the Base class wrapper into a module
+BOOST_PYTHON_MODULE(embedded_hello)
+{
+ python::class_<BaseWrap, boost::noncopyable> base("Base");
+}
+
+
+void eval_test()
+{
+ python::object result = python::eval("'abcdefg'.upper()");
+ std::string value = python::extract<std::string>(result) BOOST_EXTRACT_WORKAROUND;
+ BOOST_TEST(value == "ABCDEFG");
+}
+
+void exec_test()
+{
+ // Register the module with the interpreter
+ if (PyImport_AppendInittab(const_cast<char*>("embedded_hello"),
+#if PY_VERSION_HEX >= 0x03000000
+ PyInit_embedded_hello
+#else
+ initembedded_hello
+#endif
+ ) == -1)
+ throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
+ "builtin modules");
+ // Retrieve the main module
+ python::object main = python::import("__main__");
+
+ // Retrieve the main module's namespace
+ python::object global(main.attr("__dict__"));
+
+ // Define the derived class in Python.
+ python::object result = python::exec(
+ "from embedded_hello import * \n"
+ "class PythonDerived(Base): \n"
+ " def hello(self): \n"
+ " return 'Hello from Python!' \n",
+ global, global);
+
+ python::object PythonDerived = global["PythonDerived"];
+
+ // Creating and using instances of the C++ class is as easy as always.
+ CppDerived cpp;
+ BOOST_TEST(cpp.hello() == "Hello from C++!");
+
+ // But now creating and using instances of the Python class is almost
+ // as easy!
+ python::object py_base = PythonDerived();
+ Base& py = python::extract<Base&>(py_base) BOOST_EXTRACT_WORKAROUND;
+
+ // Make sure the right 'hello' method is called.
+ BOOST_TEST(py.hello() == "Hello from Python!");
+}
+
+void exec_file_test(std::string const &script)
+{
+ // Run a python script in an empty environment.
+ python::dict global;
+ python::object result = python::exec_file(script.c_str(), global, global);
+
+ // Extract an object the script stored in the global dictionary.
+ BOOST_TEST(python::extract<int>(global["number"]) == 42);
+}
+
+void exec_test_error()
+{
+ // Execute a statement that raises a python exception.
+ python::dict global;
+ python::object result = python::exec("print(unknown) \n", global, global);
+}
+
+void exercise_embedding_html()
+{
+ using namespace boost::python;
+ /* code from: libs/python/doc/tutorial/doc/tutorial.qbk
+ (generates libs/python/doc/tutorial/doc/html/python/embedding.html)
+ */
+ object main_module = import("__main__");
+ object main_namespace = main_module.attr("__dict__");
+
+ object ignored = exec("hello = file('hello.txt', 'w')\n"
+ "hello.write('Hello world!')\n"
+ "hello.close()",
+ main_namespace);
+}
+
+void check_pyerr(bool pyerr_expected=false)
+{
+ if (PyErr_Occurred())
+ {
+ if (!pyerr_expected) {
+ BOOST_ERROR("Python Error detected");
+ PyErr_Print();
+ }
+ else {
+ PyErr_Clear();
+ }
+ }
+ else
+ {
+ BOOST_ERROR("A C++ exception was thrown for which "
+ "there was no exception handler registered.");
+ }
+}
+
+int main(int argc, char **argv)
+{
+ BOOST_TEST(argc == 2 || argc == 3);
+ std::string script = argv[1];
+ // Initialize the interpreter
+ Py_Initialize();
+
+ if (python::handle_exception(eval_test)) {
+ check_pyerr();
+ }
+ else if(python::handle_exception(exec_test)) {
+ check_pyerr();
+ }
+ else if (python::handle_exception(boost::bind(exec_file_test, script))) {
+ check_pyerr();
+ }
+
+ if (python::handle_exception(exec_test_error))
+ {
+ check_pyerr(/*pyerr_expected*/ true);
+ }
+ else
+ {
+ BOOST_ERROR("Python exception expected, but not seen.");
+ }
+
+ if (argc > 2) {
+ // The main purpose is to test compilation. Since this test generates
+ // a file and I (rwgk) am uncertain about the side-effects, run it only
+ // if explicitly requested.
+ exercise_embedding_html();
+ }
+
+ // Boost.Python doesn't support Py_Finalize yet.
+ // Py_Finalize();
+ return boost::report_errors();
+}
+
+// Including this file makes sure
+// that on Windows, any crashes (e.g. null pointer dereferences) invoke
+// the debugger immediately, rather than being translated into structured
+// exceptions that can interfere with debugging.
+#include "module_tail.cpp"
diff --git a/libs/python/test/exec.py b/libs/python/test/exec.py
new file mode 100644
index 000000000..c7bf28f35
--- /dev/null
+++ b/libs/python/test/exec.py
@@ -0,0 +1,6 @@
+# Copyright Stefan Seefeld 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+if 1:
+ number = 42
diff --git a/libs/python/test/extract.cpp b/libs/python/test/extract.cpp
new file mode 100644
index 000000000..40584a077
--- /dev/null
+++ b/libs/python/test/extract.cpp
@@ -0,0 +1,143 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/extract.hpp>
+#include <boost/python/list.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/reference_existing_object.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/implicit.hpp>
+#include <string>
+#include <boost/lexical_cast.hpp>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+#include "test_class.hpp"
+
+using namespace boost::python;
+
+typedef test_class<> X;
+
+bool extract_bool(object x) { return extract<bool>(x); }
+
+boost::python::list extract_list(object x)
+{
+ extract<list> 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);
+ if (is_list_1 != is_list_2) {
+ throw std::runtime_error("is_list_1 == is_list_2 failure.");
+ }
+ return get_list();
+}
+
+char const* extract_cstring(object x)
+{
+ return extract<char const*>(x);
+}
+
+std::string extract_string(object x)
+{
+ std::string s = extract<std::string>(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 <= 900
+# pragma warning(push)
+# pragma warning(disable:473) // intel/win32 does too
+#endif
+
+ return extract<std::string const&>(x);
+
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 800
+# pragma warning(pop)
+#endif
+}
+
+X extract_X(object x)
+{
+ return extract<X>(x);
+}
+
+X* extract_X_ptr(object x) { return extract<X*>(x); }
+
+X& extract_X_ref(object x)
+{
+ extract<X&> get_x(x);
+ return get_x;
+}
+
+int double_X(object n)
+{
+ extract<X> x(n);
+ return x().value() + x().value();
+}
+
+bool check_bool(object x) { return extract<bool>(x).check(); }
+bool check_list(object x) { return extract<list>(x).check(); }
+bool check_cstring(object x) { return extract<char const*>(x).check(); }
+bool check_string(object x) { return extract<std::string>(x).check(); }
+bool check_string_cref(object x) { return extract<std::string const&>(x).check(); }
+bool check_X(object x) { return extract<X>(x).check(); }
+bool check_X_ptr(object x) { return extract<X*>(x).check(); }
+bool check_X_ref(object x) { return extract<X&>(x).check(); }
+
+std::string x_rep(X const& x)
+{
+ return "X(" + boost::lexical_cast<std::string>(x.value()) + ")";
+}
+
+BOOST_PYTHON_MODULE(extract_ext)
+{
+ implicitly_convertible<int, X>();
+
+ 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<reference_existing_object>());
+ def("extract_X", extract_X);
+ def("extract_X_ptr", extract_X_ptr, return_value_policy<reference_existing_object>());
+ def("extract_X_ref", extract_X_ref, return_value_policy<reference_existing_object>());
+
+ 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>("X", init<int>())
+ .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&>(x_obj);
+ if (x.value() != 3) {
+ throw std::runtime_error("x.value() == 3 failure.");
+ }
+}
+
+
+#include "module_tail.cpp"
+
diff --git a/libs/python/test/extract.py b/libs/python/test/extract.py
new file mode 100644
index 000000000..842a9f6e4
--- /dev/null
+++ b/libs/python/test/extract.py
@@ -0,0 +1,107 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+ >>> 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/libs/python/test/if_else.cpp b/libs/python/test/if_else.cpp
new file mode 100644
index 000000000..1c6258db7
--- /dev/null
+++ b/libs/python/test/if_else.cpp
@@ -0,0 +1,44 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/static_assert.hpp>
+#include <boost/python/detail/if_else.hpp>
+#include <boost/type_traits/same_traits.hpp>
+
+ typedef char c1;
+ typedef char c2[2];
+ typedef char c3[3];
+ typedef char c4[4];
+
+template <unsigned size>
+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_<void*>::type type;
+};
+
+int main()
+{
+ BOOST_STATIC_ASSERT((boost::is_same<choose<1>::type,c1>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<choose<2>::type,c2>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<choose<3>::type,c3>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<choose<4>::type,c4>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<choose<5>::type,void*>::value));
+ return 0;
+}
diff --git a/libs/python/test/implicit.cpp b/libs/python/test/implicit.cpp
new file mode 100644
index 000000000..a1bae59e8
--- /dev/null
+++ b/libs/python/test/implicit.cpp
@@ -0,0 +1,48 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/class.hpp>
+#include <boost/python/implicit.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#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 ~foo() {}; // silence compiler warnings
+ virtual void f() = 0;
+ operator bar() const { return bar(); }
+};
+
+BOOST_PYTHON_MODULE(implicit_ext)
+{
+ implicitly_convertible<foo,bar>();
+ implicitly_convertible<int,X>();
+
+ def("x_value", x_value);
+ def("make_x", make_x);
+
+ class_<X>("X", init<int>())
+ .def("value", &X::value)
+ .def("set", &X::set)
+ ;
+
+ implicitly_convertible<X,int>();
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/implicit.py b/libs/python/test/implicit.py
new file mode 100644
index 000000000..ac82d9486
--- /dev/null
+++ b/libs/python/test/implicit.py
@@ -0,0 +1,44 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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'
+
+>>> print x_value.__doc__.splitlines()[1]
+x_value( (X)arg1) -> int :
+
+>>> print make_x.__doc__.splitlines()[1]
+make_x( (object)arg1) -> X :
+
+>>> print X.value.__doc__.splitlines()[1]
+value( (X)arg1) -> int :
+
+>>> print X.set.__doc__.splitlines()[1]
+set( (X)arg1, (object)arg2) -> 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/libs/python/test/import_.cpp b/libs/python/test/import_.cpp
new file mode 100644
index 000000000..3e21de0ba
--- /dev/null
+++ b/libs/python/test/import_.cpp
@@ -0,0 +1,70 @@
+// Copyright Stefan Seefeld 2007.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+#include <sstream>
+
+namespace bpl = boost::python;
+
+void import_test(char const *py_file_path)
+{
+ // Retrieve the main module
+ bpl::object main = bpl::import("__main__");
+
+ // Retrieve the main module's namespace
+ bpl::object global(main.attr("__dict__"));
+
+ // Inject search path for import_ module
+
+ bpl::str script(
+ "import sys, os.path\n"
+ "path = os.path.dirname(%r)\n"
+ "sys.path.insert(0, path)"
+ % bpl::str(py_file_path));
+
+ bpl::object result = bpl::exec(script, global, global);
+
+ // Retrieve the main module
+ bpl::object import_ = bpl::import("import_");
+ int value = bpl::extract<int>(import_.attr("value")) BOOST_EXTRACT_WORKAROUND;
+ std::cout << value << std::endl;
+ BOOST_TEST(value == 42);
+}
+
+int main(int argc, char **argv)
+{
+ BOOST_TEST(argc == 2);
+
+ // Initialize the interpreter
+ Py_Initialize();
+
+ if (bpl::handle_exception(boost::bind(import_test,argv[1])))
+ {
+ if (PyErr_Occurred())
+ {
+ BOOST_ERROR("Python Error detected");
+ PyErr_Print();
+ }
+ else
+ {
+ BOOST_ERROR("A C++ exception was thrown for which "
+ "there was no exception handler registered.");
+ }
+ }
+
+ // Boost.Python doesn't support Py_Finalize yet.
+ // Py_Finalize();
+ return boost::report_errors();
+}
+
+// Including this file makes sure
+// that on Windows, any crashes (e.g. null pointer dereferences) invoke
+// the debugger immediately, rather than being translated into structured
+// exceptions that can interfere with debugging.
+#include "module_tail.cpp"
diff --git a/libs/python/test/import_.py b/libs/python/test/import_.py
new file mode 100644
index 000000000..48de6e5ec
--- /dev/null
+++ b/libs/python/test/import_.py
@@ -0,0 +1,5 @@
+# Copyright Stefan Seefeld 2007. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+value = 42
diff --git a/libs/python/test/indirect_traits_test.cpp b/libs/python/test/indirect_traits_test.cpp
new file mode 100644
index 000000000..594cfe555
--- /dev/null
+++ b/libs/python/test/indirect_traits_test.cpp
@@ -0,0 +1,117 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//#include <stdio.h>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+#include <boost/type_traits/is_member_function_pointer.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/python/detail/indirect_traits.hpp>
+#include <boost/mpl/assert.hpp>
+
+//#define print(expr) printf("%s ==> %s\n", #expr, expr)
+
+// not all the compilers can handle an incomplete class type here.
+struct X {};
+
+using namespace boost::python::indirect_traits;
+
+typedef void (X::*pmf)();
+
+BOOST_MPL_ASSERT((is_reference_to_function<int (&)()>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_function<int (*)()>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_function<int&>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_function<pmf>));
+
+BOOST_MPL_ASSERT_NOT((is_pointer_to_function<int (&)()>));
+BOOST_MPL_ASSERT((is_pointer_to_function<int (*)()>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_function<int (*&)()>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_function<int (*const&)()>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_function<pmf>));
+
+BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<int (&)()>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<int (*)()>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<int&>));
+BOOST_MPL_ASSERT((is_reference_to_function_pointer<int (*&)()>));
+BOOST_MPL_ASSERT((is_reference_to_function_pointer<int (*const&)()>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_function_pointer<pmf>));
+
+BOOST_MPL_ASSERT((is_reference_to_pointer<int*&>));
+BOOST_MPL_ASSERT((is_reference_to_pointer<int* const&>));
+BOOST_MPL_ASSERT((is_reference_to_pointer<int*volatile&>));
+BOOST_MPL_ASSERT((is_reference_to_pointer<int*const volatile&>));
+BOOST_MPL_ASSERT((is_reference_to_pointer<int const*&>));
+BOOST_MPL_ASSERT((is_reference_to_pointer<int const* const&>));
+BOOST_MPL_ASSERT((is_reference_to_pointer<int const*volatile&>));
+BOOST_MPL_ASSERT((is_reference_to_pointer<int const*const volatile&>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<pmf>));
+
+BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<int const volatile>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<int>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_pointer<int*>));
+
+BOOST_MPL_ASSERT_NOT((is_reference_to_const<int*&>));
+BOOST_MPL_ASSERT((is_reference_to_const<int* const&>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_const<int*volatile&>));
+BOOST_MPL_ASSERT((is_reference_to_const<int*const volatile&>));
+
+BOOST_MPL_ASSERT_NOT((is_reference_to_const<int const volatile>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_const<int>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_const<int*>));
+
+BOOST_MPL_ASSERT((is_reference_to_non_const<int*&>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int* const&>));
+BOOST_MPL_ASSERT((is_reference_to_non_const<int*volatile&>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int*const volatile&>));
+
+BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int const volatile>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_non_const<int*>));
+
+BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int*&>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int* const&>));
+BOOST_MPL_ASSERT((is_reference_to_volatile<int*volatile&>));
+BOOST_MPL_ASSERT((is_reference_to_volatile<int*const volatile&>));
+
+BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int const volatile>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int>));
+BOOST_MPL_ASSERT_NOT((is_reference_to_volatile<int*>));
+
+namespace tt = boost::python::indirect_traits;
+
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<int>));
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<int&>));
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<int*>));
+
+
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<pmf>));
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<pmf const&>));
+
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_class<X>));
+
+BOOST_MPL_ASSERT((tt::is_reference_to_class<X&>));
+BOOST_MPL_ASSERT((tt::is_reference_to_class<X const&>));
+BOOST_MPL_ASSERT((tt::is_reference_to_class<X volatile&>));
+BOOST_MPL_ASSERT((tt::is_reference_to_class<X const volatile&>));
+
+BOOST_MPL_ASSERT_NOT((is_pointer_to_class<int>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_class<int*>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_class<int&>));
+
+BOOST_MPL_ASSERT_NOT((is_pointer_to_class<X>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_class<X&>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_class<pmf>));
+BOOST_MPL_ASSERT_NOT((is_pointer_to_class<pmf const>));
+BOOST_MPL_ASSERT((is_pointer_to_class<X*>));
+BOOST_MPL_ASSERT((is_pointer_to_class<X const*>));
+BOOST_MPL_ASSERT((is_pointer_to_class<X volatile*>));
+BOOST_MPL_ASSERT((is_pointer_to_class<X const volatile*>));
+
+BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf&>));
+BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf const&>));
+BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf volatile&>));
+BOOST_MPL_ASSERT((tt::is_reference_to_member_function_pointer<pmf const volatile&>));
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_member_function_pointer<pmf[2]>));
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_member_function_pointer<pmf(&)[2]>));
+BOOST_MPL_ASSERT_NOT((tt::is_reference_to_member_function_pointer<pmf>));
+
diff --git a/libs/python/test/injected.cpp b/libs/python/test/injected.cpp
new file mode 100644
index 000000000..73e1e14ba
--- /dev/null
+++ b/libs/python/test/injected.cpp
@@ -0,0 +1,39 @@
+// Copyright David Abrahams 2003.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include "test_class.hpp"
+#include <memory>
+#include <boost/shared_ptr.hpp>
+#include <boost/python/make_constructor.hpp>
+#include <boost/python/args.hpp>
+
+using namespace boost::python;
+
+typedef test_class<> X;
+
+X* empty() { return new X(1000); }
+
+std::auto_ptr<X> sum(int a, int b) { return std::auto_ptr<X>(new X(a+b)); }
+
+boost::shared_ptr<X> product(int a, int b, int c)
+{
+ return boost::shared_ptr<X>(new X(a*b*c));
+}
+
+BOOST_PYTHON_MODULE(injected_ext)
+{
+ class_<X>("X", init<int>())
+ .def("__init__", make_constructor(empty))
+ .def("__init__", make_constructor(sum))
+ .def("__init__", make_constructor(product
+ , default_call_policies()
+ , ( arg_("a"), arg_("b"), arg_("c"))
+ ),
+ "this is product's docstring")
+ .def("value", &X::value)
+ ;
+}
diff --git a/libs/python/test/injected.py b/libs/python/test/injected.py
new file mode 100644
index 000000000..32ea0bf9d
--- /dev/null
+++ b/libs/python/test/injected.py
@@ -0,0 +1,28 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from injected_ext import *
+>>> X(3,5).value() - (3+5)
+0
+>>> X(a=3,b=5,c=7).value() - (3*5*7)
+0
+>>> X().value()
+1000
+'''
+
+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/libs/python/test/input_iterator.cpp b/libs/python/test/input_iterator.cpp
new file mode 100644
index 000000000..70b994186
--- /dev/null
+++ b/libs/python/test/input_iterator.cpp
@@ -0,0 +1,48 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/iterator.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <list>
+
+using namespace boost::python;
+
+typedef std::list<int> 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<doubler, list_int::iterator> doubling_iterator;
+typedef std::pair<doubling_iterator,doubling_iterator> list_range2;
+
+list_range2 range2(list_int& x)
+{
+ return list_range2(
+ boost::make_transform_iterator<doubler>(x.begin(), doubler())
+ , boost::make_transform_iterator<doubler>(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>("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/libs/python/test/int_map_indexing_suite.cpp b/libs/python/test/int_map_indexing_suite.cpp
new file mode 100644
index 000000000..397850131
--- /dev/null
+++ b/libs/python/test/int_map_indexing_suite.cpp
@@ -0,0 +1,16 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/class.hpp>
+#include <boost/python/suite/indexing/map_indexing_suite.hpp>
+
+void int_map_indexing_suite()
+{
+ using namespace boost::python;
+
+ // Compile check only...
+ class_<std::map<int, int> >("IntMap")
+ .def(map_indexing_suite<std::map<int, int> >())
+ ;
+}
diff --git a/libs/python/test/iterator.cpp b/libs/python/test/iterator.cpp
new file mode 100644
index 000000000..458ba2926
--- /dev/null
+++ b/libs/python/test/iterator.cpp
@@ -0,0 +1,137 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/return_internal_reference.hpp>
+#include <boost/python/copy_non_const_reference.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/iterator.hpp>
+#include <list>
+#include <utility>
+#include <iterator>
+#include <algorithm>
+
+using namespace boost::python;
+
+typedef std::list<int> list_int;
+typedef std::list<list_int> 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_int::iterator,list_int::iterator> 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>("list_int")
+ .def("push_back", push_back)
+ .def("back", back)
+ .def("__iter__", iterator<list_int>())
+ ;
+
+ class_<list_range>("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>("list_range2")
+
+ // We can specify member functions returning a non-const reference
+ .def("__iter__", range(&list_range2::begin, &list_range2::end))
+ ;
+
+ class_<two_lists>("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<return_value_policy<copy_non_const_reference> >(
+ &two_lists::two_begin, &two_lists::two_end))
+
+ // Prove that we can specify call policies and target
+ .add_property(
+ "twosies"
+ , range<return_value_policy<copy_non_const_reference>, 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>("list_list")
+ .def("push_back", push_list_back)
+ .def("__iter__", iterator<list_list,return_internal_reference<> >())
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/iterator.py b/libs/python/test/iterator.py
new file mode 100644
index 000000000..96f5fd04b
--- /dev/null
+++ b/libs/python/test/iterator.py
@@ -0,0 +1,77 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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: #doctest: +NORMALIZE_WHITESPACE
+... 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/libs/python/test/keywords.cpp b/libs/python/test/keywords.cpp
new file mode 100644
index 000000000..39bac0627
--- /dev/null
+++ b/libs/python/test/keywords.cpp
@@ -0,0 +1,118 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python.hpp>
+#include <string>
+
+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;
+ }
+
+ void seta(int a)
+ {
+ a_ = a;
+ }
+
+ 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;
+BOOST_PYTHON_MODULE(keywords)
+{
+#if BOOST_WORKAROUND(__GNUC__, == 2)
+ using boost::python::arg;
+#endif
+
+ class_<Foo>(
+ "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("set2", &Foo::set, (arg("a"), "b", "n") )
+
+ .def("a", &Foo::geta)
+ .def("b", &Foo::getb)
+ .def("n", &Foo::getn)
+ ;
+
+ class_<Bar>("Bar"
+ , init<optional<int, double, const std::string &> >()
+ )
+ .def("set", &Bar::set, bar_set())
+ .def("set2", &Bar::set, bar_set("set2's docstring"))
+ .def("seta", &Bar::seta, arg("a"))
+
+ .def("a", &Bar::geta)
+ .def("b", &Bar::getb)
+ .def("n", &Bar::getn)
+ ;
+
+}
+
+
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/keywords_test.py b/libs/python/test/keywords_test.py
new file mode 100644
index 000000000..261de0b39
--- /dev/null
+++ b/libs/python/test/keywords_test.py
@@ -0,0 +1,106 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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')
+>>> f.set2(b=2.0,n="2",a=2)
+>>> f.a(), f.b(), f.n()
+(2, 2.0, '2')
+
+# 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')
+>>> f.set2.__doc__.splitlines()[1]
+'set2( (Bar)arg1 [, (int)arg2 [, (float)arg3 [, (str)arg4]]]) -> None :'
+>>> f.set2.__doc__.splitlines()[2]
+" set2's docstring"
+'''
+
+
+
+
+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/libs/python/test/list.cpp b/libs/python/test/list.cpp
new file mode 100644
index 000000000..3e9fcbe66
--- /dev/null
+++ b/libs/python/test/list.cpp
@@ -0,0 +1,154 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/list.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/dict.hpp>
+#include <boost/python/make_function.hpp>
+#include <boost/lexical_cast.hpp>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+#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<std::string>(x.value()) + ")";
+}
+
+object apply_object_list(object f, list x)
+{
+ return f(x);
+}
+
+list apply_list_list(object f, list x)
+{
+ return call<list>(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.pop(2); // remove [1,2] so the list is sortable in py3k
+ x.sort();
+ print(x);
+
+ print("reverse sorted:");
+#if PY_VERSION_HEX >= 0x03000000
+ x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));
+#else
+ x.sort(&notcmp);
+#endif
+ print(x);
+
+ list w;
+ w.append(5);
+ w.append(6);
+ w += "hi";
+ BOOST_ASSERT(w[0] == 5);
+ BOOST_ASSERT(w[1] == 6);
+ BOOST_ASSERT(w[2] == 'h');
+ BOOST_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>("X", init<int>())
+ .def( "__repr__", x_rep)
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/list.py b/libs/python/test/list.py
new file mode 100644
index 000000000..8be211238
--- /dev/null
+++ b/libs/python/test/list.py
@@ -0,0 +1,118 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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) #doctest: +NORMALIZE_WHITESPACE
+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:
+['.', 'e', 'h', 'l', 'l', 'o', 'x', 'y']
+reverse sorted:
+['y', 'x', 'o', 'l', 'l', 'h', 'e', '.']
+'''
+
+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/libs/python/test/long.cpp b/libs/python/test/long.cpp
new file mode 100644
index 000000000..61e4518ff
--- /dev/null
+++ b/libs/python/test/long.cpp
@@ -0,0 +1,63 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/long.hpp>
+#include <boost/python/class.hpp>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+
+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;
+ BOOST_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" <milind_patil-at-hotmail.com>
+
+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_ >())
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/long.py b/libs/python/test/long.py
new file mode 100644
index 000000000..13d8775bb
--- /dev/null
+++ b/libs/python/test/long.py
@@ -0,0 +1,33 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from long_ext import *
+>>> print new_long()
+0
+>>> print longify(42)
+42
+>>> print longify_string('300')
+300
+>>> is_long(20L)
+'yes'
+>>> is_long('20')
+0
+
+>>> x = Y(4294967295L)
+'''
+
+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/libs/python/test/m1.cpp b/libs/python/test/m1.cpp
new file mode 100644
index 000000000..a873bc35d
--- /dev/null
+++ b/libs/python/test/m1.cpp
@@ -0,0 +1,344 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <boost/python/def.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/lvalue_from_pytype.hpp>
+#include <boost/python/copy_const_reference.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/to_python_converter.hpp>
+#include <boost/python/errors.hpp>
+#include <boost/python/manage_new_object.hpp>
+#include <boost/python/converter/pytype_function.hpp>
+#include <string.h>
+#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 = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ const_cast<char*>("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 */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* 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, /* 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 */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+};
+
+// 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 = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ const_cast<char*>("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 */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* 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, /* 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 */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#if PYTHON_API_VERSION >= 1012
+ 0 /* tp_del */
+#endif
+};
+
+// Create a Simple containing "hello, world"
+PyObject* new_simple()
+{
+ SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType);
+ simple->x.s = const_cast<char*>("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<simple, simple_to_python, true>
+ //, boost::python::converter::wrap_pytype<&SimpleType>
+{
+ static PyObject* convert(simple const& x)
+ {
+ SimpleObject* p = PyObject_New(SimpleObject, &SimpleType);
+ p->x = x;
+ return (PyObject*)p;
+ }
+ static PyTypeObject const *get_pytype(){return &SimpleType; }
+};
+
+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> d) { return *d; }
+
+boost::shared_ptr<A> d_factory() { return boost::shared_ptr<B>(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<int_from_noddy,&NoddyType>();
+
+ lvalue_from_pytype<
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters
+ extract_member<SimpleObject, simple, &SimpleObject::x>
+#else
+ extract_simple_object
+#endif
+ , &SimpleType
+ >();
+
+ lvalue_from_pytype<extract_identity<SimpleObject>,&SimpleType>();
+
+ def("new_noddy", new_noddy);
+ def("new_simple", new_simple);
+
+ def("make_unregistered", make_unregistered);
+ def("make_unregistered2", make_unregistered2, return_value_policy<manage_new_object>());
+
+ // 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<copy_const_reference>()
+ );
+
+ 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, shared_ptr<A> >("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,bases<A> >("B")
+ .def("name", &B::name)
+ ;
+
+ class_<C,bases<A> >("C")
+ .def("name", &C::name)
+ ;
+
+ class_<D, bases<B,C> >("D")
+ .def("name", &D::name)
+ ;
+
+ class_<complicated>("complicated",
+ init<simple const&,int>())
+ .def(init<simple const&>())
+ .def("get_n", &complicated::get_n)
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/m2.cpp b/libs/python/test/m2.cpp
new file mode 100644
index 000000000..5bcdea604
--- /dev/null
+++ b/libs/python/test/m2.cpp
@@ -0,0 +1,108 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// 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 <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/copy_non_const_reference.hpp>
+#include <boost/python/copy_const_reference.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include "simple_type.hpp"
+
+#if PY_VERSION_HEX >= 0x03000000
+# define PyString_FromString PyUnicode_FromString
+# define PyInt_FromLong PyLong_FromLong
+#endif
+
+// 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);
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+# undef PyString_FromString
+# undef PyInt_FromLong
+#endif
+
+// rewrap<T> extracts a T from the argument, then converts the T back
+// to a PyObject* and returns it.
+template <class T>
+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<int>::f);
+
+ def("wrap_int_ref", &rewrap<int&>::f
+ , return_value_policy<copy_non_const_reference>()
+ );
+
+ def("wrap_int_const_ref", &rewrap<int const&>::f
+ , return_value_policy<copy_const_reference>()
+ );
+
+ def("wrap_simple", &rewrap<simple>::f);
+
+ def("wrap_simple_ref", &rewrap<simple&>::f
+ , return_value_policy<copy_non_const_reference>()
+ );
+
+ def("wrap_simple_const_ref", &rewrap<simple const&>::f
+ , return_value_policy<copy_const_reference>()
+ );
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/map_indexing_suite.cpp b/libs/python/test/map_indexing_suite.cpp
new file mode 100644
index 000000000..b8771cf41
--- /dev/null
+++ b/libs/python/test/map_indexing_suite.cpp
@@ -0,0 +1,68 @@
+// Copyright Joel de Guzman 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/suite/indexing/map_indexing_suite.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/implicit.hpp>
+
+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>("X")
+ .def(init<>())
+ .def(init<X>())
+ .def(init<std::string>())
+ .def("__repr__", &X::repr)
+ .def("reset", &X::reset)
+ .def("foo", &X::foo)
+ ;
+
+ def("x_value", x_value);
+ implicitly_convertible<std::string, X>();
+
+ class_<std::map<std::string, X> >("XMap")
+ .def(map_indexing_suite<std::map<std::string, X> >())
+ ;
+
+ void int_map_indexing_suite(); // moved to int_map_indexing_suite.cpp to
+ int_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
+
+#if 0
+ // Compile check only...
+ class_<std::map<int, int> >("IntMap")
+ .def(map_indexing_suite<std::map<int, int> >())
+ ;
+#endif
+
+ // Some more..
+ class_<std::map<std::string, boost::shared_ptr<X> > >("TestMap")
+ .def(map_indexing_suite<std::map<std::string, boost::shared_ptr<X> >, true>())
+ ;
+
+ void a_map_indexing_suite(); // moved to a_map_indexing_suite.cpp to
+ a_map_indexing_suite(); // avoid MSVC 6/7 internal structure overflow
+
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/map_indexing_suite.py b/libs/python/test/map_indexing_suite.py
new file mode 100644
index 000000000..9d9e2b26f
--- /dev/null
+++ b/libs/python/test/map_indexing_suite.py
@@ -0,0 +1,242 @@
+# Copyright Joel de Guzman 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+
+#####################################################################
+# Check an object that we will use as container element
+#####################################################################
+
+>>> from map_indexing_suite_ext import *
+>>> assert "map_indexing_suite_IntMap_entry" in dir()
+>>> assert "map_indexing_suite_TestMap_entry" in dir()
+>>> assert "map_indexing_suite_XMap_entry" in dir()
+>>> assert "map_indexing_suite_AMap_entry" in dir()
+>>> 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) ]
+
+#####################################################################
+# Some more...
+#####################################################################
+
+>>> tm = TestMap()
+>>> tm["joel"] = X("aaa")
+>>> tm["kimpo"] = X("bbb")
+>>> print_xmap(tm)
+[ (joel, aaa) (kimpo, bbb) ]
+>>> for el in tm: #doctest: +NORMALIZE_WHITESPACE
+... print el.key(),
+... dom = el.data()
+joel kimpo
+
+#####################################################################
+# Test custom converter...
+#####################################################################
+
+>>> am = AMap()
+>>> am[3] = 4
+>>> am[3]
+4
+>>> for i in am:
+... i.data()
+4
+
+#####################################################################
+# 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/libs/python/test/minimal.cpp b/libs/python/test/minimal.cpp
new file mode 100644
index 000000000..5efee26bc
--- /dev/null
+++ b/libs/python/test/minimal.cpp
@@ -0,0 +1,16 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+
+#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
+# include <iostream> // works around a KCC intermediate code generation bug
+#endif
+
+BOOST_PYTHON_MODULE(minimal_ext)
+{
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/minimal.py b/libs/python/test/minimal.py
new file mode 100644
index 000000000..28e7918f7
--- /dev/null
+++ b/libs/python/test/minimal.py
@@ -0,0 +1,7 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+print "IMPORTING minimal_ext"
+import minimal_ext
+print "DONE IMPORTING minimal_ext"
+
diff --git a/libs/python/test/module_tail.cpp b/libs/python/test/module_tail.cpp
new file mode 100644
index 000000000..f9cdca189
--- /dev/null
+++ b/libs/python/test/module_tail.cpp
@@ -0,0 +1,58 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if defined(_WIN32)
+# ifdef __MWERKS__
+# pragma ANSI_strict off
+# endif
+# include <windows.h>
+# ifdef __MWERKS__
+# pragma ANSI_strict reset
+# endif
+
+# ifdef _MSC_VER
+# include <eh.h> // for _set_se_translator()
+# pragma warning(push)
+# pragma warning(disable:4297)
+# pragma warning(disable:4535)
+extern "C" void straight_to_debugger(unsigned int, EXCEPTION_POINTERS*)
+{
+ throw;
+}
+extern "C" void (*old_translator)(unsigned, EXCEPTION_POINTERS*)
+ = _set_se_translator(straight_to_debugger);
+# pragma warning(pop)
+# endif
+
+#endif // _WIN32
+
+#include <exception>
+#include <boost/python/extract.hpp>
+#include <boost/python/str.hpp>
+struct test_failure : std::exception
+{
+ test_failure(char const* expr, char const* /*function*/, char const* file, unsigned line)
+ : msg(file + boost::python::str(":%s:") % line + ": Boost.Python assertion failure: " + expr)
+ {}
+
+ ~test_failure() throw() {}
+
+ char const* what() const throw()
+ {
+ return boost::python::extract<char const*>(msg)();
+ }
+
+ boost::python::str msg;
+};
+
+namespace boost
+{
+
+void assertion_failed(char const * expr, char const * function, char const * file, long line)
+{
+ throw ::test_failure(expr,function, file, line);
+}
+
+} // namespace boost
diff --git a/libs/python/test/multi_arg_constructor.cpp b/libs/python/test/multi_arg_constructor.cpp
new file mode 100644
index 000000000..7d49bb556
--- /dev/null
+++ b/libs/python/test/multi_arg_constructor.cpp
@@ -0,0 +1,27 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+
+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>(
+ "A"
+ , init<double, double, double, double, double, double, double, double, double>()
+ )
+ ;
+
+}
+
diff --git a/libs/python/test/multi_arg_constructor.py b/libs/python/test/multi_arg_constructor.py
new file mode 100644
index 000000000..eb8d338b3
--- /dev/null
+++ b/libs/python/test/multi_arg_constructor.py
@@ -0,0 +1,21 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/nested.cpp b/libs/python/test/nested.cpp
new file mode 100644
index 000000000..de656d2b8
--- /dev/null
+++ b/libs/python/test/nested.cpp
@@ -0,0 +1,51 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/operators.hpp>
+#include <boost/python/scope.hpp>
+#include "test_class.hpp"
+#if __GNUC__ != 2
+# include <ostream>
+#else
+# include <ostream.h>
+#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>("X", init<int>())
+ .def(str(self))
+ ;
+
+
+ // Y will now be defined in the current scope
+ class_<Y>("Y", init<int>())
+ .def(str(self))
+ ;
+}
+
+
+#include "module_tail.cpp"
+
+
+
diff --git a/libs/python/test/nested.py b/libs/python/test/nested.py
new file mode 100644
index 000000000..c3446e848
--- /dev/null
+++ b/libs/python/test/nested.py
@@ -0,0 +1,40 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+ >>> from nested_ext import *
+
+ >>> X
+ <class 'nested_ext.X'>
+
+ >>> X.__module__
+ 'nested_ext'
+
+ >>> X.__name__
+ 'X'
+
+ >>> X.Y
+ <class 'nested_ext.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/libs/python/test/newtest.py b/libs/python/test/newtest.py
new file mode 100644
index 000000000..1862dcb49
--- /dev/null
+++ b/libs/python/test/newtest.py
@@ -0,0 +1,206 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> 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'
+>>> print g.__doc__.splitlines()[1]
+g( (Simple)arg1) -> Simple :
+
+"""
+
+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/libs/python/test/numarray_tests.py b/libs/python/test/numarray_tests.py
new file mode 100644
index 000000000..be3d9d4e4
--- /dev/null
+++ b/libs/python/test/numarray_tests.py
@@ -0,0 +1,63 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+import printer
+
+# So we can coerce portably across Python versions
+bool = type(1 == 1)
+
+'''
+>>> from numpy_ext import *
+>>> x = new_array()
+>>> y = x.copy()
+>>> p = _printer()
+>>> check = p.check
+>>> exercise_numarray(x, p)
+
+>>> check(str(y))
+
+>>> 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, 0));
+>>> check(y.diagonal(0, 1, 0));
+
+>>> check(y.is_c_array());
+
+# coerce because numarray still returns an int and the C++ interface forces
+# the return type to bool
+>>> check( bool(y.isbyteswapped()) );
+
+>>> check(y.trace());
+>>> check(y.trace(1));
+>>> check(y.trace(0, 0));
+>>> check(y.trace(0, 1, 0));
+
+>>> check(y.new('D').getshape());
+>>> check(y.new('D').type());
+>>> y.sort();
+>>> check(y);
+>>> check(y.type());
+
+>>> check(y.factory((1.2, 3.4)));
+>>> check(y.factory((1.2, 3.4), "f8"))
+>>> check(y.factory((1.2, 3.4), "f8", true))
+>>> check(y.factory((1.2, 3.4), "f8", true, false))
+>>> check(y.factory((1.2, 3.4), "f8", true, false, None))
+>>> check(y.factory((1.2, 3.4), "f8", true, false, None, (1,2,1)))
+
+>>> p.results
+[]
+>>> del p
+'''
diff --git a/libs/python/test/numeric_tests.py b/libs/python/test/numeric_tests.py
new file mode 100644
index 000000000..569ec19e5
--- /dev/null
+++ b/libs/python/test/numeric_tests.py
@@ -0,0 +1,39 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+import printer
+'''
+>>> 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
+'''
diff --git a/libs/python/test/numpy.cpp b/libs/python/test/numpy.cpp
new file mode 100644
index 000000000..9472f92ed
--- /dev/null
+++ b/libs/python/test/numpy.cpp
@@ -0,0 +1,136 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/numeric.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/str.hpp>
+
+using namespace boost::python;
+namespace py = boost::python;
+
+// See if we can invoke array() from C++
+numeric::array new_array()
+{
+ return numeric::array(
+ py::make_tuple(
+ py::make_tuple(1,2,3)
+ , py::make_tuple(4,5,6)
+ , py::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();
+}
+
+namespace
+{
+ object handle_error()
+ {
+ PyObject* type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ handle<> ty(type), v(value), tr(traceback);
+ return object("exception");
+ str format("exception type: %sn");
+ format += "exception value: %sn";
+ format += "traceback:n%s" ;
+ object ret = format % py::make_tuple(ty, v, tr);
+ return ret;
+ }
+}
+#define CHECK(expr) \
+{ \
+ object result; \
+ try { result = object(expr); } \
+ catch(error_already_set) \
+ { \
+ result = handle_error(); \
+ } \
+ check(result); \
+}
+
+// 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[py::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(str(y));
+
+ 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, 0));
+ 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, 0));
+ CHECK(y.trace(0, 1, 0));
+
+ CHECK(y.new_("D").getshape());
+ CHECK(y.new_("D").type());
+ y.sort();
+ CHECK(y);
+ CHECK(y.type());
+
+ CHECK(y.factory(py::make_tuple(1.2, 3.4)));
+ CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8"));
+ CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8", true));
+ CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8", true, false));
+ CHECK(y.factory(py::make_tuple(1.2, 3.4), "f8", true, false, object()));
+ CHECK (y.factory(py::make_tuple(1.2, 3.4), "f8", true, false, object(), py::make_tuple(1,2,1)));
+
+}
+
+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("get_module_name", &numeric::array::get_module_name);
+ def("info", info);
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/numpy.py b/libs/python/test/numpy.py
new file mode 100644
index 000000000..84e8313d1
--- /dev/null
+++ b/libs/python/test/numpy.py
@@ -0,0 +1,87 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+false = 0;
+true = 1;
+
+import doctest, numeric_tests
+def _count_failures(test_modules = (numeric_tests,)):
+ failures = 0
+ for m in test_modules:
+ failures += doctest.testmod(m)[0]
+ return failures
+
+def _run(args = None):
+ import sys, numarray_tests, numeric_tests
+
+ if args is not None:
+ sys.argv = args
+
+ # See which of the numeric modules are installed
+ has_numeric = 0
+ try: import Numeric
+ except ImportError: pass
+ else:
+ has_numeric = 1
+ m = Numeric
+
+ has_numarray = 0
+ try: import numarray
+ except ImportError: pass
+ else:
+ has_numarray = 1
+ m = numarray
+
+ # 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:', \
+ numpy_ext.get_module_name() or '[numeric support not installed]'
+
+ failures += _count_failures()
+
+ # test against Numeric if installed
+ if has_numeric:
+ print 'testing Numeric module explicitly'
+ numpy_ext.set_module_and_type('Numeric', 'ArrayType')
+
+ failures += _count_failures()
+
+ if has_numarray:
+ print 'testing numarray module explicitly'
+ numpy_ext.set_module_and_type('numarray', 'NDArray')
+ # Add the _numarray_tests to the list of things to test in
+ # this case.
+ failures += _count_failures((numarray_tests, numeric_tests))
+
+ # see that we can go back to the default
+ numpy_ext.set_module_and_type('', '')
+ print 'testing default module again:', \
+ numpy_ext.get_module_name() or '[numeric support not installed]'
+
+ failures += _count_failures()
+
+ return failures
+
+if __name__ == '__main__':
+ print "running..."
+ import sys
+ status = _run()
+ if (status == 0): print "Done."
+ sys.exit(status)
diff --git a/libs/python/test/object.cpp b/libs/python/test/object.cpp
new file mode 100644
index 000000000..b1f015187
--- /dev/null
+++ b/libs/python/test/object.cpp
@@ -0,0 +1,392 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/class.hpp>
+
+using namespace boost::python;
+
+class NotCopyable
+{
+} not_copyable;
+
+object ref_to_noncopyable()
+{
+ return object(boost::ref(not_copyable));
+}
+
+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_objgetattr(object x, object const& name)
+{
+ return x.attr(name);
+}
+
+object obj_const_getattr(object const& x, char const* name)
+{
+ return x.attr(name);
+}
+
+object obj_const_objgetattr(object const& x, object const& name)
+{
+ return x.attr(name);
+}
+
+void obj_setattr(object x, char const* name, object value)
+{
+ x.attr(name) = value;
+}
+
+void obj_objsetattr(object x, object const& name, object value)
+{
+ x.attr(name) = value;
+}
+
+void obj_setattr42(object x, char const* name)
+{
+ x.attr(name) = 42;
+}
+
+void obj_objsetattr42(object x, object const& name)
+{
+ x.attr(name) = 42;
+}
+
+void obj_moveattr(object& x, char const* src, char const* dst)
+{
+ x.attr(dst) = x.attr(src);
+}
+
+void obj_objmoveattr(object& x, object const& src, object const& dst)
+{
+ x.attr(dst) = x.attr(src);
+}
+
+void obj_delattr(object x, char const* name)
+{
+ x.attr(name).del();
+}
+
+void obj_objdelattr(object x, object const& name)
+{
+ x.attr(name).del();
+}
+
+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_objattr(object y, object& name)
+{
+ return y.attr(name);
+}
+
+bool test_not_attr(object y, char* name)
+{
+ return !y.attr(name);
+}
+
+bool test_not_objattr(object y, object& 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(_,_) != s)
+ return false;
+
+ if (", " != s.slice(5,7))
+ return false;
+
+ return s.slice(2,-1).slice(1,-1) == "lo, wor";
+}
+
+object test_call(object c, object args, object kwds)
+{
+ return c(*args, **kwds);
+}
+
+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)
+{
+ class_<NotCopyable, boost::noncopyable>("NotCopyable", no_init);
+
+ def("ref_to_noncopyable", ref_to_noncopyable);
+ def("call_object_3", call_object_3);
+ def("message", message);
+ def("number", number);
+
+ def("obj_getattr", obj_getattr);
+ def("obj_objgetattr", obj_objgetattr);
+ def("obj_const_getattr", obj_const_getattr);
+ def("obj_const_objgetattr", obj_const_objgetattr);
+ def("obj_setattr", obj_setattr);
+ def("obj_objsetattr", obj_objsetattr);
+ def("obj_setattr42", obj_setattr42);
+ def("obj_objsetattr42", obj_objsetattr42);
+ def("obj_moveattr", obj_moveattr);
+ def("obj_objmoveattr", obj_objmoveattr);
+ def("obj_delattr", obj_delattr);
+ def("obj_objdelattr", obj_objdelattr);
+
+ 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_objattr", test_objattr);
+ def("test_not_attr", test_not_attr);
+ def("test_not_objattr", test_not_objattr);
+
+ def("test_item", test_item);
+ def("test_not_item", test_not_item);
+
+ def("test_call", test_call);
+ 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/libs/python/test/object.py b/libs/python/test/object.py
new file mode 100644
index 000000000..84972e64f
--- /dev/null
+++ b/libs/python/test/object.py
@@ -0,0 +1,179 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from object_ext import *
+
+>>> type(ref_to_noncopyable())
+<class 'object_ext.NotCopyable'>
+
+>>> 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'
+>>> try: obj_objgetattr(x, 'objfoo')
+... except AttributeError: pass
+... else: print 'expected an exception'
+
+>>> obj_setattr(x, 'foo', 1)
+>>> x.foo
+1
+>>> obj_objsetattr(x, 'objfoo', 1)
+>>> try:obj_objsetattr(x, 1)
+... except TypeError: pass
+... else: print 'expected an exception'
+>>> x.objfoo
+1
+>>> obj_getattr(x, 'foo')
+1
+>>> obj_objgetattr(x, 'objfoo')
+1
+>>> try:obj_objgetattr(x, 1)
+... except TypeError: pass
+... else: print 'expected an exception'
+>>> obj_const_getattr(x, 'foo')
+1
+>>> obj_const_objgetattr(x, 'objfoo')
+1
+>>> obj_setattr42(x, 'foo')
+>>> x.foo
+42
+>>> obj_objsetattr42(x, 'objfoo')
+>>> x.objfoo
+42
+>>> obj_moveattr(x, 'foo', 'bar')
+>>> x.bar
+42
+>>> obj_objmoveattr(x, 'objfoo', 'objbar')
+>>> x.objbar
+42
+>>> test_attr(x, 'foo')
+1
+>>> test_objattr(x, 'objfoo')
+1
+>>> test_not_attr(x, 'foo')
+0
+>>> test_not_objattr(x, 'objfoo')
+0
+>>> x.foo = None
+>>> test_attr(x, 'foo')
+0
+>>> x.objfoo = None
+>>> test_objattr(x, 'objfoo')
+0
+>>> test_not_attr(x, 'foo')
+1
+>>> test_not_objattr(x, 'objfoo')
+1
+>>> obj_delattr(x, 'foo')
+>>> obj_objdelattr(x, 'objfoo')
+>>> try:obj_delattr(x, 'foo')
+... except AttributeError: pass
+... else: print 'expected an exception'
+>>> try:obj_objdelattr(x, 'objfoo')
+... except AttributeError: pass
+... else: print 'expected an exception'
+
+ 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
+
+>>> def print_args(*args, **kwds):
+... print args, kwds
+>>> test_call(print_args, (0, 1, 2, 3), {'a':'A'})
+(0, 1, 2, 3) {'a': 'A'}
+
+
+>>> 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/libs/python/test/object_fail1.cpp b/libs/python/test/object_fail1.cpp
new file mode 100644
index 000000000..6bb2eda5c
--- /dev/null
+++ b/libs/python/test/object_fail1.cpp
@@ -0,0 +1,11 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/object.hpp>
+
+int f(boost::python::object const& x)
+{
+ x._("hello") = 1;
+ return 0;
+}
diff --git a/libs/python/test/object_manager.cpp b/libs/python/test/object_manager.cpp
new file mode 100644
index 000000000..e3608c1f1
--- /dev/null
+++ b/libs/python/test/object_manager.cpp
@@ -0,0 +1,33 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/converter/object_manager.hpp>
+#include <boost/python/borrowed.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/python/handle.hpp>
+
+using namespace boost::python;
+using namespace boost::python::converter;
+
+struct X {};
+
+int main()
+{
+ BOOST_STATIC_ASSERT(is_object_manager<handle<> >::value);
+ BOOST_STATIC_ASSERT(!is_object_manager<int>::value);
+ BOOST_STATIC_ASSERT(!is_object_manager<X>::value);
+
+ BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<>&>::value);
+ BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<> const&>::value);
+ BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<> volatile&>::value);
+ BOOST_STATIC_ASSERT(is_reference_to_object_manager<handle<> const volatile&>::value);
+
+ BOOST_STATIC_ASSERT(!is_reference_to_object_manager<handle<> >::value);
+ BOOST_STATIC_ASSERT(!is_reference_to_object_manager<X>::value);
+ BOOST_STATIC_ASSERT(!is_reference_to_object_manager<X&>::value);
+ BOOST_STATIC_ASSERT(!is_reference_to_object_manager<X const&>::value);
+
+ return 0;
+}
+
diff --git a/libs/python/test/opaque.cpp b/libs/python/test/opaque.cpp
new file mode 100644
index 000000000..f15e9458f
--- /dev/null
+++ b/libs/python/test/opaque.cpp
@@ -0,0 +1,76 @@
+// Copyright David Abrahams and Gottfried Ganssauge 2003.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+# include <boost/python/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;
+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::return_opaque_pointer>());
+ bpl::def ("use", &::use);
+ bpl::def ("useany", &::useany);
+ bpl::def ("getnull", &::getnull, bpl::return_value_policy<bpl::return_opaque_pointer>());
+ bpl::def ("failuse", &::failuse);
+
+ bpl::def (
+ "get2",
+ &::get2,
+ bpl::return_value_policy<bpl::return_opaque_pointer>());
+ bpl::def ("use2", &::use2);
+ bpl::def ("failuse2", &::failuse2);
+}
+
+# include "module_tail.cpp"
diff --git a/libs/python/test/opaque.py b/libs/python/test/opaque.py
new file mode 100644
index 000000000..2ee0aa0c0
--- /dev/null
+++ b/libs/python/test/opaque.py
@@ -0,0 +1,87 @@
+# -*- coding: latin-1 -*-
+# Copyright Gottfried Ganßauge 2003..2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+"""
+>>> 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'
+
+ This used to result in a segmentation violation
+
+>>> type(get()) != type (get2())
+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/libs/python/test/operators.cpp b/libs/python/test/operators.cpp
new file mode 100644
index 000000000..c58f2b005
--- /dev/null
+++ b/libs/python/test/operators.cpp
@@ -0,0 +1,175 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/operators.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include "test_class.hpp"
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/operators.hpp>
+#include <boost/operators.hpp>
+//#include <boost/python/str.hpp>
+// Just use math.h here; trying to use std::pow() causes too much
+// trouble for non-conforming compilers and libraries.
+#include <math.h>
+
+#if __GNUC__ != 2
+# include <ostream>
+#else
+# include <ostream.h>
+#endif
+
+using namespace boost::python;
+
+
+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()); }
+
+// typedef int (X::*safe_bool)() const;
+// operator safe_bool() const { return value() != 0 ? &X::value : 0; }
+};
+
+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();
+}
+
+struct number
+ : boost::integer_arithmetic<number>
+{
+ explicit number(long x_) : x(x_) {}
+ operator long() const { return x; }
+
+ template <class T>
+ number& operator+=(T const& rhs)
+ { x += rhs; return *this; }
+
+ template <class T>
+ number& operator-=(T const& rhs)
+ { x -= rhs; return *this; }
+
+ template <class T>
+ number& operator*=(T const& rhs)
+ { x *= rhs; return *this; }
+
+ template <class T>
+ number& operator/=(T const& rhs)
+ { x /= rhs; return *this; }
+
+ template <class T>
+ number& operator%=(T const& rhs)
+ { x %= rhs; return *this; }
+
+ long x;
+};
+
+BOOST_PYTHON_MODULE(operators_ext)
+{
+ class_<X>("X", init<int>())
+ .def("value", &X::value)
+ .def(self + self)
+ .def(self - self)
+ .def(self - int())
+ .def(other<int>() - self)
+ .def(-self)
+ .def(self < other<int>())
+ .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))
+ .def(
+ !self
+ // "not self" is legal here but causes friction on a few
+ // nonconforming compilers; it's cute because it looks
+ // like python, but doing it here doesn't prove much and
+ // just causes tests to fail or complicated workarounds to
+ // be enacted.
+ )
+ ;
+
+ class_<number>("number", init<long>())
+ // 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)
+ ;
+
+ class_<test_class<1> >("Z", init<int>())
+ .def(int_(self))
+ .def(float_(self))
+ .def(complex_(self))
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/operators.py b/libs/python/test/operators.py
new file mode 100644
index 000000000..f39134b66
--- /dev/null
+++ b/libs/python/test/operators.py
@@ -0,0 +1,102 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from operators_ext import *
+
+ Check __nonzero__ support
+
+>>> assert X(2)
+>>> assert not X(0)
+
+ ----
+
+>>> 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/libs/python/test/operators_wrapper.cpp b/libs/python/test/operators_wrapper.cpp
new file mode 100644
index 000000000..12f30048d
--- /dev/null
+++ b/libs/python/test/operators_wrapper.cpp
@@ -0,0 +1,42 @@
+#include "boost/python.hpp"
+#include <memory>
+
+struct vector
+{
+ virtual ~vector() {}
+
+ vector operator+( const vector& ) const
+ { return vector(); }
+
+ vector& operator+=( const vector& )
+ { return *this; }
+
+ vector operator-() const
+ { return *this; }
+};
+
+struct dvector : vector
+{};
+
+using namespace boost::python;
+
+struct vector_wrapper
+ : vector, wrapper< vector >
+{
+ vector_wrapper(vector const&) {}
+ vector_wrapper() {}
+};
+
+BOOST_PYTHON_MODULE( operators_wrapper_ext )
+{
+ class_< vector_wrapper >( "vector" )
+ .def( self + self )
+ .def( self += self )
+ .def( -self )
+ ;
+
+ scope().attr("v") = vector();
+ std::auto_ptr<vector> dp(new dvector);
+ register_ptr_to_python< std::auto_ptr<vector> >();
+ scope().attr("d") = dp;
+}
diff --git a/libs/python/test/operators_wrapper.py b/libs/python/test/operators_wrapper.py
new file mode 100644
index 000000000..6c889b0a3
--- /dev/null
+++ b/libs/python/test/operators_wrapper.py
@@ -0,0 +1,11 @@
+from operators_wrapper_ext import *
+
+class D2(vector): pass
+d2 = D2()
+
+for lhs in (v,d,d2):
+ -lhs
+ for rhs in (v,d,d2):
+ lhs + rhs
+ lhs += rhs
+
diff --git a/libs/python/test/pickle1.cpp b/libs/python/test/pickle1.cpp
new file mode 100644
index 000000000..cc4ad6795
--- /dev/null
+++ b/libs/python/test/pickle1.cpp
@@ -0,0 +1,62 @@
+// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ 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 <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/tuple.hpp>
+
+#include <string>
+
+namespace boost_python_test {
+
+ // 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)
+ {
+ return boost::python::make_tuple(w.get_country());
+ }
+ };
+
+ // To support test of "pickling not enabled" error message.
+ struct noop {};
+}
+
+BOOST_PYTHON_MODULE(pickle1_ext)
+{
+ using namespace boost::python;
+ using namespace boost_python_test;
+ class_<world>("world", init<const std::string&>())
+ .def("greet", &world::greet)
+ .def_pickle(world_pickle_suite())
+ ;
+
+ // To support test of "pickling not enabled" error message.
+ class_<noop>("noop");
+}
diff --git a/libs/python/test/pickle1.py b/libs/python/test/pickle1.py
new file mode 100644
index 000000000..8369768d6
--- /dev/null
+++ b/libs/python/test/pickle1.py
@@ -0,0 +1,41 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+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__()
+ (<class 'pickle1_ext.world'>, ('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!
+
+ >>> noop = pickle1_ext.noop()
+ >>> try: pickle.dumps(noop)
+ ... except RuntimeError, e: print str(e)[:55]
+ Pickling of "pickle1_ext.noop" instances is not enabled
+'''
+
+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/libs/python/test/pickle2.cpp b/libs/python/test/pickle2.cpp
new file mode 100644
index 000000000..c9610946e
--- /dev/null
+++ b/libs/python/test/pickle2.cpp
@@ -0,0 +1,97 @@
+// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ 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 <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/extract.hpp>
+
+namespace boost_python_test {
+
+ // 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)
+ {
+ return boost::python::make_tuple(w.get_country());
+ }
+
+ static
+ boost::python::tuple
+ getstate(const world& w)
+ {
+ return boost::python::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<long>(state[0]);
+ if (number != 42)
+ w.set_secret_number(number);
+ }
+ };
+
+}
+
+BOOST_PYTHON_MODULE(pickle2_ext)
+{
+ using namespace boost_python_test;
+ boost::python::class_<world>(
+ "world", boost::python::init<const std::string&>())
+ .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/libs/python/test/pickle2.py b/libs/python/test/pickle2.py
new file mode 100644
index 000000000..2ad663fff
--- /dev/null
+++ b/libs/python/test/pickle2.py
@@ -0,0 +1,50 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+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__()
+ (<class 'pickle2_ext.world'>, ('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
+ ...
+ 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/libs/python/test/pickle3.cpp b/libs/python/test/pickle3.cpp
new file mode 100644
index 000000000..7afe2dbfa
--- /dev/null
+++ b/libs/python/test/pickle3.cpp
@@ -0,0 +1,107 @@
+// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ 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 <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/dict.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/back_reference.hpp>
+
+namespace boost_python_test {
+
+ // 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)
+ {
+ return boost::python::make_tuple(w.get_country());
+ }
+
+ static
+ boost::python::tuple
+ getstate(boost::python::object w_obj)
+ {
+ world const& w = boost::python::extract<world const&>(w_obj)();
+
+ return boost::python::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<world&>(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<dict>(w_obj.attr("__dict__"))();
+ d.update(state[0]);
+
+ // restore the internal state of the C++ object
+ long number = extract<long>(state[1]);
+ if (number != 42)
+ w.set_secret_number(number);
+ }
+
+ static bool getstate_manages_dict() { return true; }
+ };
+
+}
+
+BOOST_PYTHON_MODULE(pickle3_ext)
+{
+ using namespace boost_python_test;
+ boost::python::class_<world>(
+ "world", boost::python::init<const std::string&>())
+ .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/libs/python/test/pickle3.py b/libs/python/test/pickle3.py
new file mode 100644
index 000000000..6be3128c5
--- /dev/null
+++ b/libs/python/test/pickle3.py
@@ -0,0 +1,45 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+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__()
+ (<class 'pickle3_ext.world'>, ('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/libs/python/test/pickle4.cpp b/libs/python/test/pickle4.cpp
new file mode 100644
index 000000000..1374cc7dc
--- /dev/null
+++ b/libs/python/test/pickle4.cpp
@@ -0,0 +1,44 @@
+// Copyright Ralf W. Grosse-Kunstleve 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ This example shows how to enable pickling without using the
+ pickle_suite. The pickling interface (__getinitargs__) is
+ implemented in Python.
+
+ For more information refer to boost/libs/python/doc/pickle.html.
+ */
+
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+
+#include <string>
+
+namespace boost_python_test {
+
+ // 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; }
+ };
+
+}
+
+BOOST_PYTHON_MODULE(pickle4_ext)
+{
+ using namespace boost::python;
+ using namespace boost_python_test;
+ class_<world>("world", init<const std::string&>())
+ .enable_pickling()
+ .def("greet", &world::greet)
+ .def("get_country", &world::get_country)
+ ;
+}
diff --git a/libs/python/test/pickle4.py b/libs/python/test/pickle4.py
new file mode 100644
index 000000000..a5069c90d
--- /dev/null
+++ b/libs/python/test/pickle4.py
@@ -0,0 +1,39 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+r'''>>> import pickle4_ext
+ >>> import pickle
+ >>> def world_getinitargs(self):
+ ... return (self.get_country(),)
+ >>> pickle4_ext.world.__getinitargs__ = world_getinitargs
+ >>> pickle4_ext.world.__module__
+ 'pickle4_ext'
+ >>> pickle4_ext.world.__safe_for_unpickling__
+ 1
+ >>> pickle4_ext.world.__name__
+ 'world'
+ >>> pickle4_ext.world('Hello').__reduce__()
+ (<class 'pickle4_ext.world'>, ('Hello',))
+ >>> wd = pickle4_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/libs/python/test/pointee.cpp b/libs/python/test/pointee.cpp
new file mode 100644
index 000000000..d962e79f5
--- /dev/null
+++ b/libs/python/test/pointee.cpp
@@ -0,0 +1,34 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/pointee.hpp>
+#include <boost/type_traits/same_traits.hpp>
+#include <memory>
+#include <boost/shared_ptr.hpp>
+#include <boost/static_assert.hpp>
+
+struct A;
+
+int main()
+{
+ BOOST_STATIC_ASSERT(
+ (boost::is_same<
+ boost::python::pointee<std::auto_ptr<char**> >::type
+ , char**
+ >::value));
+
+ BOOST_STATIC_ASSERT(
+ (boost::is_same<
+ boost::python::pointee<boost::shared_ptr<A> >::type
+ , A>::value));
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ BOOST_STATIC_ASSERT(
+ (boost::is_same<
+ boost::python::pointee<char*>::type
+ , char
+ >::value));
+#endif
+ return 0;
+}
diff --git a/libs/python/test/pointer_type_id_test.cpp b/libs/python/test/pointer_type_id_test.cpp
new file mode 100644
index 000000000..02e168c7e
--- /dev/null
+++ b/libs/python/test/pointer_type_id_test.cpp
@@ -0,0 +1,43 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/type_id.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/python/converter/pointer_type_id.hpp>
+
+int main()
+{
+ using namespace boost::python::converter;
+
+ boost::python::type_info x
+ = boost::python::type_id<int>();
+
+
+ BOOST_TEST(pointer_type_id<int*>() == x);
+ BOOST_TEST(pointer_type_id<int const*>() == x);
+ BOOST_TEST(pointer_type_id<int volatile*>() == x);
+ BOOST_TEST(pointer_type_id<int const volatile*>() == x);
+
+ BOOST_TEST(pointer_type_id<int*&>() == x);
+ BOOST_TEST(pointer_type_id<int const*&>() == x);
+ BOOST_TEST(pointer_type_id<int volatile*&>() == x);
+ BOOST_TEST(pointer_type_id<int const volatile*&>() == x);
+
+ BOOST_TEST(pointer_type_id<int*const&>() == x);
+ BOOST_TEST(pointer_type_id<int const*const&>() == x);
+ BOOST_TEST(pointer_type_id<int volatile*const&>() == x);
+ BOOST_TEST(pointer_type_id<int const volatile*const&>() == x);
+
+ BOOST_TEST(pointer_type_id<int*volatile&>() == x);
+ BOOST_TEST(pointer_type_id<int const*volatile&>() == x);
+ BOOST_TEST(pointer_type_id<int volatile*volatile&>() == x);
+ BOOST_TEST(pointer_type_id<int const volatile*volatile&>() == x);
+
+ BOOST_TEST(pointer_type_id<int*const volatile&>() == x);
+ BOOST_TEST(pointer_type_id<int const*const volatile&>() == x);
+ BOOST_TEST(pointer_type_id<int volatile*const volatile&>() == x);
+ BOOST_TEST(pointer_type_id<int const volatile*const volatile&>() == x);
+
+ return boost::report_errors();
+}
diff --git a/libs/python/test/pointer_vector.cpp b/libs/python/test/pointer_vector.cpp
new file mode 100644
index 000000000..08cd48619
--- /dev/null
+++ b/libs/python/test/pointer_vector.cpp
@@ -0,0 +1,52 @@
+// Copyright Joel de Guzman 2005-2006. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python.hpp>
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <vector>
+
+using namespace boost::python;
+
+class Abstract
+{
+public:
+ virtual ~Abstract() {}; // silence compiler warningsa
+ virtual std::string f() =0;
+};
+
+class Concrete1 : public Abstract
+{
+public:
+ virtual std::string f() { return "harru"; }
+};
+
+typedef std::vector<Abstract*> ListOfObjects;
+
+class DoesSomething
+{
+public:
+ DoesSomething() {}
+
+ ListOfObjects returnList()
+ {
+ ListOfObjects lst;
+ lst.push_back(new Concrete1()); return lst;
+ }
+};
+
+BOOST_PYTHON_MODULE(pointer_vector_ext)
+{
+class_<Abstract, boost::noncopyable>("Abstract", no_init)
+ .def("f", &Abstract::f)
+ ;
+
+class_<ListOfObjects>("ListOfObjects")
+ .def( vector_indexing_suite<ListOfObjects>() )
+ ;
+
+class_<DoesSomething>("DoesSomething")
+ .def("returnList", &DoesSomething::returnList)
+ ;
+}
+
+
diff --git a/libs/python/test/pointer_vector.py b/libs/python/test/pointer_vector.py
new file mode 100644
index 000000000..16900e8eb
--- /dev/null
+++ b/libs/python/test/pointer_vector.py
@@ -0,0 +1,31 @@
+# Copyright Joel de Guzman 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+
+>>> import pointer_vector_ext
+>>> d = pointer_vector_ext.DoesSomething()
+>>> lst = d.returnList()
+>>> lst[0].f();
+'harru'
+
+'''
+
+
+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/libs/python/test/polymorphism.cpp b/libs/python/test/polymorphism.cpp
new file mode 100644
index 000000000..02713ae26
--- /dev/null
+++ b/libs/python/test/polymorphism.cpp
@@ -0,0 +1,162 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/manage_new_object.hpp>
+#include <boost/python/reference_existing_object.hpp>
+#include <boost/python/call_method.hpp>
+#include <boost/python/pure_virtual.hpp>
+#include <boost/python/def.hpp>
+#include <boost/utility.hpp>
+
+using namespace boost::python;
+
+struct Callback
+{
+ Callback(PyObject* o) : mSelf(o) {}
+ PyObject* mSelf;
+};
+
+struct P
+{
+ virtual ~P(){}
+ virtual std::string f() = 0;
+ std::string g() { return "P::g()"; }
+};
+
+struct PCallback : P, Callback
+{
+ PCallback (PyObject* self) : Callback(self) {}
+
+ std::string f()
+ {
+ return call_method<std::string>(mSelf, "f");
+ }
+};
+
+struct Q : virtual 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<std::string>(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<std::string>(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,boost::noncopyable,ACallback>("A")
+ .def("f", &A::f, &ACallback::default_f)
+ ;
+
+ def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
+
+ class_<C,bases<A>,boost::noncopyable>("C")
+ .def("f", &C::f)
+ ;
+
+ class_<D,bases<A>,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<reference_existing_object>());
+
+ def("factory", factory, return_value_policy<manage_new_object>());
+
+ def("call_f", call_f);
+
+ class_<P,boost::noncopyable,PCallback>("P")
+ .def("f", pure_virtual(&P::f))
+ ;
+
+ class_<Q, bases<P> >("Q")
+ .def("g", &P::g) // make sure virtual inheritance doesn't interfere
+ ;
+}
+
+//#include "module_tail.cpp"
diff --git a/libs/python/test/polymorphism.py b/libs/python/test/polymorphism.py
new file mode 100644
index 000000000..0218b8108
--- /dev/null
+++ b/libs/python/test/polymorphism.py
@@ -0,0 +1,74 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+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/libs/python/test/polymorphism2.cpp b/libs/python/test/polymorphism2.cpp
new file mode 100644
index 000000000..8aefbc3af
--- /dev/null
+++ b/libs/python/test/polymorphism2.cpp
@@ -0,0 +1,172 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/manage_new_object.hpp>
+#include <boost/python/reference_existing_object.hpp>
+#include <boost/python/pure_virtual.hpp>
+#include <boost/python/wrapper.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/call.hpp>
+#include <boost/utility.hpp>
+
+#include <memory>
+
+#ifdef HELD_BY_AUTO_PTR
+# define HELD_PTR(X) , std::auto_ptr< X >
+#else
+# define HELD_PTR(X)
+#endif
+
+using namespace boost::python;
+
+struct P
+{
+ virtual ~P(){}
+ virtual char const* f() = 0;
+ char const* g() { return "P::g()"; }
+};
+
+struct PCallback : P, wrapper<P>
+{
+ char const* f()
+ {
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ return call<char const*>(this->get_override("f").ptr());
+#else
+ return this->get_override("f")();
+#endif
+ }
+};
+
+struct Q : virtual P
+{
+ char const* f() { return "Q::f()"; }
+};
+
+struct A
+{
+ virtual ~A(){}
+ virtual char const* f() { return "A::f()"; }
+};
+
+struct ACallback : A, wrapper<A>
+{
+ char const* f()
+ {
+ if (override f = this->get_override("f"))
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ return call<char const*>(f.ptr());
+#else
+ return f();
+#endif
+
+ return A::f();
+ }
+
+ char const* default_f() { return this->A::f(); }
+};
+
+struct B : A
+{
+ virtual char const* f() { return "B::f()"; }
+};
+
+struct C : A
+{
+ virtual char const* f() { return "C::f()"; }
+};
+
+struct D : A
+{
+ virtual char const* f() { return "D::f()"; }
+ char const* g() { return "D::g()"; }
+};
+
+struct DCallback : D, wrapper<D>
+{
+ char const* f()
+ {
+ if (override f = this->get_override("f"))
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+ return call<char const*>(f.ptr());
+#else
+ return f();
+#endif
+ //else
+ return D::f();
+ }
+};
+
+
+A& getBCppObj ()
+{
+ static B b;
+ return b;
+}
+
+char const* 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; }
+
+#ifdef HELD_BY_AUTO_PTR
+BOOST_PYTHON_MODULE_INIT(polymorphism2_auto_ptr_ext)
+#else
+BOOST_PYTHON_MODULE_INIT(polymorphism2_ext)
+#endif
+{
+ class_<ACallback HELD_PTR(A),boost::noncopyable>("A")
+ .def("f", &A::f, &ACallback::default_f)
+ ;
+
+ def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
+
+ class_<C HELD_PTR(C),bases<A>,boost::noncopyable>("C")
+ .def("f", &C::f)
+ ;
+
+ class_<DCallback HELD_PTR(D),bases<A>,boost::noncopyable>("D")
+ .def("f", &D::f)
+ .def("g", &D::g)
+ ;
+
+ def("pass_a", &pass_a, return_internal_reference<>());
+
+ def("getCCppObj", getCCppObj, return_value_policy<reference_existing_object>());
+
+ def("factory", factory, return_value_policy<manage_new_object>());
+
+ def("call_f", call_f);
+
+ class_<PCallback,boost::noncopyable>("P")
+ .def("f", pure_virtual(&P::f))
+ ;
+
+ class_<Q HELD_PTR(Q), bases<P> >("Q")
+ .def("g", &P::g) // make sure virtual inheritance doesn't interfere
+ ;
+}
+
+//#include "module_tail.cpp"
diff --git a/libs/python/test/polymorphism2.py b/libs/python/test/polymorphism2.py
new file mode 100644
index 000000000..2690bac9a
--- /dev/null
+++ b/libs/python/test/polymorphism2.py
@@ -0,0 +1,94 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+import unittest
+import sys
+
+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_self_default(self):
+
+ class X(A):
+ def f(self):
+ return 'X.f() -> ' + A.f(self)
+
+ x = X()
+
+ self.failUnlessEqual ('X.f() -> A::f()', x.f())
+
+ # This one properly raises the "dangling reference" exception
+ # self.failUnlessEqual ('X.f() -> A::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())
+
+
+def test():
+ # remove the option that upsets unittest
+ import sys
+ sys.argv = [ x for x in sys.argv if x != '--broken-auto-ptr' ]
+ unittest.main()
+
+# This nasty hack basically says that if we're loaded by another module, we'll
+# be testing polymorphism2_auto_ptr_ext instead of polymorphism2_ext.
+if __name__ == "__main__":
+ from polymorphism2_ext import *
+ test()
+else:
+ from polymorphism2_auto_ptr_ext import *
+
diff --git a/libs/python/test/polymorphism2_auto_ptr.cpp b/libs/python/test/polymorphism2_auto_ptr.cpp
new file mode 100644
index 000000000..8cd5ef247
--- /dev/null
+++ b/libs/python/test/polymorphism2_auto_ptr.cpp
@@ -0,0 +1,6 @@
+// Copyright David Abrahams 2005. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define HELD_BY_AUTO_PTR
+#include "polymorphism2.cpp"
diff --git a/libs/python/test/polymorphism2_auto_ptr.py b/libs/python/test/polymorphism2_auto_ptr.py
new file mode 100644
index 000000000..88cf664ab
--- /dev/null
+++ b/libs/python/test/polymorphism2_auto_ptr.py
@@ -0,0 +1,5 @@
+# Copyright David Abrahams 2005. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+import polymorphism2
+polymorphism2.test()
diff --git a/libs/python/test/printer.py b/libs/python/test/printer.py
new file mode 100644
index 000000000..e08f7c453
--- /dev/null
+++ b/libs/python/test/printer.py
@@ -0,0 +1,13 @@
+# Copyright David Abrahams 2006. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+class _printer(object):
+ def __init__(self):
+ self.results = [];
+ def __call__(self, *stuff):
+ for x in stuff:
+ self.results.append(str(x))
+ def check(self, x):
+ if self.results[0] != str(x):
+ print ' Expected:\n %s\n but the C++ interface gave:\n %s' % (x, self.results[0])
+ del self.results[0]
diff --git a/libs/python/test/properties.cpp b/libs/python/test/properties.cpp
new file mode 100644
index 000000000..d338beb91
--- /dev/null
+++ b/libs/python/test/properties.cpp
@@ -0,0 +1,100 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python.hpp>
+
+using namespace boost::python;
+
+namespace test {
+
+// Hmm. return_internal_reference<>() wants to wrap a real class.
+class ret_type
+{
+ public:
+ ret_type() : i(42.5) {}
+ double i;
+};
+
+class crash_me
+{
+ private:
+ ret_type i;
+ public:
+ ret_type& get_i() { return i; }
+};
+
+}
+
+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> return_by_value_t;
+ typedef return_internal_reference<> return_by_internal_reference_t;
+ class_<X>("X", init<int>() )
+ //defining read only property
+ .add_property( "value_r", &X::get_value )
+ .add_property( "value_r_ds", &X::get_value, "value_r_ds is read-only")
+ //defining read \ write property
+ .add_property( "value_rw", &X::get_value, &X::set_value )
+ .add_property( "value_rw_ds", &X::get_value, &X::set_value,
+ "value_rw_ds is read-write")
+ //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 );
+
+
+ class_< test::ret_type>( "ret_type")
+ .add_property( "i", &test::ret_type::i, &test::ret_type::i)
+ ;
+
+ class_< test::crash_me> crash_me_wrapper( "crash_me");
+
+ crash_me_wrapper
+ .def( "get_i", &test::crash_me::get_i , return_internal_reference<>())
+ ;
+
+ crash_me_wrapper.add_property( "i", crash_me_wrapper.attr("get_i"));
+
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/properties.py b/libs/python/test/properties.py
new file mode 100644
index 000000000..720fb8598
--- /dev/null
+++ b/libs/python/test/properties.py
@@ -0,0 +1,106 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+This is test module for properties.
+
+>>> r = properties.ret_type()
+>>> r.i = 22.5
+>>> r.i
+22.5
+>>> c = properties.crash_me()
+>>> c.i.i
+42.5
+
+>>> 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
+
+>>> assert properties.X.value_r_ds.__doc__ == "value_r_ds is read-only"
+
+>>> assert properties.X.value_rw_ds.__doc__ == "value_rw_ds is read-write"
+
+"""
+
+#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/libs/python/test/pyrun.py b/libs/python/test/pyrun.py
new file mode 100644
index 000000000..e033069eb
--- /dev/null
+++ b/libs/python/test/pyrun.py
@@ -0,0 +1,7 @@
+import sys
+
+pythonpath = sys.argv[1]
+scriptfile = sys.argv[2]
+sys.argv = sys.argv[2:]
+sys.path.append(pythonpath)
+execfile(scriptfile)
diff --git a/libs/python/test/pytype_function.cpp b/libs/python/test/pytype_function.cpp
new file mode 100644
index 000000000..46cce19e6
--- /dev/null
+++ b/libs/python/test/pytype_function.cpp
@@ -0,0 +1,85 @@
+// Copyright Joel de Guzman 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/to_python_converter.hpp>
+#include <boost/python/class.hpp>
+
+using namespace boost::python;
+
+struct A
+{
+};
+
+struct B
+{
+ A a;
+ B(const A& a_):a(a_){}
+};
+
+// Converter from A to python int
+struct BToPython
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ : converter::to_python_target_type<A> //inherits get_pytype
+#endif
+{
+ static PyObject* convert(const B& b)
+ {
+ return boost::python::incref(boost::python::object(b.a).ptr());
+ }
+};
+
+// Conversion from python int to A
+struct BFromPython
+{
+ BFromPython()
+ {
+ boost::python::converter::registry::push_back(
+ &convertible,
+ &construct,
+ boost::python::type_id< B >()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &converter::expected_from_python_type<A>::get_pytype//convertible to A can be converted to B
+#endif
+ );
+ }
+
+ static void* convertible(PyObject* obj_ptr)
+ {
+ extract<const A&> ex(obj_ptr);
+ if (!ex.check()) return 0;
+ return obj_ptr;
+ }
+
+ static void construct(
+ PyObject* obj_ptr,
+ boost::python::converter::rvalue_from_python_stage1_data* data)
+ {
+ void* storage = (
+ (boost::python::converter::rvalue_from_python_storage< B >*)data)-> storage.bytes;
+
+ extract<const A&> ex(obj_ptr);
+ new (storage) B(ex());
+ data->convertible = storage;
+ }
+};
+
+
+B func(const B& b) { return b ; }
+
+
+BOOST_PYTHON_MODULE(pytype_function_ext)
+{
+ to_python_converter< B , BToPython,true >(); //has get_pytype
+ BFromPython();
+
+ class_<A>("A") ;
+
+ def("func", &func);
+
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/pytype_function.py b/libs/python/test/pytype_function.py
new file mode 100755
index 000000000..83674632a
--- /dev/null
+++ b/libs/python/test/pytype_function.py
@@ -0,0 +1,32 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> from pytype_function_ext import *
+
+>>> print func.__doc__.splitlines()[1]
+func( (A)arg1) -> A :
+
+>>> print func.__module__
+pytype_function_ext
+
+>>> print func.__name__
+func
+"""
+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/libs/python/test/raw_ctor.cpp b/libs/python/test/raw_ctor.cpp
new file mode 100644
index 000000000..a825ae019
--- /dev/null
+++ b/libs/python/test/raw_ctor.cpp
@@ -0,0 +1,43 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/class.hpp>
+#include <boost/python/raw_function.hpp>
+#include <boost/python/make_constructor.hpp>
+#include <boost/python/dict.hpp>
+#include <boost/python/tuple.hpp>
+#include <boost/python/module.hpp>
+
+using namespace boost::python;
+
+class Foo
+{
+ public:
+ Foo(tuple args, dict kw)
+ : args(args), kw(kw) {}
+
+ tuple args;
+ dict kw;
+};
+
+object init_foo(tuple args, dict kw)
+{
+ tuple rest(args.slice(1,_));
+ return args[0].attr("__init__")(rest, kw);
+}
+
+BOOST_PYTHON_MODULE(raw_ctor_ext)
+{
+ // using no_init postpones defining __init__ function until after
+ // raw_function for proper overload resolution order, since later
+ // defs get higher priority.
+ class_<Foo>("Foo", no_init)
+ .def("__init__", raw_function(&init_foo))
+ .def(init<tuple, dict>())
+ .def_readwrite("args", &Foo::args)
+ .def_readwrite("kw", &Foo::kw)
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/raw_ctor.py b/libs/python/test/raw_ctor.py
new file mode 100644
index 000000000..686948ff0
--- /dev/null
+++ b/libs/python/test/raw_ctor.py
@@ -0,0 +1,76 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> 'importing'
+'importing'
+>>> from raw_ctor_ext import *
+>>> 'imported'
+'imported'
+>>> import sys
+>>> sys.stdout.flush()
+>>> f = Foo(1, 2, 'a', bar = 3, baz = 4)
+>>> f.args
+(1, 2, 'a')
+>>> f.kw.items()
+[('bar', 3), ('baz', 4)]
+"""
+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/libs/python/test/raw_pyobject_fail1.cpp b/libs/python/test/raw_pyobject_fail1.cpp
new file mode 100644
index 000000000..f9dd54bc3
--- /dev/null
+++ b/libs/python/test/raw_pyobject_fail1.cpp
@@ -0,0 +1,11 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/converter/arg_to_python.hpp>
+
+int main()
+{
+ boost::python::converter::arg_to_python<PyTypeObject*> x(0);
+ return 0;
+}
diff --git a/libs/python/test/raw_pyobject_fail2.cpp b/libs/python/test/raw_pyobject_fail2.cpp
new file mode 100644
index 000000000..62c57ae74
--- /dev/null
+++ b/libs/python/test/raw_pyobject_fail2.cpp
@@ -0,0 +1,13 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/converter/arg_to_python.hpp>
+
+struct X : PyObject {};
+
+int main()
+{
+ boost::python::converter::arg_to_python<X*> x(0);
+ return 0;
+}
diff --git a/libs/python/test/register_ptr.cpp b/libs/python/test/register_ptr.cpp
new file mode 100644
index 000000000..6cd4d7856
--- /dev/null
+++ b/libs/python/test/register_ptr.cpp
@@ -0,0 +1,55 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python.hpp>
+#include <boost/shared_ptr.hpp>
+
+using namespace boost;
+using namespace python;
+
+struct A
+{
+ virtual int f() { return 0; }
+};
+
+shared_ptr<A> New() { return shared_ptr<A>( new A() ); }
+
+int Call( 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_) {}
+ A_Wrapper(PyObject* self_, const A& a): self(self_), A(a) {}
+
+ 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)
+ ;
+ register_ptr_to_python< shared_ptr<A> >();
+ def("New", &New);
+ def("Call", &Call);
+ def("Fail", &Fail);
+}
diff --git a/libs/python/test/register_ptr_test.py b/libs/python/test/register_ptr_test.py
new file mode 100644
index 000000000..674e5572f
--- /dev/null
+++ b/libs/python/test/register_ptr_test.py
@@ -0,0 +1,25 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+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/libs/python/test/result.cpp b/libs/python/test/result.cpp
new file mode 100644
index 000000000..d5f43cc3d
--- /dev/null
+++ b/libs/python/test/result.cpp
@@ -0,0 +1,111 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/detail/result.hpp>
+#include <boost/type.hpp>
+#include <functional>
+
+using boost::python::detail::result;
+using boost::type;
+
+void expect_int(type<int>*) {}
+void expect_string(type<char*>*) {}
+
+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<int>(),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<char*>(),0)
+ );
+
+ return 0;
+}
diff --git a/libs/python/test/return_arg.cpp b/libs/python/test/return_arg.cpp
new file mode 100644
index 000000000..d8d3c1ddb
--- /dev/null
+++ b/libs/python/test/return_arg.cpp
@@ -0,0 +1,67 @@
+// Copyright David Abrahams and Nikolay Mladenov 2003.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/def.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_;
+};
+
+void return_arg_f(boost::python::object) {}
+
+using namespace boost::python;
+BOOST_PYTHON_MODULE(return_arg_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)//,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/libs/python/test/return_arg.py b/libs/python/test/return_arg.py
new file mode 100644
index 000000000..f191d5964
--- /dev/null
+++ b/libs/python/test/return_arg.py
@@ -0,0 +1,27 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/select_arg_to_python_test.cpp b/libs/python/test/select_arg_to_python_test.cpp
new file mode 100644
index 000000000..c5faace36
--- /dev/null
+++ b/libs/python/test/select_arg_to_python_test.cpp
@@ -0,0 +1,70 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/converter/arg_to_python.hpp>
+#include <boost/python/type_id.hpp>
+#include <boost/python/handle.hpp>
+#include <boost/python/object.hpp>
+#include <iostream>
+
+// 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<void>)
+{
+ return true;
+}
+}}
+#endif
+
+int result;
+
+#define ASSERT_SAME(T1,T2) assert_same< T1,T2 >()
+
+template <class T, class U>
+void assert_same(U* = 0, T* = 0)
+{
+ BOOST_STATIC_ASSERT((boost::is_same<T,U>::value));
+
+}
+
+
+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<int>::type, value_arg_to_python<int>
+ );
+
+ ASSERT_SAME(
+ select_arg_to_python<reference_wrapper<int> >::type, reference_arg_to_python<int>
+ );
+
+ ASSERT_SAME(
+ select_arg_to_python<pointer_wrapper<int> >::type, pointer_shallow_arg_to_python<int>
+ );
+
+ ASSERT_SAME(
+ select_arg_to_python<int*>::type, pointer_deep_arg_to_python<int*>
+ );
+
+ ASSERT_SAME(
+ select_arg_to_python<handle<> >::type, object_manager_arg_to_python<handle<> >
+ );
+
+ ASSERT_SAME(
+ select_arg_to_python<object>::type, object_manager_arg_to_python<object>
+ );
+
+ ASSERT_SAME(
+ select_arg_to_python<char[20]>::type, arg_to_python<char const*>
+ );
+
+ return result;
+}
diff --git a/libs/python/test/select_from_python_test.cpp b/libs/python/test/select_from_python_test.cpp
new file mode 100644
index 000000000..bb60962a3
--- /dev/null
+++ b/libs/python/test/select_from_python_test.cpp
@@ -0,0 +1,161 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/converter/arg_from_python.hpp>
+#include <boost/python/type_id.hpp>
+#include <iostream>
+
+// gcc 2.95.x, MIPSpro 7.3.1.3 and IBM XL for Linux linker seem to demand this definition
+#if (defined(__GNUC__) && (__GNUC__ < 3)) \
+ || (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) \
+ || (defined(__IBMCPP__) && defined(__linux__))
+namespace boost { namespace python {
+BOOST_PYTHON_DECL bool handle_exception_impl(function0<void>)
+{
+ 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<int>::type, arg_rvalue_from_python<int>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const>::type, arg_rvalue_from_python<int const>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int volatile>::type, arg_rvalue_from_python<int volatile>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const volatile>::type, arg_rvalue_from_python<int const volatile>
+ );
+
+
+
+ ASSERT_SAME(
+ select_arg_from_python<int*>::type, pointer_arg_from_python<int*>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const*>::type, pointer_arg_from_python<int const*>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int volatile*>::type, pointer_arg_from_python<int volatile*>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const volatile*>::type, pointer_arg_from_python<int const volatile*>
+ );
+
+
+
+
+ ASSERT_SAME(
+ select_arg_from_python<int&>::type, reference_arg_from_python<int&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const&>::type, arg_rvalue_from_python<int const&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int volatile&>::type, reference_arg_from_python<int volatile&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const volatile&>::type, reference_arg_from_python<int const volatile&>
+ );
+
+
+
+ ASSERT_SAME(
+ select_arg_from_python<int*&>::type, reference_arg_from_python<int*&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const*&>::type, reference_arg_from_python<int const*&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int volatile*&>::type, reference_arg_from_python<int volatile*&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const volatile*&>::type, reference_arg_from_python<int const volatile*&>
+ );
+
+
+
+ ASSERT_SAME(
+ select_arg_from_python<int* const&>::type, pointer_cref_arg_from_python<int*const&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const* const&>::type, pointer_cref_arg_from_python<int const*const&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int volatile* const&>::type, pointer_cref_arg_from_python<int volatile*const&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const volatile* const&>::type, pointer_cref_arg_from_python<int const volatile*const&>
+ );
+
+
+
+ ASSERT_SAME(
+ select_arg_from_python<int*volatile&>::type, reference_arg_from_python<int*volatile&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const*volatile&>::type, reference_arg_from_python<int const*volatile&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int volatile*volatile&>::type, reference_arg_from_python<int volatile*volatile&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const volatile*volatile&>::type, reference_arg_from_python<int const volatile*volatile&>
+ );
+
+
+
+ ASSERT_SAME(
+ select_arg_from_python<int*const volatile&>::type, reference_arg_from_python<int*const volatile&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const*const volatile&>::type, reference_arg_from_python<int const*const volatile&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int volatile*const volatile&>::type, reference_arg_from_python<int volatile*const volatile&>
+ );
+
+ ASSERT_SAME(
+ select_arg_from_python<int const volatile*const volatile&>::type, reference_arg_from_python<int const volatile*const volatile&>
+ );
+ return result;
+}
diff --git a/libs/python/test/select_holder.cpp b/libs/python/test/select_holder.cpp
new file mode 100644
index 000000000..4ecc52e7a
--- /dev/null
+++ b/libs/python/test/select_holder.cpp
@@ -0,0 +1,76 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/object/class_metadata.hpp>
+#include <boost/python/has_back_reference.hpp>
+#include <boost/python/detail/not_specified.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/same_traits.hpp>
+#include <boost/function/function0.hpp>
+#include <boost/mpl/bool.hpp>
+#include <memory>
+
+struct BR {};
+
+struct Base {};
+struct Derived : Base {};
+
+namespace boost { namespace python
+{
+ // specialization
+ template <>
+ struct has_back_reference<BR>
+ : mpl::true_
+ {
+ };
+}} // namespace boost::python
+
+template <class T, class U>
+void assert_same(U* = 0, T* = 0)
+{
+ BOOST_STATIC_ASSERT((boost::is_same<T,U>::value));
+
+}
+
+template <class T, class Held, class Holder>
+void assert_holder(T* = 0, Held* = 0, Holder* = 0)
+{
+ using namespace boost::python::detail;
+ using namespace boost::python::objects;
+
+ typedef typename class_metadata<
+ T,Held,not_specified,not_specified
+ >::holder h;
+
+ assert_same<Holder>(
+ (h*)0
+ );
+}
+
+int test_main(int, char * [])
+{
+ using namespace boost::python::detail;
+ using namespace boost::python::objects;
+
+ assert_holder<Base,not_specified,value_holder<Base> >();
+
+ assert_holder<BR,not_specified,value_holder_back_reference<BR,BR> >();
+ assert_holder<Base,Base,value_holder_back_reference<Base,Base> >();
+ assert_holder<BR,BR,value_holder_back_reference<BR,BR> >();
+
+ assert_holder<Base,Derived
+ ,value_holder_back_reference<Base,Derived> >();
+
+ assert_holder<Base,std::auto_ptr<Base>
+ ,pointer_holder<std::auto_ptr<Base>,Base> >();
+
+ assert_holder<Base,std::auto_ptr<Derived>
+ ,pointer_holder_back_reference<std::auto_ptr<Derived>,Base> >();
+
+ assert_holder<BR,std::auto_ptr<BR>
+ ,pointer_holder_back_reference<std::auto_ptr<BR>,BR> > ();
+
+ return 0;
+}
+
diff --git a/libs/python/test/shared_ptr.cpp b/libs/python/test/shared_ptr.cpp
new file mode 100644
index 000000000..e5f20a732
--- /dev/null
+++ b/libs/python/test/shared_ptr.cpp
@@ -0,0 +1,217 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/call_method.hpp>
+#include <boost/python/extract.hpp>
+#include <boost/python/def.hpp>
+#include <boost/shared_ptr.hpp>
+#include "test_class.hpp"
+
+#include <memory>
+
+using namespace boost::python;
+using boost::shared_ptr;
+
+typedef test_class<> X;
+typedef test_class<1> Y;
+
+template <class T>
+struct functions
+{
+ static int look(shared_ptr<T> const& x)
+ {
+ return (x.get()) ? x->value() : -1;
+ }
+
+ static void store(shared_ptr<T> x)
+ {
+ storage = x;
+ }
+
+ static void release_store()
+ {
+ store(shared_ptr<T>());
+ }
+
+ static void modify(shared_ptr<T>& x)
+ {
+ x.reset();
+ }
+
+ static shared_ptr<T> get() { return storage; }
+ static shared_ptr<T> &get1() { return storage; }
+
+ static int look_store()
+ {
+ return look(get());
+ }
+
+ template <class C>
+ static void expose(C const& c)
+ {
+ def("look", &look);
+ def("store", &store);
+ def("modify", &modify);
+ def("identity", &identity);
+ def("null", &null);
+
+ const_cast<C&>(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("get1", &get1, return_internal_reference<>())
+ .staticmethod("get1")
+ .def("get", &get)
+ .staticmethod("get")
+ .def("count", &T::count)
+ .staticmethod("count")
+ .def("release", &release_store)
+ .staticmethod("release")
+ ;
+ }
+
+ static shared_ptr<T> identity(shared_ptr<T> x) { return x; }
+ static shared_ptr<T> null(T const&) { return shared_ptr<T>(); }
+
+
+ static shared_ptr<T> storage;
+};
+
+template <class T> shared_ptr<T> functions<T>::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<int>(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<Y> factory(int n)
+{
+ return shared_ptr<Y>(n < 42 ? new Y(n) : new YY(n));
+}
+
+// regressions from Nicodemus
+ struct A
+ {
+ virtual ~A() {}; // silence compiler warnings
+ virtual int f() = 0;
+ static int call_f(shared_ptr<A>& a) { return a->f(); }
+ };
+
+ struct B: A
+ {
+ int f() { return 1; }
+ };
+
+ boost::shared_ptr<A> New(bool make)
+ {
+ return boost::shared_ptr<A>( 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;
+ };
+
+// ------
+
+// from Neal Becker
+
+struct Test {
+ boost::shared_ptr<X> x;
+};
+// ------
+
+
+BOOST_PYTHON_MODULE(shared_ptr_ext)
+{
+ class_<A, boost::shared_ptr<A_Wrapper>, 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<A>.
+ objects::class_value_wrapper<
+ shared_ptr<A>
+ , objects::make_ptr_instance<A, objects::pointer_holder<shared_ptr<A>,A> >
+ >();
+
+ def("New", &New);
+
+ def("factory", factory);
+
+ functions<X>::expose(
+ class_<X, boost::noncopyable>("X", init<int>())
+ .def("value", &X::value)
+ );
+
+ functions<Y>::expose(
+ class_<Y, boost::shared_ptr<Y> >("Y", init<int>())
+ .def("value", &Y::value)
+ );
+
+ class_<YY, bases<Y>, boost::noncopyable>("YY", init<int>())
+ ;
+
+ class_<YYY, shared_ptr<YYY>, bases<Y> >("YYY", init<int>())
+ ;
+
+ functions<Z>::expose(
+ class_<Z, ZWrap>("Z", init<int>())
+ .def("value", &Z::value)
+ .def("v", &Z::v, &ZWrap::default_v)
+ );
+
+// from Neal Becker
+ class_<Test> ("Test")
+ .def_readonly ("x", &Test::x, "x")
+ ;
+// ------
+}
+
+#include "module_tail.cpp"
+
diff --git a/libs/python/test/shared_ptr.py b/libs/python/test/shared_ptr.py
new file mode 100644
index 000000000..554b4a6b6
--- /dev/null
+++ b/libs/python/test/shared_ptr.py
@@ -0,0 +1,130 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from shared_ptr_ext import *
+
+ Test that shared_ptr<Derived> can be converted to shared_ptr<Base>
+
+>>> 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))
+<class 'shared_ptr_ext.Y'>
+>>> type(factory(42))
+<class 'shared_ptr_ext.YY'>
+
+>>> 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/libs/python/test/simple_type.hpp b/libs/python/test/simple_type.hpp
new file mode 100644
index 000000000..d1314ff97
--- /dev/null
+++ b/libs/python/test/simple_type.hpp
@@ -0,0 +1,13 @@
+// Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef SIMPLE_TYPE_DWA2001128_HPP
+# define SIMPLE_TYPE_DWA2001128_HPP
+
+struct simple
+{
+ char* s;
+};
+
+#endif // SIMPLE_TYPE_DWA2001128_HPP
diff --git a/libs/python/test/slice.cpp b/libs/python/test/slice.cpp
new file mode 100644
index 000000000..5072d7f7c
--- /dev/null
+++ b/libs/python/test/slice.cpp
@@ -0,0 +1,140 @@
+#include <boost/python.hpp>
+#include <boost/python/slice.hpp>
+#include <boost/python/str.hpp>
+#include <vector>
+
+// Copyright (c) 2004 Jonathan Brandmeyer
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+using namespace boost::python;
+
+#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) || BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+# define make_tuple boost::python::make_tuple
+#endif
+
+// These checks are only valid under Python 2.3
+// (rich slicing wasn't supported for builtins under Python 2.2)
+bool check_string_rich_slice()
+{
+ object s("hello, world");
+
+ // default slice
+ if (s[slice()] != "hello, world")
+ return false;
+
+ // simple reverse
+ if (s[slice(_,_,-1)] != "dlrow ,olleh")
+ return false;
+
+ // reverse with mixed-sign offsets
+ if (s[slice(-6,1,-1)] != " ,oll")
+ return false;
+
+ // all of the object.cpp check_string_slice() checks should work
+ // with the form that omits the step argument.
+ 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";
+}
+
+// Tried to get more info into the error message (actual array
+// contents) but Numeric complains that treating an array as a boolean
+// value doesn't make any sense.
+#define ASSERT_EQUAL( e1, e2 ) \
+ if (!all((e1) == (e2))) \
+ return "assertion failed: " #e1 " == " #e2 "\nLHS:\n%s\nRHS:\n%s" % make_tuple(e1,e2); \
+else
+
+// These tests work with Python 2.2, but you must have Numeric installed.
+object check_numeric_array_rich_slice(
+ char const* module_name, char const* array_type_name, object all)
+{
+ using numeric::array;
+ array::set_module_and_type(module_name, array_type_name);
+
+ array original = array( make_tuple( make_tuple( 11, 12, 13, 14),
+ make_tuple( 21, 22, 23, 24),
+ make_tuple( 31, 32, 33, 34),
+ make_tuple( 41, 42, 43, 44)));
+ array upper_left_quadrant = array( make_tuple( make_tuple( 11, 12),
+ make_tuple( 21, 22)));
+ array odd_cells = array( make_tuple( make_tuple( 11, 13),
+ make_tuple( 31, 33)));
+ array even_cells = array( make_tuple( make_tuple( 22, 24),
+ make_tuple( 42, 44)));
+ array lower_right_quadrant_reversed = array(
+ make_tuple( make_tuple(44, 43),
+ make_tuple(34, 33)));
+
+ // The following comments represent equivalent Python expressions used
+ // to validate the array behavior.
+ // original[::] == original
+ ASSERT_EQUAL(original[slice()],original);
+
+ // original[:2,:2] == array( [[11, 12], [21, 22]])
+ ASSERT_EQUAL(original[make_tuple(slice(_,2), slice(_,2))],upper_left_quadrant);
+
+ // original[::2,::2] == array( [[11, 13], [31, 33]])
+ ASSERT_EQUAL(original[make_tuple( slice(_,_,2), slice(_,_,2))],odd_cells);
+
+ // original[1::2, 1::2] == array( [[22, 24], [42, 44]])
+ ASSERT_EQUAL(original[make_tuple( slice(1,_,2), slice(1,_,2))],even_cells);
+
+ // original[:-3:-1, :-3,-1] == array( [[44, 43], [34, 33]])
+ ASSERT_EQUAL(original[make_tuple( slice(_,-3,-1), slice(_,-3,-1))],lower_right_quadrant_reversed);
+
+ return object(1);
+}
+
+// Verify functions accepting a slice argument can be called
+bool accept_slice( slice) { return true; }
+
+#if BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1400)) \
+ || BOOST_WORKAROUND( BOOST_INTEL_WIN, == 710)
+int check_slice_get_indices(slice index);
+#endif
+int check_slice_get_indices(
+#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+ const
+#endif
+ slice index)
+{
+ // A vector of integers from [-5, 5].
+ std::vector<int> coll(11);
+ typedef std::vector<int>::iterator coll_iterator;
+
+ for (coll_iterator i = coll.begin(); i != coll.end(); ++i) {
+ *i = i - coll.begin() - 5;
+ }
+
+ slice::range<std::vector<int>::iterator> bounds;
+ try {
+ bounds = index.get_indices(coll.begin(), coll.end());
+ }
+ catch (std::invalid_argument) {
+ return 0;
+ }
+ int sum = 0;
+ while (bounds.start != bounds.stop) {
+ sum += *bounds.start;
+ std::advance( bounds.start, bounds.step);
+ }
+ sum += *bounds.start;
+ return sum;
+}
+
+
+BOOST_PYTHON_MODULE(slice_ext)
+{
+ def( "accept_slice", accept_slice);
+ def( "check_numeric_array_rich_slice", check_numeric_array_rich_slice);
+ def( "check_string_rich_slice", check_string_rich_slice);
+ def( "check_slice_get_indices", check_slice_get_indices);
+}
diff --git a/libs/python/test/slice.py b/libs/python/test/slice.py
new file mode 100644
index 000000000..95f4883b0
--- /dev/null
+++ b/libs/python/test/slice.py
@@ -0,0 +1,72 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> from slice_ext import *
+>>> accept_slice(slice(1, None, (1,2)))
+1
+>>> try:
+... accept_slice(list((1,2)))
+... print "test failed"
+... except:
+... print "test passed"
+...
+test passed
+>>> try:
+... from Numeric import array
+... except:
+... print 1
+... else:
+... check_numeric_array_rich_slice('Numeric', 'ArrayType', lambda x:x)
+...
+1
+>>> try:
+... from numarray import array, all
+... except:
+... print 1
+... else:
+... check_numeric_array_rich_slice('numarray', 'NDArray', all)
+...
+1
+>>> import sys
+>>> if sys.version_info[0] == 2 and sys.version_info[1] >= 3:
+... check_string_rich_slice()
+... elif sys.version_info[0] > 2:
+... check_string_rich_slice()
+... else:
+... print 1
+...
+1
+>>> check_slice_get_indices( slice(None))
+0
+>>> check_slice_get_indices( slice(2,-2))
+0
+>>> check_slice_get_indices( slice(2, None, 2))
+5
+>>> check_slice_get_indices( slice(2, None, -1))
+-12
+>>> check_slice_get_indices( slice( 20, None))
+0
+>>> check_slice_get_indices( slice( -2, -5, -2))
+6
+"""
+
+# Performs an affirmative and negative argument resolution check,
+# checks the operation of extended slicing in Numeric arrays
+# (only performed if Numeric.array or numarray.array can be found).
+# checks the operation of extended slicing in new strings (Python 2.3 only).
+
+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/libs/python/test/staticmethod.cpp b/libs/python/test/staticmethod.cpp
new file mode 100644
index 000000000..dcd75ca82
--- /dev/null
+++ b/libs/python/test/staticmethod.cpp
@@ -0,0 +1,48 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/call_method.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+
+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() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
+
+ void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
+ int value() const { BOOST_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>("X", init<int>())
+ .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/libs/python/test/staticmethod.py b/libs/python/test/staticmethod.py
new file mode 100644
index 000000000..cc2fb6a7b
--- /dev/null
+++ b/libs/python/test/staticmethod.py
@@ -0,0 +1,57 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/stl_iterator.cpp b/libs/python/test/stl_iterator.cpp
new file mode 100644
index 000000000..409e0da84
--- /dev/null
+++ b/libs/python/test/stl_iterator.cpp
@@ -0,0 +1,33 @@
+// Copyright Eric Niebler 2005.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/iterator.hpp>
+#include <boost/python/stl_iterator.hpp>
+#include <list>
+
+using namespace boost::python;
+
+typedef std::list<int> list_int;
+
+void assign(list_int& x, object const& y)
+{
+ stl_input_iterator<int> begin(y), end;
+ x.clear();
+ for( ; begin != end; ++begin)
+ x.push_back(*begin);
+}
+
+BOOST_PYTHON_MODULE(stl_iterator_ext)
+{
+ using boost::python::iterator; // gcc 2.96 bug workaround
+
+ class_<list_int>("list_int")
+ .def("assign", assign)
+ .def("__iter__", iterator<list_int>())
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/stl_iterator.py b/libs/python/test/stl_iterator.py
new file mode 100644
index 000000000..2c324c0ab
--- /dev/null
+++ b/libs/python/test/stl_iterator.py
@@ -0,0 +1,39 @@
+# Copyright Eric Niebler 2005. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from stl_iterator_ext import *
+>>> x = list_int()
+>>> x.assign(iter([1,2,3,4,5]))
+>>> for y in x:
+... print y
+1
+2
+3
+4
+5
+>>> def generator():
+... yield 1
+... yield 2
+... raise RuntimeError, "oops"
+>>> try:
+... x.assign(iter(generator()))
+... print "NOT OK"
+... except RuntimeError:
+... print "OK"
+OK
+'''
+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/libs/python/test/str.cpp b/libs/python/test/str.cpp
new file mode 100644
index 000000000..0505b250a
--- /dev/null
+++ b/libs/python/test/str.cpp
@@ -0,0 +1,84 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/str.hpp>
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+
+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"));
+#if PY_VERSION_HEX < 0x03000000
+ print(data.encode("utf-8"));
+ print(data.decode("utf-8"));
+#else
+ print(data.encode("utf-8").attr("decode")("utf-8"));
+ print(data.encode("utf-8").attr("decode")("utf-8"));
+#endif
+
+ BOOST_ASSERT(!data.endswith("xx"));
+ BOOST_ASSERT(!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));
+
+ BOOST_ASSERT(!data.startswith("asdf"));
+ BOOST_ASSERT(!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);
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/str.py b/libs/python/test/str.py
new file mode 100644
index 000000000..5f10580cf
--- /dev/null
+++ b/libs/python/test/str.py
@@ -0,0 +1,53 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> from str_ext import *
+>>> def printer(*args):
+... for x in args: print x,
+... print
+...
+>>> work_with_string(printer) #doctest: +NORMALIZE_WHITESPACE
+['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
+['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
+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/libs/python/test/string_literal.cpp b/libs/python/test/string_literal.cpp
new file mode 100644
index 000000000..7a349d6c2
--- /dev/null
+++ b/libs/python/test/string_literal.cpp
@@ -0,0 +1,42 @@
+// Copyright David Abrahams 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/detail/string_literal.hpp>
+//#include <stdio.h>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+using namespace boost::python::detail;
+
+
+template <class T>
+void expect_string_literal(T const&)
+{
+ BOOST_STATIC_ASSERT(is_string_literal<T const>::value);
+}
+
+int main()
+{
+ expect_string_literal("hello");
+ BOOST_STATIC_ASSERT(!is_string_literal<int*&>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<int* const&>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<int*volatile&>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<int*const volatile&>::value);
+
+ BOOST_STATIC_ASSERT(!is_string_literal<char const*>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<char*>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<char*&>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<char* const&>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<char*volatile&>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<char*const volatile&>::value);
+
+ BOOST_STATIC_ASSERT(!is_string_literal<char[20]>::value);
+ BOOST_STATIC_ASSERT(is_string_literal<char const[20]>::value);
+ BOOST_STATIC_ASSERT(is_string_literal<char const[3]>::value);
+
+ BOOST_STATIC_ASSERT(!is_string_literal<int[20]>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<int const[20]>::value);
+ BOOST_STATIC_ASSERT(!is_string_literal<int const[3]>::value);
+ return boost::report_errors();
+}
diff --git a/libs/python/test/test_builtin_converters.cpp b/libs/python/test/test_builtin_converters.cpp
new file mode 100644
index 000000000..f66e61bd8
--- /dev/null
+++ b/libs/python/test/test_builtin_converters.cpp
@@ -0,0 +1,152 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <complex>
+#include <boost/python/handle.hpp>
+#include <boost/python/cast.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/detail/wrap_python.hpp>
+
+template <class T>
+struct by_value
+{
+ static T rewrap(T x)
+ {
+ return x;
+ }
+ static int size(void)
+ {
+ return sizeof(T);
+ }
+};
+
+template <class T>
+struct by_const_reference
+{
+ static T rewrap(T const& x)
+ {
+ return x;
+ }
+};
+
+template <class T>
+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<PyTypeObject> get_type(handle<> x)
+{
+ return handle<PyTypeObject>(borrowed(x->ob_type));
+}
+
+handle<> return_null_handle()
+{
+ return handle<>();
+}
+
+char const* rewrap_value_mutable_cstring(char* x) { return x; }
+
+object identity_(object x) { return x; }
+
+BOOST_PYTHON_MODULE(builtin_converters_ext)
+{
+ def("get_type", get_type);
+ def("return_null_handle", return_null_handle);
+
+// These methods are used solely for getting some C++ type sizes
+ def("bool_size", by_value<bool>::size);
+ def("char_size", by_value<char>::size);
+ def("int_size", by_value<int>::size);
+ def("short_size", by_value<short>::size);
+ def("long_size", by_value<long>::size);
+#ifdef HAVE_LONG_LONG
+ def("long_long_size", by_value<BOOST_PYTHON_LONG_LONG>::size);
+#endif
+
+ def("rewrap_value_bool", by_value<bool>::rewrap);
+ def("rewrap_value_char", by_value<char>::rewrap);
+ def("rewrap_value_signed_char", by_value<signed char>::rewrap);
+ def("rewrap_value_unsigned_char", by_value<unsigned char>::rewrap);
+ def("rewrap_value_int", by_value<int>::rewrap);
+ def("rewrap_value_unsigned_int", by_value<unsigned int>::rewrap);
+ def("rewrap_value_short", by_value<short>::rewrap);
+ def("rewrap_value_unsigned_short", by_value<unsigned short>::rewrap);
+ def("rewrap_value_long", by_value<long>::rewrap);
+ def("rewrap_value_unsigned_long", by_value<unsigned long>::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<BOOST_PYTHON_LONG_LONG>::rewrap);
+ def("rewrap_value_unsigned_long_long", by_value<unsigned BOOST_PYTHON_LONG_LONG>::rewrap);
+# endif
+ def("rewrap_value_float", by_value<float>::rewrap);
+ def("rewrap_value_double", by_value<double>::rewrap);
+ def("rewrap_value_long_double", by_value<long double>::rewrap);
+ def("rewrap_value_complex_float", by_value<std::complex<float> >::rewrap);
+ def("rewrap_value_complex_double", by_value<std::complex<double> >::rewrap);
+ def("rewrap_value_complex_long_double", by_value<std::complex<long double> >::rewrap);
+ def("rewrap_value_wstring",
+# if defined(BOOST_NO_STD_WSTRING) || !defined(Py_USING_UNICODE)
+ identity_
+# else
+ by_value<std::wstring>::rewrap
+# endif
+ );
+ def("rewrap_value_string",
+# if defined(BOOST_NO_STD_WSTRING) || !defined(Py_USING_UNICODE)
+ identity_
+# else
+ by_value<std::wstring>::rewrap
+# endif
+ );
+ def("rewrap_value_string", by_value<std::string>::rewrap);
+ def("rewrap_value_cstring", by_value<char const*>::rewrap);
+ def("rewrap_value_handle", by_value<handle<> >::rewrap);
+ def("rewrap_value_object", by_value<object>::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<bool>::rewrap);
+ def("rewrap_const_reference_char", by_const_reference<char>::rewrap);
+ def("rewrap_const_reference_signed_char", by_const_reference<signed char>::rewrap);
+ def("rewrap_const_reference_unsigned_char", by_const_reference<unsigned char>::rewrap);
+ def("rewrap_const_reference_int", by_const_reference<int>::rewrap);
+ def("rewrap_const_reference_unsigned_int", by_const_reference<unsigned int>::rewrap);
+ def("rewrap_const_reference_short", by_const_reference<short>::rewrap);
+ def("rewrap_const_reference_unsigned_short", by_const_reference<unsigned short>::rewrap);
+ def("rewrap_const_reference_long", by_const_reference<long>::rewrap);
+ def("rewrap_const_reference_unsigned_long", by_const_reference<unsigned long>::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<BOOST_PYTHON_LONG_LONG>::rewrap);
+ def("rewrap_const_reference_unsigned_long_long", by_const_reference<unsigned BOOST_PYTHON_LONG_LONG>::rewrap);
+# endif
+ def("rewrap_const_reference_float", by_const_reference<float>::rewrap);
+ def("rewrap_const_reference_double", by_const_reference<double>::rewrap);
+ def("rewrap_const_reference_long_double", by_const_reference<long double>::rewrap);
+ def("rewrap_const_reference_complex_float", by_const_reference<std::complex<float> >::rewrap);
+ def("rewrap_const_reference_complex_double", by_const_reference<std::complex<double> >::rewrap);
+ def("rewrap_const_reference_complex_long_double", by_const_reference<std::complex<long double> >::rewrap);
+ def("rewrap_const_reference_string", by_const_reference<std::string>::rewrap);
+ def("rewrap_const_reference_cstring", by_const_reference<char const*>::rewrap);
+ def("rewrap_const_reference_handle", by_const_reference<handle<> >::rewrap);
+ def("rewrap_const_reference_object", by_const_reference<object>::rewrap);
+ def("rewrap_reference_object", by_reference<object>::rewrap);
+}
+
diff --git a/libs/python/test/test_builtin_converters.py b/libs/python/test/test_builtin_converters.py
new file mode 100644
index 000000000..5a6c8c50a
--- /dev/null
+++ b/libs/python/test/test_builtin_converters.py
@@ -0,0 +1,302 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+r"""
+>>> from builtin_converters_ext import *
+
+# Provide values for integer converter tests
+>>> def _signed_values(s):
+... base = 2 ** (8 * s - 1)
+... return [[-base, -1, 1, base - 1], [-base - 1, base]]
+>>> def _unsigned_values(s):
+... base = 2 ** (8 * s)
+... return [[1, base - 1], [-1L, -1, base]]
+
+# Wrappers to simplify tests
+>>> def should_pass(method, values):
+... result = map(method, values[0])
+... if result != values[0]:
+... print "Got %s but expected %s" % (result, values[0])
+>>> def test_overflow(method, values):
+... for v in values[1]:
+... try: method(v)
+... except OverflowError: pass
+... else: print "OverflowError expected"
+
+# 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)
+>>> if not 'long_long_size' in dir():
+... def long_long_size(): return long_size()
+
+>>> try: bool_exists = bool
+... except: pass
+... else:
+... rewrap_value_bool(True)
+... rewrap_value_bool(False)
+True
+False
+
+>>> 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) == 42
+True
+>>> rewrap_value_unsigned_long_long(42) == 42
+True
+
+ show that we have range checking.
+
+>>> should_pass(rewrap_value_signed_char, _signed_values(char_size()))
+>>> should_pass(rewrap_value_short, _signed_values(short_size()))
+>>> should_pass(rewrap_value_int, _signed_values(int_size()))
+>>> should_pass(rewrap_value_long, _signed_values(long_size()))
+>>> should_pass(rewrap_value_long_long, _signed_values(long_long_size()))
+
+>>> should_pass(rewrap_value_unsigned_char, _unsigned_values(char_size()))
+>>> should_pass(rewrap_value_unsigned_short, _unsigned_values(short_size()))
+>>> should_pass(rewrap_value_unsigned_int, _unsigned_values(int_size()))
+>>> should_pass(rewrap_value_unsigned_long, _unsigned_values(long_size()))
+>>> should_pass(rewrap_value_unsigned_long_long,
+... _unsigned_values(long_long_size()))
+
+>>> test_overflow(rewrap_value_signed_char, _signed_values(char_size()))
+>>> test_overflow(rewrap_value_short, _signed_values(short_size()))
+>>> test_overflow(rewrap_value_int, _signed_values(int_size()))
+>>> test_overflow(rewrap_value_long, _signed_values(long_size()))
+>>> test_overflow(rewrap_value_long_long, _signed_values(long_long_size()))
+
+>>> test_overflow(rewrap_value_unsigned_char, _unsigned_values(char_size()))
+>>> test_overflow(rewrap_value_unsigned_short, _unsigned_values(short_size()))
+>>> test_overflow(rewrap_value_unsigned_int, _unsigned_values(int_size()))
+>>> test_overflow(rewrap_value_unsigned_long, _unsigned_values(long_size()))
+
+# Exceptionally for PyLong_AsUnsignedLongLong(), a negative value raises
+# TypeError on Python versions prior to 2.7
+>>> for v in _unsigned_values(long_long_size())[1]:
+... try: rewrap_value_unsigned_long_long(v)
+... except (OverflowError, TypeError): pass
+... else: print "OverflowError or TypeError expected"
+
+>>> 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?'
+
+>>> print rewrap_value_wstring(u'yo, wassup?')
+yo, wassup?
+
+ test that overloading on unicode works:
+
+>>> print rewrap_value_string(u'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) == 42
+True
+>>> rewrap_const_reference_unsigned_long_long(42) == 42
+True
+
+
+>>> 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<T> 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_ext
+
+ if 'rewrap_value_long_long' in dir(builtin_converters_ext):
+ 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/libs/python/test/test_class.hpp b/libs/python/test/test_class.hpp
new file mode 100644
index 000000000..5404fdba2
--- /dev/null
+++ b/libs/python/test/test_class.hpp
@@ -0,0 +1,32 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef TEST_CLASS_DWA2002326_HPP
+# define TEST_CLASS_DWA2002326_HPP
+# include <boost/detail/lightweight_test.hpp>
+
+template <int n = 0>
+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() { BOOST_TEST(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; }
+
+ void set(int _x) { BOOST_TEST(magic == 7654321 + n); this->x = _x; }
+ int value() const { BOOST_TEST(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 n>
+int test_class<n>::counter;
+
+#endif // TEST_CLASS_DWA2002326_HPP
diff --git a/libs/python/test/test_cltree.py b/libs/python/test/test_cltree.py
new file mode 100644
index 000000000..016cf63d1
--- /dev/null
+++ b/libs/python/test/test_cltree.py
@@ -0,0 +1,43 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#!/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/libs/python/test/test_overload_resolution.cpp b/libs/python/test/test_overload_resolution.cpp
new file mode 100644
index 000000000..e15bcc6a7
--- /dev/null
+++ b/libs/python/test/test_overload_resolution.cpp
@@ -0,0 +1,53 @@
+// Copyright Troy D. Straszheim 2009
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// example that shows problems with overloading and automatic conversion.
+// if you call one of the below functions from python with bool/int/double,
+// you'll see that the overload called is first match, not best match.
+// See overload matching in luabind for an example of how to do this better.
+//
+// see this mail:
+// http://mail.python.org/pipermail/cplusplus-sig/2009-March/014362.html
+//
+// This test isn't called by the cmake/jamfiles. For future use.
+//
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <complex>
+#include <boost/python/handle.hpp>
+#include <boost/python/cast.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/detail/wrap_python.hpp>
+
+using boost::python::def;
+using boost::python::handle;
+using boost::python::object;
+using boost::python::borrowed;
+
+std::string takes_bool(bool b) { return "bool"; }
+std::string takes_int(int b) { return "int"; }
+std::string takes_double(double b) { return "double"; }
+
+
+BOOST_PYTHON_MODULE(overload_resolution)
+{
+ def("bid", takes_bool);
+ def("bid", takes_int);
+ def("bid", takes_double);
+
+ def("dib", takes_double);
+ def("dib", takes_int);
+ def("dib", takes_bool);
+
+ def("idb", takes_int);
+ def("idb", takes_double);
+ def("idb", takes_bool);
+
+ def("bdi", takes_bool);
+ def("bdi", takes_double);
+ def("bdi", takes_int);
+}
+
diff --git a/libs/python/test/test_pointer_adoption.cpp b/libs/python/test/test_pointer_adoption.cpp
new file mode 100644
index 000000000..a4e14af5d
--- /dev/null
+++ b/libs/python/test/test_pointer_adoption.cpp
@@ -0,0 +1,125 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/manage_new_object.hpp>
+#include <boost/python/return_internal_reference.hpp>
+#include <boost/python/class.hpp>
+
+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<A*>(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<manage_new_object>());
+
+ def("as_A", as_A, return_internal_reference<>());
+
+ class_<Base>("Base")
+ ;
+
+ class_<A, bases<Base> >("A", no_init)
+ .def("content", &A::content)
+ .def("get_inner", &A::get_inner, return_internal_reference<>())
+ ;
+
+ class_<inner>("inner", no_init)
+ .def("change", &inner::change)
+ ;
+
+ class_<B>("B")
+ .def(init<A*>()[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/libs/python/test/test_pointer_adoption.py b/libs/python/test/test_pointer_adoption.py
new file mode 100644
index 000000000..5bb9dd6dc
--- /dev/null
+++ b/libs/python/test/test_pointer_adoption.py
@@ -0,0 +1,93 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> 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/libs/python/test/tuple.cpp b/libs/python/test/tuple.cpp
new file mode 100644
index 000000000..d48e91d88
--- /dev/null
+++ b/libs/python/test/tuple.cpp
@@ -0,0 +1,33 @@
+// Copyright David Abrahams 2005. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/tuple.hpp>
+
+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/libs/python/test/tuple.py b/libs/python/test/tuple.py
new file mode 100644
index 000000000..9d25aef41
--- /dev/null
+++ b/libs/python/test/tuple.py
@@ -0,0 +1,37 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+"""
+>>> 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) #doctest: +NORMALIZE_WHITESPACE
+('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/libs/python/test/upcast.cpp b/libs/python/test/upcast.cpp
new file mode 100644
index 000000000..255429f16
--- /dev/null
+++ b/libs/python/test/upcast.cpp
@@ -0,0 +1,19 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/cast.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct X { long x; };
+struct Y : X, PyObject {};
+
+int main()
+{
+ PyTypeObject o;
+ Y y;
+ BOOST_TEST(&Py_REFCNT(boost::python::upcast<PyObject>(&o)) == &Py_REFCNT(&o));
+ BOOST_TEST(&Py_REFCNT(boost::python::upcast<PyObject>(&y)) == &Py_REFCNT(&y));
+ return boost::report_errors();
+}
diff --git a/libs/python/test/vector_indexing_suite.cpp b/libs/python/test/vector_indexing_suite.cpp
new file mode 100644
index 000000000..0f9cd74ca
--- /dev/null
+++ b/libs/python/test/vector_indexing_suite.cpp
@@ -0,0 +1,62 @@
+// Copyright Joel de Guzman 2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/implicit.hpp>
+
+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>("X")
+ .def(init<>())
+ .def(init<X>())
+ .def(init<std::string>())
+ .def("__repr__", &X::repr)
+ .def("reset", &X::reset)
+ .def("foo", &X::foo)
+ ;
+
+ def("x_value", x_value);
+ implicitly_convertible<std::string, X>();
+
+ class_<std::vector<X> >("XVec")
+ .def(vector_indexing_suite<std::vector<X> >())
+ ;
+
+ // Compile check only...
+ class_<std::vector<float> >("FloatVec")
+ .def(vector_indexing_suite<std::vector<float> >())
+ ;
+
+ // Compile check only...
+ class_<std::vector<bool> >("BoolVec")
+ .def(vector_indexing_suite<std::vector<bool> >())
+ ;
+
+ // vector of strings
+ class_<std::vector<std::string> >("StringVec")
+ .def(vector_indexing_suite<std::vector<std::string> >())
+ ;
+}
+
diff --git a/libs/python/test/vector_indexing_suite.py b/libs/python/test/vector_indexing_suite.py
new file mode 100644
index 000000000..5fe2efe4d
--- /dev/null
+++ b/libs/python/test/vector_indexing_suite.py
@@ -0,0 +1,370 @@
+# Copyright Joel de Guzman 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+
+#####################################################################
+# 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 ]
+
+#####################################################################
+# extend using a generator expression
+#####################################################################
+>>> v[:] = ['a','b','c','d','e'] # reset again
+>>> def generator():
+... addlist = ['f','g','h','i','j']
+... for i in addlist:
+... if i != 'g':
+... yield i
+>>> v.extend(generator())
+>>> print_xvec(v)
+[ a b c d e f h i j ]
+
+#####################################################################
+# vector of strings
+#####################################################################
+>>> sv = StringVec()
+>>> sv.append('a')
+>>> print sv[0]
+a
+
+#####################################################################
+# 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/libs/python/test/virtual_functions.cpp b/libs/python/test/virtual_functions.cpp
new file mode 100644
index 000000000..774b11b12
--- /dev/null
+++ b/libs/python/test/virtual_functions.cpp
@@ -0,0 +1,125 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/return_internal_reference.hpp>
+#include <boost/python/call_method.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+
+#define BOOST_ENABLE_ASSERT_HANDLER
+#include <boost/assert.hpp>
+
+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() { BOOST_ASSERT(magic == 7654321); magic = 6666666; x = 9999; --counter; }
+
+ void set(int _x) { BOOST_ASSERT(magic == 7654321); this->x = _x; }
+ int value() const { BOOST_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<int>(self, "f", boost::ref(y));
+ }
+
+ abstract& g(Y const& y)
+ {
+ return call_method<abstract&>(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<int>(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, concrete_callback>("concrete", init<int>())
+ .def("value", &concrete::value)
+ .def("set", &concrete::set)
+ .def("call_f", &concrete::call_f)
+ .def("f", &concrete_callback::f_impl)
+ ;
+
+ class_<abstract, boost::noncopyable, abstract_callback
+ >("abstract", init<int>())
+
+ .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>("Y", init<int>())
+ .def("value", &Y::value)
+ .def("set", &Y::set)
+ ;
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/virtual_functions.py b/libs/python/test/virtual_functions.py
new file mode 100644
index 000000000..1372f9afb
--- /dev/null
+++ b/libs/python/test/virtual_functions.py
@@ -0,0 +1,110 @@
+# Copyright David Abrahams 2004. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> 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/libs/python/test/voidptr.cpp b/libs/python/test/voidptr.cpp
new file mode 100644
index 000000000..82e412bea
--- /dev/null
+++ b/libs/python/test/voidptr.cpp
@@ -0,0 +1,43 @@
+// Copyright Niall Douglas 2005.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+# include <boost/python/return_opaque_pointer.hpp>
+# include <boost/python/def.hpp>
+# include <boost/python/module.hpp>
+# include <boost/python/return_value_policy.hpp>
+
+static void *test=(void *) 78;
+
+void *get()
+{
+ return test;
+}
+
+void *getnull()
+{
+ return 0;
+}
+
+void use(void *a)
+{
+ if(a!=test)
+ throw std::runtime_error(std::string("failed"));
+}
+
+int useany(void *a)
+{
+ return a ? 1 : 0;
+}
+
+
+namespace bpl = boost::python;
+
+BOOST_PYTHON_MODULE(voidptr_ext)
+{
+ bpl::def("get", &::get, bpl::return_value_policy<bpl::return_opaque_pointer>());
+ bpl::def("getnull", &::getnull, bpl::return_value_policy<bpl::return_opaque_pointer>());
+ bpl::def("use", &::use);
+ bpl::def("useany", &::useany);
+}
diff --git a/libs/python/test/voidptr.py b/libs/python/test/voidptr.py
new file mode 100644
index 000000000..da1fa9c14
--- /dev/null
+++ b/libs/python/test/voidptr.py
@@ -0,0 +1,54 @@
+# Copyright Niall Douglas 2005.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+
+"""
+>>> from voidptr_ext import *
+
+
+ Check for correct conversion
+
+>>> use(get())
+
+ Check that None is converted to a NULL void 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
+
+ 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'
+"""
+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/libs/python/test/wrapper_held_type.cpp b/libs/python/test/wrapper_held_type.cpp
new file mode 100644
index 000000000..e99422796
--- /dev/null
+++ b/libs/python/test/wrapper_held_type.cpp
@@ -0,0 +1,69 @@
+// Copyright David Abrahams 2005. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/python/register_ptr_to_python.hpp>
+#include <boost/python/def.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/wrapper.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/implicit.hpp>
+
+#include <memory>
+
+struct data
+{
+ virtual ~data() {}; // silence compiler warnings
+ virtual int id() const
+ {
+ return 42;
+ }
+};
+
+std::auto_ptr<data> create_data()
+{
+ return std::auto_ptr<data>( new data );
+}
+
+void do_nothing( std::auto_ptr<data>& ){}
+
+
+namespace bp = boost::python;
+
+struct data_wrapper : data, bp::wrapper< data >
+{
+ data_wrapper(data const & arg )
+ : data( arg )
+ , bp::wrapper< data >()
+ {}
+
+ data_wrapper()
+ : data()
+ , bp::wrapper< data >()
+ {}
+
+ virtual int id() const
+ {
+ if( bp::override id = this->get_override( "id" ) )
+ return bp::call<int>(id.ptr()); // id();
+ else
+ return data::id( );
+ }
+
+ virtual int default_id( ) const
+ {
+ return this->data::id( );
+ }
+
+};
+
+BOOST_PYTHON_MODULE(wrapper_held_type_ext)
+{
+ bp::class_< data_wrapper, std::auto_ptr< data > >( "data" )
+ .def( "id", &data::id, &::data_wrapper::default_id );
+
+ bp::def( "do_nothing", &do_nothing );
+ bp::def( "create_data", &create_data );
+}
+
+#include "module_tail.cpp"
diff --git a/libs/python/test/wrapper_held_type.py b/libs/python/test/wrapper_held_type.py
new file mode 100644
index 000000000..4b33ff738
--- /dev/null
+++ b/libs/python/test/wrapper_held_type.py
@@ -0,0 +1,34 @@
+# Copyright David Abrahams 2005. Distributed under the Boost
+# Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+'''
+>>> from wrapper_held_type_ext import *
+>>> d = data()
+>>> print d.id()
+42
+>>> do_nothing( d )
+>>> print d.id()
+42
+>>> d = create_data()
+>>> print d.id()
+42
+>>> do_nothing( d )
+>>> print d.id()
+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/libs/python/todo.html b/libs/python/todo.html
new file mode 100644
index 000000000..c2c4bdf7b
--- /dev/null
+++ b/libs/python/todo.html
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
+<title>Boost.Python TODO list Boost</title>
+<meta name="copyright" content="Copyright David Abrahams 2003. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)" />
+<link rel="stylesheet" href="../../rst.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="boost-python-todo-list-logo">
+<h1 class="title"><a class="reference" href="index.html">Boost.Python</a> TODO list <a class="reference" href="../../index.htm"><img alt="Boost" class="boost-logo" src="../../boost.png" /></a></h1>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr><th class="docinfo-name">Copyright:</th>
+<td>Copyright David Abrahams 2003. Use, modification, and
+distribution are subject to the Boost Software License, Version
+1.0. (See accompanying file <a class="reference" href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+<a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td></tr>
+</tbody>
+</table>
+<!-- -*- mode: rst -*- -->
+<div class="contents topic">
+<p class="topic-title first"><a id="outline" name="outline">Outline</a></p>
+<ul class="simple">
+<li><a class="reference" href="#class-support" id="id4" name="id4">Class Support</a><ul>
+<li><a class="reference" href="#base-class-for-virtual-function-callback-wrappers" id="id5" name="id5">Base Class for Virtual Function Callback Wrappers</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#miscellaneous" id="id6" name="id6">Miscellaneous</a><ul>
+<li><a class="reference" href="#support-for-enums-with-duplicate-values" id="id7" name="id7">Support for Enums with Duplicate Values</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#functions" id="id8" name="id8">Functions</a><ul>
+<li><a class="reference" href="#wrapping-function-objects" id="id9" name="id9">Wrapping Function Objects</a></li>
+<li><a class="reference" href="#best-match-overload-resolution" id="id10" name="id10">&quot;Best Match&quot; Overload Resolution</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#type-converters" id="id11" name="id11">Type Converters</a><ul>
+<li><a class="reference" href="#lvalue-conversions-from-non-const-pytypeobject-s" id="id12" name="id12">Lvalue conversions from non-const <tt class="docutils literal"><span class="pre">PyTypeObject*</span></tt>s</a></li>
+<li><a class="reference" href="#converter-scoping" id="id13" name="id13">Converter Scoping</a></li>
+<li><a class="reference" href="#boost-tuple" id="id14" name="id14"><tt class="docutils literal"><span class="pre">boost::tuple</span></tt></a></li>
+<li><a class="reference" href="#file-conversions" id="id15" name="id15"><tt class="docutils literal"><span class="pre">FILE*</span></tt> conversions</a></li>
+<li><a class="reference" href="#void-conversions" id="id16" name="id16"><tt class="docutils literal"><span class="pre">void*</span></tt> conversions</a></li>
+<li><a class="reference" href="#post-call-actions" id="id17" name="id17">Post-Call Actions</a></li>
+<li><a class="reference" href="#pyunicode-support" id="id18" name="id18"><tt class="docutils literal"><span class="pre">PyUnicode</span></tt> Support</a></li>
+<li><a class="reference" href="#ownership-metadata" id="id19" name="id19">Ownership Metadata</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#documentation" id="id20" name="id20">Documentation</a><ul>
+<li><a class="reference" href="#builtin-converters" id="id21" name="id21">Builtin Converters</a></li>
+<li><a class="reference" href="#internals" id="id22" name="id22">Internals</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#large-scale" id="id23" name="id23">Large Scale</a><ul>
+<li><a class="reference" href="#full-threading-support" id="id24" name="id24">Full Threading Support</a></li>
+<li><a class="reference" href="#langbinding" id="id25" name="id25">Langbinding</a></li>
+<li><a class="reference" href="#refactoring-and-reorganization" id="id26" name="id26">Refactoring and Reorganization</a></li>
+<li><a class="reference" href="#numarray-support-enhancements" id="id27" name="id27">NumArray Support Enhancements</a></li>
+<li><a class="reference" href="#pyfinalize-safety" id="id28" name="id28"><tt class="docutils literal"><span class="pre">PyFinalize</span></tt> Safety</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id4" id="class-support" name="class-support">Class Support</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id5" id="base-class-for-virtual-function-callback-wrappers" name="base-class-for-virtual-function-callback-wrappers">Base Class for Virtual Function Callback Wrappers</a></h2>
+<ul class="simple">
+<li><a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1456023">http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1456023</a>
+(bottom of message)</li>
+<li><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2003-August/005297.html">http://mail.python.org/pipermail/c++-sig/2003-August/005297.html</a>
+(search for <tt class="docutils literal"><span class="pre">VirtualDispatcher</span></tt>) describes how callback classes
+can swap ownership relationship with their Python wrappers.</li>
+<li><a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1860301">http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1860301</a>
+describes how this can also be used to considerably simplify
+callback classes, solve some &quot;dangling reference&quot; problems, and
+optimize the calling of non-overridden virtual functions.</li>
+</ul>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id6" id="miscellaneous" name="miscellaneous">Miscellaneous</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id7" id="support-for-enums-with-duplicate-values" name="support-for-enums-with-duplicate-values">Support for Enums with Duplicate Values</a></h2>
+<blockquote>
+Scott Snyder provided a patch; Dave was dissatisfied for some
+reason, but maybe it should just be applied if no further action
+occurs <a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1824616">http://aspn.activestate.com/ASPN/Mail/Message/1824616</a>.</blockquote>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id8" id="functions" name="functions">Functions</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id9" id="wrapping-function-objects" name="wrapping-function-objects">Wrapping Function Objects</a></h2>
+<blockquote>
+<p>It should be possible to wrap classes which support <tt class="docutils literal"><span class="pre">operator()</span></tt>
+as Python methods.</p>
+<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2003-August/005184.html">http://mail.python.org/pipermail/c++-sig/2003-August/005184.html</a></p>
+</blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id10" id="best-match-overload-resolution" name="best-match-overload-resolution">&quot;Best Match&quot; Overload Resolution</a></h2>
+<blockquote>
+<p>Overload resolution currently depends on the order in which <tt class="docutils literal"><span class="pre">def</span></tt>
+calls are made (preferring later overloads). This should be
+changed so that the best-matching overload is always selected.
+This may await <a class="reference" href="#langbinding">Langbinding</a> integration, since the technology is
+already in <a class="reference" href="http://luabind.sf.net">Luabind</a>.</p>
+</blockquote>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id11" id="type-converters" name="type-converters">Type Converters</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id12" id="lvalue-conversions-from-non-const-pytypeobject-s" name="lvalue-conversions-from-non-const-pytypeobject-s">Lvalue conversions from non-const <tt class="docutils literal"><span class="pre">PyTypeObject*</span></tt>s</a></h2>
+<blockquote>
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1662717">http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1662717</a></blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id13" id="converter-scoping" name="converter-scoping">Converter Scoping</a></h2>
+<blockquote>
+<p><a class="reference" href="http://article.gmane.org/gmane.comp.python.c++/2044">http://article.gmane.org/gmane.comp.python.c++/2044</a></p>
+<p>If this gets done at all, it is going to happen in conjunction
+with <a class="reference" href="#langbinding">Luabind integration</a>.</p>
+</blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id14" id="boost-tuple" name="boost-tuple"><tt class="docutils literal"><span class="pre">boost::tuple</span></tt></a></h2>
+<blockquote>
+Conversions to and from Python would be nice. See
+<a class="reference" href="http://news.gmane.org/find-root.php?message_id=%3cuvewak97m.fsf%40boost%2dconsulting.com%3e">http://news.gmane.org/find-root.php?message_id=%3cuvewak97m.fsf%40boost%2dconsulting.com%3e</a></blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id15" id="file-conversions" name="file-conversions"><tt class="docutils literal"><span class="pre">FILE*</span></tt> conversions</a></h2>
+<blockquote>
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1411366">http://aspn.activestate.com/ASPN/Mail/Message/1411366</a></blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id16" id="void-conversions" name="void-conversions"><tt class="docutils literal"><span class="pre">void*</span></tt> conversions</a></h2>
+<blockquote>
+Pointers to <em>cv</em> <tt class="docutils literal"><span class="pre">void</span></tt> should be able to be passed and
+returned as opaque values.</blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id17" id="post-call-actions" name="post-call-actions">Post-Call Actions</a></h2>
+<blockquote>
+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
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1755435">http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1755435</a></blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id18" id="pyunicode-support" name="pyunicode-support"><tt class="docutils literal"><span class="pre">PyUnicode</span></tt> Support</a></h2>
+<blockquote>
+<p>Review and possibly incorporate changes from <a class="reference" href="mailto:qinlj-at-solidshare.com">Lijun Qin</a> at
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1771145">http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1771145</a></p>
+</blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id19" id="ownership-metadata" name="ownership-metadata">Ownership Metadata</a></h2>
+<blockquote>
+In the thread at
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1860301">http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1860301</a>,
+Niall Douglas describes an idea for solving some &quot;false&quot;
+dangling pointer/reference return errors by attaching data about
+objects which lets the framework determine that the reference
+count on an object doesn't tell us anything about the lifetime
+of its data.</blockquote>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id20" id="documentation" name="documentation">Documentation</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id21" id="builtin-converters" name="builtin-converters">Builtin Converters</a></h2>
+<blockquote>
+Builtin correspondences between builtiin Python types and C++
+types need to be documented</blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id22" id="internals" name="internals">Internals</a></h2>
+<blockquote>
+<p>The structure of the framework needs to get documented; <a class="reference" href="mailto:brett.calcott-at-paradise.net.nz">Brett
+Calcott</a> has promised to turn <a class="reference" href="doc/internals.html">this document</a> into something fit
+for users</p>
+</blockquote>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id23" id="large-scale" name="large-scale">Large Scale</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id24" id="full-threading-support" name="full-threading-support">Full Threading Support</a></h2>
+<blockquote>
+Various people have proposed patches to improve threading support
+in Boost.Python: see the thread at
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1826544">http://aspn.activestate.com/ASPN/Mail/Message/1826544</a> and
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1865842">http://aspn.activestate.com/ASPN/Mail/Message/1865842</a> for some
+examples. The only problem is that these are incomplete
+solutions and verifying that we <em>do</em> have a complete solution is
+going to take some time and attention.</blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id25" id="langbinding" name="langbinding">Langbinding</a></h2>
+<blockquote>
+This project to generalizes Boost.Python to work for other
+languages, initially Lua. See discussions at
+<a class="reference" href="http://lists.sourceforge.net/lists/listinfo/boost-langbinding">http://lists.sourceforge.net/lists/listinfo/boost-langbinding</a></blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id26" id="refactoring-and-reorganization" name="refactoring-and-reorganization">Refactoring and Reorganization</a></h2>
+<blockquote>
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1673338">http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1673338</a></blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id27" id="numarray-support-enhancements" name="numarray-support-enhancements">NumArray Support Enhancements</a></h2>
+<blockquote>
+Consider integrating the enhancements described in
+<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1757092">http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1757092</a></blockquote>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id28" id="pyfinalize-safety" name="pyfinalize-safety"><tt class="docutils literal"><span class="pre">PyFinalize</span></tt> Safety</a></h2>
+<blockquote>
+<p>Currently Boost.Python has several global (or function-static)
+objects whose existence keeps reference counts from dropping to
+zero until the Boost.Python shared object is unloaded. This can
+cause a crash because when the reference counts <em>do</em> go to zero,
+there's no interpreter. In order to make it safe to call
+<tt class="docutils literal"><span class="pre">PyFinalize()</span></tt> we must register an <tt class="docutils literal"><span class="pre">atexit</span></tt> routine which
+destroys these objects and releases all Python reference counts
+so that Python can clean them up while there's still an
+interpreter. <a class="reference" href="mailto:dirk-at-gerrits.homeip.net">Dirk Gerrits</a> has promised to do this job.</p>
+</blockquote>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/libs/python/todo.txt b/libs/python/todo.txt
new file mode 100644
index 000000000..fb4f1c3c3
--- /dev/null
+++ b/libs/python/todo.txt
@@ -0,0 +1,206 @@
+.. -*- mode: rst -*-
+
+====================================
+ Boost.Python_ TODO list |(logo)|__
+====================================
+
+.. |(logo)| image:: ../../boost.png
+ :alt: Boost
+ :class: boost-logo
+
+__ ../../index.htm
+
+.. _`Boost.Python`: index.html
+
+:copyright: Copyright David Abrahams 2003. Use, modification, and
+ distribution are subject to the Boost Software License, Version
+ 1.0. (See accompanying file `LICENSE_1_0.txt`_ or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+
+.. contents:: Outline
+
+.. _`LICENSE_1_0.txt`: ../../LICENSE_1_0.txt
+
+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.
+
+* http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1860301
+ describes how this can also be used to considerably simplify
+ callback classes, solve some "dangling reference" problems, and
+ optimize the calling of non-overridden virtual functions.
+
+Miscellaneous
+=============
+
+Support for Enums with Duplicate Values
+---------------------------------------
+
+ Scott Snyder provided a patch; Dave was dissatisfied for some
+ reason, but maybe it should just be applied if no further action
+ occurs http://aspn.activestate.com/ASPN/Mail/Message/1824616.
+
+
+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
+
+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_
+
+
+``boost::tuple``
+----------------
+
+ Conversions to and from Python would be nice. See
+ http://news.gmane.org/find-root.php?message_id=%3cuvewak97m.fsf%40boost%2dconsulting.com%3e
+
+``FILE*`` conversions
+---------------------
+
+ http://aspn.activestate.com/ASPN/Mail/Message/1411366
+
+``void*`` conversions
+---------------------
+
+ Pointers to *cv* ``void`` should be able to be passed and
+ returned as opaque values.
+
+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
+
+Ownership Metadata
+------------------
+
+ In the thread at
+ http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1860301,
+ Niall Douglas describes an idea for solving some "false"
+ dangling pointer/reference return errors by attaching data about
+ objects which lets the framework determine that the reference
+ count on an object doesn't tell us anything about the lifetime
+ of its data.
+
+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
+===========
+
+Full Threading Support
+----------------------
+
+ Various people have proposed patches to improve threading support
+ in Boost.Python: see the thread at
+ http://aspn.activestate.com/ASPN/Mail/Message/1826544 and
+ http://aspn.activestate.com/ASPN/Mail/Message/1865842 for some
+ examples. The only problem is that these are incomplete
+ solutions and verifying that we *do* have a complete solution is
+ going to take some time and attention.
+
+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
+
+``PyFinalize`` Safety
+---------------------
+
+ Currently Boost.Python has several global (or function-static)
+ objects whose existence keeps reference counts from dropping to
+ zero until the Boost.Python shared object is unloaded. This can
+ cause a crash because when the reference counts *do* go to zero,
+ there's no interpreter. In order to make it safe to call
+ ``PyFinalize()`` we must register an ``atexit`` routine which
+ destroys these objects and releases all Python reference counts
+ so that Python can clean them up while there's still an
+ interpreter. `Dirk Gerrits`_ has promised to do this job.
+
+ .. _`Dirk Gerrits`: mailto:dirk-at-gerrits.homeip.net
+