summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/python
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/python
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/python')
-rw-r--r--src/boost/libs/python/Jamfile68
-rw-r--r--src/boost/libs/python/LICENSE_1_0.txt23
-rw-r--r--src/boost/libs/python/README.md60
-rw-r--r--src/boost/libs/python/build/Jamfile161
-rw-r--r--src/boost/libs/python/example/Jamroot35
-rw-r--r--src/boost/libs/python/example/README.md11
-rw-r--r--src/boost/libs/python/example/numpy/Jamfile29
-rw-r--r--src/boost/libs/python/example/numpy/demo_gaussian.py37
-rw-r--r--src/boost/libs/python/example/numpy/dtype.cpp49
-rw-r--r--src/boost/libs/python/example/numpy/fromdata.cpp48
-rw-r--r--src/boost/libs/python/example/numpy/gaussian.cpp315
-rw-r--r--src/boost/libs/python/example/numpy/ndarray.cpp71
-rw-r--r--src/boost/libs/python/example/numpy/simple.cpp32
-rw-r--r--src/boost/libs/python/example/numpy/ufunc.cpp86
-rw-r--r--src/boost/libs/python/example/numpy/wrap.cpp135
-rw-r--r--src/boost/libs/python/example/quickstart/Jamfile35
-rw-r--r--src/boost/libs/python/example/quickstart/embedding.cpp154
-rw-r--r--src/boost/libs/python/example/quickstart/extending.cpp41
-rw-r--r--src/boost/libs/python/example/quickstart/script.py7
-rw-r--r--src/boost/libs/python/example/quickstart/test_extending.py37
-rw-r--r--src/boost/libs/python/example/tutorial/Jamfile19
-rw-r--r--src/boost/libs/python/example/tutorial/hello.cpp20
-rwxr-xr-xsrc/boost/libs/python/example/tutorial/hello.py8
-rw-r--r--src/boost/libs/python/fabscript82
-rw-r--r--src/boost/libs/python/index.html13
-rw-r--r--src/boost/libs/python/meta/libraries.json14
-rw-r--r--src/boost/libs/python/src/converter/arg_to_python_base.cpp28
-rw-r--r--src/boost/libs/python/src/converter/builtin_converters.cpp592
-rw-r--r--src/boost/libs/python/src/converter/from_python.cpp303
-rw-r--r--src/boost/libs/python/src/converter/registry.cpp306
-rw-r--r--src/boost/libs/python/src/converter/type_id.cpp212
-rw-r--r--src/boost/libs/python/src/dict.cpp184
-rw-r--r--src/boost/libs/python/src/errors.cpp105
-rw-r--r--src/boost/libs/python/src/exec.cpp129
-rw-r--r--src/boost/libs/python/src/fabscript58
-rw-r--r--src/boost/libs/python/src/import.cpp25
-rw-r--r--src/boost/libs/python/src/list.cpp170
-rw-r--r--src/boost/libs/python/src/long.cpp39
-rw-r--r--src/boost/libs/python/src/module.cpp73
-rw-r--r--src/boost/libs/python/src/numpy/dtype.cpp220
-rw-r--r--src/boost/libs/python/src/numpy/matrix.cpp63
-rw-r--r--src/boost/libs/python/src/numpy/ndarray.cpp301
-rw-r--r--src/boost/libs/python/src/numpy/numpy.cpp34
-rw-r--r--src/boost/libs/python/src/numpy/scalars.cpp36
-rw-r--r--src/boost/libs/python/src/numpy/ufunc.cpp65
-rw-r--r--src/boost/libs/python/src/object/class.cpp764
-rw-r--r--src/boost/libs/python/src/object/enum.cpp252
-rw-r--r--src/boost/libs/python/src/object/function.cpp789
-rw-r--r--src/boost/libs/python/src/object/function_doc_signature.cpp344
-rw-r--r--src/boost/libs/python/src/object/inheritance.cpp495
-rw-r--r--src/boost/libs/python/src/object/iterator.cpp39
-rw-r--r--src/boost/libs/python/src/object/life_support.cpp121
-rw-r--r--src/boost/libs/python/src/object/pickle_support.cpp78
-rw-r--r--src/boost/libs/python/src/object/stl_iterator.cpp48
-rw-r--r--src/boost/libs/python/src/object_operators.cpp85
-rw-r--r--src/boost/libs/python/src/object_protocol.cpp197
-rw-r--r--src/boost/libs/python/src/slice.cpp37
-rw-r--r--src/boost/libs/python/src/str.cpp419
-rw-r--r--src/boost/libs/python/src/tuple.cpp35
-rw-r--r--src/boost/libs/python/src/wrapper.cpp66
-rw-r--r--src/boost/libs/python/test/Jamfile257
-rw-r--r--src/boost/libs/python/test/a_map_indexing_suite.cpp92
-rw-r--r--src/boost/libs/python/test/andreas_beyer.cpp61
-rw-r--r--src/boost/libs/python/test/andreas_beyer.py24
-rw-r--r--src/boost/libs/python/test/args.cpp99
-rw-r--r--src/boost/libs/python/test/args.py148
-rw-r--r--src/boost/libs/python/test/as_to_python_function.cpp13
-rw-r--r--src/boost/libs/python/test/auto_ptr.cpp90
-rw-r--r--src/boost/libs/python/test/auto_ptr.py100
-rw-r--r--src/boost/libs/python/test/back_reference.cpp112
-rw-r--r--src/boost/libs/python/test/back_reference.py37
-rw-r--r--src/boost/libs/python/test/bases.cpp62
-rw-r--r--src/boost/libs/python/test/ben_scott1.cpp54
-rw-r--r--src/boost/libs/python/test/ben_scott1.py17
-rw-r--r--src/boost/libs/python/test/bienstman1.cpp40
-rw-r--r--src/boost/libs/python/test/bienstman1.py23
-rw-r--r--src/boost/libs/python/test/bienstman2.cpp28
-rw-r--r--src/boost/libs/python/test/bienstman2.py20
-rw-r--r--src/boost/libs/python/test/bienstman3.cpp26
-rw-r--r--src/boost/libs/python/test/bienstman3.py30
-rw-r--r--src/boost/libs/python/test/bienstman4.cpp39
-rw-r--r--src/boost/libs/python/test/bienstman4.py23
-rw-r--r--src/boost/libs/python/test/bienstman5.cpp23
-rw-r--r--src/boost/libs/python/test/bienstman5.py21
-rw-r--r--src/boost/libs/python/test/boost_shared_ptr.cpp20
-rw-r--r--src/boost/libs/python/test/boost_shared_ptr.py130
-rw-r--r--src/boost/libs/python/test/borrowed.cpp33
-rw-r--r--src/boost/libs/python/test/builtin_converters.cpp152
-rw-r--r--src/boost/libs/python/test/callbacks.cpp150
-rw-r--r--src/boost/libs/python/test/callbacks.py147
-rw-r--r--src/boost/libs/python/test/calling_conventions.cpp160
-rw-r--r--src/boost/libs/python/test/calling_conventions.py81
-rw-r--r--src/boost/libs/python/test/calling_conventions_mf.cpp161
-rw-r--r--src/boost/libs/python/test/calling_conventions_mf.py84
-rw-r--r--src/boost/libs/python/test/class.cpp28
-rw-r--r--src/boost/libs/python/test/class.py40
-rw-r--r--src/boost/libs/python/test/cltree.cpp74
-rw-r--r--src/boost/libs/python/test/complicated.hpp38
-rw-r--r--src/boost/libs/python/test/const_argument.cpp28
-rw-r--r--src/boost/libs/python/test/const_argument.py23
-rw-r--r--src/boost/libs/python/test/copy_ctor_mutates_rhs.cpp23
-rw-r--r--src/boost/libs/python/test/crossmod_exception.py19
-rw-r--r--src/boost/libs/python/test/crossmod_exception_a.cpp18
-rw-r--r--src/boost/libs/python/test/crossmod_exception_b.cpp18
-rw-r--r--src/boost/libs/python/test/crossmod_opaque.py16
-rw-r--r--src/boost/libs/python/test/crossmod_opaque_a.cpp26
-rw-r--r--src/boost/libs/python/test/crossmod_opaque_b.cpp26
-rw-r--r--src/boost/libs/python/test/data_members.cpp132
-rw-r--r--src/boost/libs/python/test/data_members.py215
-rw-r--r--src/boost/libs/python/test/defaults.cpp173
-rw-r--r--src/boost/libs/python/test/defaults.py140
-rw-r--r--src/boost/libs/python/test/destroy_test.cpp58
-rw-r--r--src/boost/libs/python/test/dict.cpp91
-rw-r--r--src/boost/libs/python/test/dict.py46
-rw-r--r--src/boost/libs/python/test/docstring.cpp116
-rw-r--r--src/boost/libs/python/test/docstring.py153
-rw-r--r--src/boost/libs/python/test/enable_shared_from_this.cpp48
-rw-r--r--src/boost/libs/python/test/enable_shared_from_this.py26
-rw-r--r--src/boost/libs/python/test/enum_ext.cpp55
-rw-r--r--src/boost/libs/python/test/exception_translator.cpp28
-rw-r--r--src/boost/libs/python/test/exception_translator.py27
-rw-r--r--src/boost/libs/python/test/exec.cpp197
-rw-r--r--src/boost/libs/python/test/exec.py6
-rw-r--r--src/boost/libs/python/test/extract.cpp143
-rw-r--r--src/boost/libs/python/test/extract.py107
-rw-r--r--src/boost/libs/python/test/fabscript173
-rw-r--r--src/boost/libs/python/test/if_else.cpp44
-rw-r--r--src/boost/libs/python/test/implicit.cpp48
-rw-r--r--src/boost/libs/python/test/implicit.py44
-rw-r--r--src/boost/libs/python/test/import_.cpp70
-rw-r--r--src/boost/libs/python/test/import_.py5
-rw-r--r--src/boost/libs/python/test/indirect_traits_test.cpp116
-rw-r--r--src/boost/libs/python/test/injected.cpp39
-rw-r--r--src/boost/libs/python/test/injected.py28
-rw-r--r--src/boost/libs/python/test/input_iterator.cpp48
-rw-r--r--src/boost/libs/python/test/int_map_indexing_suite.cpp16
-rw-r--r--src/boost/libs/python/test/iterator.cpp137
-rw-r--r--src/boost/libs/python/test/iterator.py78
-rw-r--r--src/boost/libs/python/test/keywords.cpp118
-rw-r--r--src/boost/libs/python/test/keywords_test.py106
-rw-r--r--src/boost/libs/python/test/list.cpp154
-rw-r--r--src/boost/libs/python/test/list.py119
-rw-r--r--src/boost/libs/python/test/long.cpp63
-rw-r--r--src/boost/libs/python/test/long.py36
-rw-r--r--src/boost/libs/python/test/m1.cpp344
-rw-r--r--src/boost/libs/python/test/m2.cpp108
-rw-r--r--src/boost/libs/python/test/map_indexing_suite.cpp68
-rw-r--r--src/boost/libs/python/test/map_indexing_suite.py243
-rw-r--r--src/boost/libs/python/test/minimal.cpp16
-rw-r--r--src/boost/libs/python/test/minimal.py7
-rw-r--r--src/boost/libs/python/test/module_tail.cpp58
-rw-r--r--src/boost/libs/python/test/multi_arg_constructor.cpp27
-rw-r--r--src/boost/libs/python/test/multi_arg_constructor.py21
-rw-r--r--src/boost/libs/python/test/nested.cpp51
-rw-r--r--src/boost/libs/python/test/nested.py40
-rw-r--r--src/boost/libs/python/test/newtest.py206
-rw-r--r--src/boost/libs/python/test/numpy/dtype.cpp49
-rw-r--r--src/boost/libs/python/test/numpy/dtype.py63
-rw-r--r--src/boost/libs/python/test/numpy/indexing.cpp28
-rw-r--r--src/boost/libs/python/test/numpy/indexing.py55
-rw-r--r--src/boost/libs/python/test/numpy/ndarray.cpp51
-rw-r--r--src/boost/libs/python/test/numpy/ndarray.py112
-rw-r--r--src/boost/libs/python/test/numpy/shapes.cpp22
-rw-r--r--src/boost/libs/python/test/numpy/shapes.py21
-rw-r--r--src/boost/libs/python/test/numpy/templates.cpp63
-rwxr-xr-xsrc/boost/libs/python/test/numpy/templates.py28
-rw-r--r--src/boost/libs/python/test/numpy/ufunc.cpp36
-rwxr-xr-xsrc/boost/libs/python/test/numpy/ufunc.py57
-rw-r--r--src/boost/libs/python/test/object.cpp392
-rw-r--r--src/boost/libs/python/test/object.py180
-rw-r--r--src/boost/libs/python/test/object_fail1.cpp11
-rw-r--r--src/boost/libs/python/test/object_manager.cpp33
-rw-r--r--src/boost/libs/python/test/opaque.cpp76
-rw-r--r--src/boost/libs/python/test/opaque.py87
-rw-r--r--src/boost/libs/python/test/operators.cpp175
-rw-r--r--src/boost/libs/python/test/operators.py102
-rw-r--r--src/boost/libs/python/test/operators_wrapper.cpp42
-rw-r--r--src/boost/libs/python/test/operators_wrapper.py11
-rw-r--r--src/boost/libs/python/test/pickle1.cpp62
-rw-r--r--src/boost/libs/python/test/pickle1.py41
-rw-r--r--src/boost/libs/python/test/pickle2.cpp97
-rw-r--r--src/boost/libs/python/test/pickle2.py51
-rw-r--r--src/boost/libs/python/test/pickle3.cpp107
-rw-r--r--src/boost/libs/python/test/pickle3.py46
-rw-r--r--src/boost/libs/python/test/pickle4.cpp44
-rw-r--r--src/boost/libs/python/test/pickle4.py39
-rw-r--r--src/boost/libs/python/test/pointee.cpp34
-rw-r--r--src/boost/libs/python/test/pointer_type_id_test.cpp43
-rw-r--r--src/boost/libs/python/test/pointer_vector.cpp52
-rw-r--r--src/boost/libs/python/test/pointer_vector.py31
-rw-r--r--src/boost/libs/python/test/polymorphism.cpp162
-rw-r--r--src/boost/libs/python/test/polymorphism.py74
-rw-r--r--src/boost/libs/python/test/polymorphism2.cpp172
-rw-r--r--src/boost/libs/python/test/polymorphism2.py94
-rw-r--r--src/boost/libs/python/test/polymorphism2_auto_ptr.cpp6
-rw-r--r--src/boost/libs/python/test/polymorphism2_auto_ptr.py5
-rw-r--r--src/boost/libs/python/test/properties.cpp100
-rw-r--r--src/boost/libs/python/test/properties.py106
-rw-r--r--src/boost/libs/python/test/pyrun.py7
-rw-r--r--src/boost/libs/python/test/pytype_function.cpp85
-rw-r--r--src/boost/libs/python/test/pytype_function.py32
-rw-r--r--src/boost/libs/python/test/raw_ctor.cpp43
-rw-r--r--src/boost/libs/python/test/raw_ctor.py76
-rw-r--r--src/boost/libs/python/test/raw_pyobject_fail1.cpp11
-rw-r--r--src/boost/libs/python/test/raw_pyobject_fail2.cpp13
-rw-r--r--src/boost/libs/python/test/register_ptr.cpp55
-rw-r--r--src/boost/libs/python/test/register_ptr_test.py25
-rw-r--r--src/boost/libs/python/test/result.cpp111
-rw-r--r--src/boost/libs/python/test/return_arg.cpp67
-rw-r--r--src/boost/libs/python/test/return_arg.py27
-rw-r--r--src/boost/libs/python/test/select_arg_to_python_test.cpp70
-rw-r--r--src/boost/libs/python/test/select_from_python_test.cpp161
-rw-r--r--src/boost/libs/python/test/select_holder.cpp76
-rw-r--r--src/boost/libs/python/test/shared_ptr.cpp19
-rw-r--r--src/boost/libs/python/test/shared_ptr.hpp206
-rw-r--r--src/boost/libs/python/test/shared_ptr.py130
-rw-r--r--src/boost/libs/python/test/simple_type.hpp13
-rw-r--r--src/boost/libs/python/test/slice.cpp98
-rw-r--r--src/boost/libs/python/test/slice.py54
-rw-r--r--src/boost/libs/python/test/staticmethod.cpp48
-rw-r--r--src/boost/libs/python/test/staticmethod.py57
-rw-r--r--src/boost/libs/python/test/stl_iterator.cpp33
-rw-r--r--src/boost/libs/python/test/stl_iterator.py39
-rw-r--r--src/boost/libs/python/test/str.cpp84
-rw-r--r--src/boost/libs/python/test/str.py54
-rw-r--r--src/boost/libs/python/test/string_literal.cpp42
-rw-r--r--src/boost/libs/python/test/test_builtin_converters.py312
-rw-r--r--src/boost/libs/python/test/test_class.hpp32
-rw-r--r--src/boost/libs/python/test/test_cltree.py43
-rw-r--r--src/boost/libs/python/test/test_enum.py85
-rw-r--r--src/boost/libs/python/test/test_overload_resolution.cpp53
-rw-r--r--src/boost/libs/python/test/test_pointer_adoption.cpp125
-rw-r--r--src/boost/libs/python/test/test_pointer_adoption.py93
-rw-r--r--src/boost/libs/python/test/tuple.cpp33
-rw-r--r--src/boost/libs/python/test/tuple.py38
-rw-r--r--src/boost/libs/python/test/upcast.cpp19
-rw-r--r--src/boost/libs/python/test/vector_indexing_suite.cpp62
-rw-r--r--src/boost/libs/python/test/vector_indexing_suite.py370
-rw-r--r--src/boost/libs/python/test/virtual_functions.cpp125
-rw-r--r--src/boost/libs/python/test/virtual_functions.py110
-rw-r--r--src/boost/libs/python/test/voidptr.cpp43
-rw-r--r--src/boost/libs/python/test/voidptr.py54
-rw-r--r--src/boost/libs/python/test/wrapper_held_type.cpp69
-rw-r--r--src/boost/libs/python/test/wrapper_held_type.py34
-rw-r--r--src/boost/libs/python/todo.txt206
245 files changed, 22330 insertions, 0 deletions
diff --git a/src/boost/libs/python/Jamfile b/src/boost/libs/python/Jamfile
new file mode 100644
index 000000000..32e87d80f
--- /dev/null
+++ b/src/boost/libs/python/Jamfile
@@ -0,0 +1,68 @@
+# Copyright (c) 2018 Stefan Seefeld
+# All rights reserved.
+#
+# Distributed under the 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 option ;
+import regex ;
+import python ;
+
+#
+# The `version-suffix` rule really belongs into python.jam, and
+# should be moved there. `split-version` is only duplicated here
+# as a prerequisite. (See https://github.com/boostorg/build/pull/290)
+#
+
+
+# Validate the version string and extract the major/minor part we care about.
+#
+local rule split-version ( version )
+{
+ local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)(.*)$" : $(version) : 1 2 3 ] ;
+ if ! $(major-minor[2]) || $(major-minor[3])
+ {
+ ECHO "Warning: \"using python\" expects a two part (major, minor) version number; got" $(version) instead ;
+
+ # Add a zero to account for the missing digit if necessary.
+ major-minor += 0 ;
+ }
+
+ return $(major-minor[1]) $(major-minor[2]) ;
+}
+
+# Define a version suffix for libraries depending on Python.
+# For example, Boost.Python built for Python 2.7 uses the suffix "27"
+rule version-suffix ( version )
+{
+ local major-minor = [ split-version $(version) ] ;
+ local suffix = $(major-minor:J="") ;
+ return $(suffix) ;
+}
+
+
+# Python build id (for Python libraries only).
+python-id = [ option.get "python-buildid" ] ;
+if $(python-id)
+{
+ PYTHON_ID = [ regex.replace $(python-id) "[*\\/:.\"\']" _ ] ;
+}
+
+rule python-tag ( name : type ? : property-set )
+{
+ local result = $(name) ;
+ if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
+ {
+ local version = [ $(property-set).get <python> ] ;
+ local lib-suffix = [ version-suffix $(version) ] ;
+ result = $(result)$(lib-suffix) ;
+ }
+ if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB && $(PYTHON_ID)
+ {
+ result = $(result)-$(PYTHON_ID) ;
+ }
+
+ # forward to the boost tagging rule
+ return [ tag $(result) : $(type) : $(property-set) ] ;
+}
diff --git a/src/boost/libs/python/LICENSE_1_0.txt b/src/boost/libs/python/LICENSE_1_0.txt
new file mode 100644
index 000000000..36b7cd93c
--- /dev/null
+++ b/src/boost/libs/python/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/src/boost/libs/python/README.md b/src/boost/libs/python/README.md
new file mode 100644
index 000000000..7646d3a87
--- /dev/null
+++ b/src/boost/libs/python/README.md
@@ -0,0 +1,60 @@
+![logo](https://raw.githubusercontent.com/boostorg/python/develop/doc/images/bpl.png)
+
+# Synopsis
+
+[![Join the chat at https://gitter.im/boostorg/python](https://badges.gitter.im/boostorg/python.svg)](https://gitter.im/boostorg/python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+Welcome to Boost.Python, a C++ library which enables seamless interoperability between C++ and the Python programming language. The library includes support for:
+
+* References and Pointers
+* Globally Registered Type Coercions
+* Automatic Cross-Module Type Conversions
+* Efficient Function Overloading
+* C++ to Python Exception Translation
+* Default Arguments
+* Keyword Arguments
+* Manipulating Python objects in C++
+* Exporting C++ Iterators as Python Iterators
+* Documentation Strings
+
+See the [Boost.Python](http://boostorg.github.io/python) documentation for details.
+
+**Hint :** Check out the [development version](http://boostorg.github.io/python/develop) of the documentation to see work in progress.
+
+# Building [![Build Status](https://travis-ci.org/boostorg/python.svg?branch=develop)](https://travis-ci.org/boostorg/python) [![Build status](https://ci.appveyor.com/api/projects/status/cgx9xma6v3gjav92/branch/develop?svg=true)](https://ci.appveyor.com/project/stefanseefeld/python/branch/develop)
+
+
+While Boost.Python is part of the Boost C++ Libraries super-project, and thus can be compiled as part of Boost, it can also be compiled and installed stand-alone, i.e. against a pre-installed Boost package.
+
+## Prerequisites
+
+* [Python](http://www.python.org)
+* [Boost](http://www.boost.org)
+* [Faber](https://stefanseefeld.github.io/faber)
+
+## Build
+
+Run
+
+```
+faber
+```
+to build the library.
+
+## Test
+
+Run
+
+```
+faber test.report
+```
+to run the tests.
+
+## Build docs
+
+Run
+
+```
+faber doc.html
+```
+to build the documentation.
diff --git a/src/boost/libs/python/build/Jamfile b/src/boost/libs/python/build/Jamfile
new file mode 100644
index 000000000..34f99dde7
--- /dev/null
+++ b/src/boost/libs/python/build/Jamfile
@@ -0,0 +1,161 @@
+# 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 property ;
+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"
+ ;
+}
+
+if [ python.configured ]
+{
+project boost/python
+ : source-location ../src
+ ;
+
+rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
+rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
+local rule eq ( a : b ) { if $(a) = $(b) { return 1 ; } }
+
+lib boost_python
+ : # sources
+ 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
+ -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
+ <tag>@$(__name__).python-tag
+ <conditional>@python.require-py
+
+ : # default build
+ <link>shared
+ : # usage requirements
+ <link>static:<define>BOOST_PYTHON_STATIC_LIB
+ <python-debugging>on:<define>BOOST_DEBUG_PYTHON
+ ;
+
+numpy-include = [ python.numpy-include ] ;
+lib boost_numpy
+ : # sources
+ numpy/dtype.cpp
+ numpy/matrix.cpp
+ numpy/ndarray.cpp
+ numpy/numpy.cpp
+ numpy/scalars.cpp
+ numpy/ufunc.cpp
+ : # requirements
+ <link>static:<define>BOOST_NUMPY_STATIC_LIB
+ <define>BOOST_NUMPY_SOURCE
+ [ cond [ python.numpy ] : <library>/python//python_for_extensions ]
+ [ unless [ python.numpy ] : <build>no ]
+ <include>$(numpy-include)
+ <library>boost_python
+ <python-debugging>on:<define>BOOST_DEBUG_PYTHON
+ -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
+ <tag>@$(__name__).python-tag
+ <conditional>@python.require-py
+
+ : # default build
+ <link>shared
+ : # usage requirements
+ <link>static:<define>BOOST_NUMPY_STATIC_LIB
+ <python-debugging>on:<define>BOOST_DEBUG_PYTHON
+ ;
+
+# boost-install creates `stage` and `install` targets
+#
+# `stage` stages (builds and copies into `stage/lib`) the given libraries
+# `boost_python` and `boost_numpy` and their dependencies and is similar
+# to issuing `b2 --with-python stage` from top level
+#
+# `install` installs the two libraries and their dependencies and is similar
+# to issuing `b2 --with-python install` from top level
+
+boost-install boost_python boost_numpy ;
+
+}
+else
+{
+
+# When Python isn't configured, the above `boost-install` is not executed,
+# so we create empty `stage` and `install` targets that do nothing but issue
+# a warning message unless `--without-python` is given
+
+alias stage : config-warning ;
+explicit stage ;
+
+alias install : config-warning ;
+explicit install ;
+
+}
diff --git a/src/boost/libs/python/example/Jamroot b/src/boost/libs/python/example/Jamroot
new file mode 100644
index 000000000..fe9d69ecc
--- /dev/null
+++ b/src/boost/libs/python/example/Jamroot
@@ -0,0 +1,35 @@
+# Copyright Stefan Seefeld 2016.
+# Distributed under the 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 "warning: no Python configured in user-config.jam" ;
+ ECHO "warning: will use default configuration" ;
+ using python ;
+}
+
+# Adjust the following if Boost.Python isn't installed in a default location
+lib boost_python ;
+
+project
+ : requirements
+# <include>/path/to/boost/python
+ <library>boost_python
+;
+
+rule run-test ( test-name : sources + )
+{
+ import testing ;
+ testing.make-test run-pyd : $(sources) : : $(test-name) ;
+}
+
+build-project quickstart ;
+build-project tutorial ;
+if [ python.numpy ]
+{
+ build-project numpy ;
+}
diff --git a/src/boost/libs/python/example/README.md b/src/boost/libs/python/example/README.md
new file mode 100644
index 000000000..b090cbe1e
--- /dev/null
+++ b/src/boost/libs/python/example/README.md
@@ -0,0 +1,11 @@
+![logo](https://raw.githubusercontent.com/boostorg/python/develop/doc/images/bpl.png)
+
+# Examples
+
+This directory contains various examples using Boost.Python.
+You may compile these using the `bjam` command either in this directory
+or in any of the subdirectories.
+You may need to adjust the paths in the Jamroot file if Boost.Python
+is not installed in a default location.
+See http://boostorg.github.io/python/doc/html/building/no_install_quickstart.html
+for details.
diff --git a/src/boost/libs/python/example/numpy/Jamfile b/src/boost/libs/python/example/numpy/Jamfile
new file mode 100644
index 000000000..ac70a6ff0
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/Jamfile
@@ -0,0 +1,29 @@
+# Copyright Stefan Seefeld 2016.
+# Distributed under the 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 ;
+
+# Adjust the following if Boost.Python isn't installed in a default location
+lib boost_numpy
+ :
+ : <search>/usr/local/Boost/lib
+ <include>/usr/local/Boost/include
+ ;
+
+project numpy
+ : requirements
+ <include>/usr/local/Boost/include
+ <library>boost_numpy
+ <location>.
+ ;
+
+exe simple : simple.cpp boost_numpy /python//python ;
+exe dtype : dtype.cpp boost_numpy /python//python ;
+exe ndarray : ndarray.cpp /python//python ;
+exe fromdata : fromdata.cpp /python//python ;
+exe ufunc : ufunc.cpp /python//python ;
+exe wrap : wrap.cpp /python//python ;
+
+python-extension gaussian : gaussian.cpp ;
diff --git a/src/boost/libs/python/example/numpy/demo_gaussian.py b/src/boost/libs/python/example/numpy/demo_gaussian.py
new file mode 100644
index 000000000..0b1c78995
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/demo_gaussian.py
@@ -0,0 +1,37 @@
+# Copyright Jim Bosch 2010-2012.
+# Distributed under the 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 numpy
+import gaussian
+
+mu = numpy.zeros(2, dtype=float)
+sigma = numpy.identity(2, dtype=float)
+sigma[0, 1] = 0.15
+sigma[1, 0] = 0.15
+
+g = gaussian.bivariate_gaussian(mu, sigma)
+
+r = numpy.linspace(-40, 40, 1001)
+x, y = numpy.meshgrid(r, r)
+
+z = g(x, y)
+
+s = z.sum() * (r[1] - r[0])**2
+print "sum (should be ~ 1):", s
+
+xc = (z * x).sum() / z.sum()
+print "x centroid (should be ~ %f): %f" % (mu[0], xc)
+
+yc = (z * y).sum() / z.sum()
+print "y centroid (should be ~ %f): %f" % (mu[1], yc)
+
+xx = (z * (x - xc)**2).sum() / z.sum()
+print "xx moment (should be ~ %f): %f" % (sigma[0,0], xx)
+
+yy = (z * (y - yc)**2).sum() / z.sum()
+print "yy moment (should be ~ %f): %f" % (sigma[1,1], yy)
+
+xy = 0.5 * (z * (x - xc) * (y - yc)).sum() / z.sum()
+print "xy moment (should be ~ %f): %f" % (sigma[0,1], xy)
diff --git a/src/boost/libs/python/example/numpy/dtype.cpp b/src/boost/libs/python/example/numpy/dtype.cpp
new file mode 100644
index 000000000..749a36b5e
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/dtype.cpp
@@ -0,0 +1,49 @@
+// Copyright Ankit Daftery 2011-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * @brief An example to show how to create ndarrays with built-in python data types, and extract
+ * the types and values of member variables
+ *
+ * @todo Add an example to show type conversion.
+ * Add an example to show use of user-defined types
+ *
+ */
+
+#include <boost/python/numpy.hpp>
+#include <iostream>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+int main(int argc, char **argv)
+{
+ // Initialize the Python runtime.
+ Py_Initialize();
+ // Initialize NumPy
+ np::initialize();
+ // Create a 3x3 shape...
+ p::tuple shape = p::make_tuple(3, 3);
+ // ...as well as a type for C++ double
+ np::dtype dtype = np::dtype::get_builtin<double>();
+ // Construct an array with the above shape and type
+ np::ndarray a = np::zeros(shape, dtype);
+ // Print the array
+ std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
+ // Print the datatype of the elements
+ std::cout << "Datatype is:\n" << p::extract<char const *>(p::str(a.get_dtype())) << std::endl ;
+ // Using user defined dtypes to create dtype and an array of the custom dtype
+ // First create a tuple with a variable name and its dtype, double, to create a custom dtype
+ p::tuple for_custom_dtype = p::make_tuple("ha",dtype) ;
+ // The list needs to be created, because the constructor to create the custom dtype
+ // takes a list of (variable,variable_type) as an argument
+ p::list list_for_dtype ;
+ list_for_dtype.append(for_custom_dtype) ;
+ // Create the custom dtype
+ np::dtype custom_dtype = np::dtype(list_for_dtype) ;
+ // Create an ndarray with the custom dtype
+ np::ndarray new_array = np::zeros(shape,custom_dtype);
+
+}
diff --git a/src/boost/libs/python/example/numpy/fromdata.cpp b/src/boost/libs/python/example/numpy/fromdata.cpp
new file mode 100644
index 000000000..bd073cc69
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/fromdata.cpp
@@ -0,0 +1,48 @@
+// Copyright Ankit Daftery 2011-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * @brief An example to show how to access data using raw pointers. This shows that you can use and
+ * manipulate data in either Python or C++ and have the changes reflected in both.
+ */
+
+#include <boost/python/numpy.hpp>
+#include <iostream>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+
+int main(int argc, char **argv)
+{
+ // Initialize the Python runtime.
+ Py_Initialize();
+ // Initialize NumPy
+ np::initialize();
+ // Create an array in C++
+ int arr[] = {1,2,3,4} ;
+ // Create the ndarray in Python
+ np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
+ // Print the ndarray that we just created, and the source C++ array
+ std::cout << "C++ array :" << std::endl ;
+ for (int j=0;j<4;j++)
+ {
+ std::cout << arr[j] << ' ' ;
+ }
+ std::cout << std::endl << "Python ndarray :" << p::extract<char const *>(p::str(py_array)) << std::endl;
+ // Change an element in the python ndarray
+ py_array[1] = 5 ;
+ // And see if the C++ container is changed or not
+ std::cout << "Is the change reflected in the C++ array used to create the ndarray ? " << std::endl ;
+ for (int j = 0;j<4 ; j++)
+ {
+ std::cout << arr[j] << ' ' ;
+ }
+ // Conversely, change it in C++
+ arr[2] = 8 ;
+ // And see if the changes are reflected in the Python ndarray
+ std::cout << std::endl << "Is the change reflected in the Python ndarray ?" << std::endl << p::extract<char const *>(p::str(py_array)) << std::endl;
+
+}
diff --git a/src/boost/libs/python/example/numpy/gaussian.cpp b/src/boost/libs/python/example/numpy/gaussian.cpp
new file mode 100644
index 000000000..5f138b397
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/gaussian.cpp
@@ -0,0 +1,315 @@
+// Copyright Jim Bosch 2010-2012.
+// Distributed under the 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/numpy.hpp>
+
+#include <cmath>
+#include <memory>
+
+#ifndef M_PI
+#include <boost/math/constants/constants.hpp>
+const double M_PI = boost::math::constants::pi<double>();
+#endif
+
+namespace bp = boost::python;
+namespace bn = boost::python::numpy;
+
+/**
+ * A 2x2 matrix class, purely for demonstration purposes.
+ *
+ * Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
+ */
+class matrix2 {
+public:
+
+ double & operator()(int i, int j) {
+ return _data[i*2 + j];
+ }
+
+ double const & operator()(int i, int j) const {
+ return _data[i*2 + j];
+ }
+
+ double const * data() const { return _data; }
+
+private:
+ double _data[4];
+};
+
+/**
+ * A 2-element vector class, purely for demonstration purposes.
+ *
+ * Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
+ */
+class vector2 {
+public:
+
+ double & operator[](int i) {
+ return _data[i];
+ }
+
+ double const & operator[](int i) const {
+ return _data[i];
+ }
+
+ double const * data() const { return _data; }
+
+ vector2 operator+(vector2 const & other) const {
+ vector2 r;
+ r[0] = _data[0] + other[0];
+ r[1] = _data[1] + other[1];
+ return r;
+ }
+
+ vector2 operator-(vector2 const & other) const {
+ vector2 r;
+ r[0] = _data[0] - other[0];
+ r[1] = _data[1] - other[1];
+ return r;
+ }
+
+private:
+ double _data[2];
+};
+
+/**
+ * Matrix-vector multiplication.
+ */
+vector2 operator*(matrix2 const & m, vector2 const & v) {
+ vector2 r;
+ r[0] = m(0, 0) * v[0] + m(0, 1) * v[1];
+ r[1] = m(1, 0) * v[0] + m(1, 1) * v[1];
+ return r;
+}
+
+/**
+ * Vector inner product.
+ */
+double dot(vector2 const & v1, vector2 const & v2) {
+ return v1[0] * v2[0] + v1[1] * v2[1];
+}
+
+/**
+ * This class represents a simple 2-d Gaussian (Normal) distribution, defined by a
+ * mean vector 'mu' and a covariance matrix 'sigma'.
+ */
+class bivariate_gaussian {
+public:
+
+ vector2 const & get_mu() const { return _mu; }
+
+ matrix2 const & get_sigma() const { return _sigma; }
+
+ /**
+ * Evaluate the density of the distribution at a point defined by a two-element vector.
+ */
+ double operator()(vector2 const & p) const {
+ vector2 u = _cholesky * (p - _mu);
+ return 0.5 * _cholesky(0, 0) * _cholesky(1, 1) * std::exp(-0.5 * dot(u, u)) / M_PI;
+ }
+
+ /**
+ * Evaluate the density of the distribution at an (x, y) point.
+ */
+ double operator()(double x, double y) const {
+ vector2 p;
+ p[0] = x;
+ p[1] = y;
+ return operator()(p);
+ }
+
+ /**
+ * Construct from a mean vector and covariance matrix.
+ */
+ bivariate_gaussian(vector2 const & mu, matrix2 const & sigma)
+ : _mu(mu), _sigma(sigma), _cholesky(compute_inverse_cholesky(sigma))
+ {}
+
+private:
+
+ /**
+ * This evaluates the inverse of the Cholesky factorization of a 2x2 matrix;
+ * it's just a shortcut in evaluating the density.
+ */
+ static matrix2 compute_inverse_cholesky(matrix2 const & m) {
+ matrix2 l;
+ // First do cholesky factorization: l l^t = m
+ l(0, 0) = std::sqrt(m(0, 0));
+ l(0, 1) = m(0, 1) / l(0, 0);
+ l(1, 1) = std::sqrt(m(1, 1) - l(0,1) * l(0,1));
+ // Now do forward-substitution (in-place) to invert:
+ l(0, 0) = 1.0 / l(0, 0);
+ l(1, 0) = l(0, 1) = -l(0, 1) / l(1, 1);
+ l(1, 1) = 1.0 / l(1, 1);
+ return l;
+ }
+
+ vector2 _mu;
+ matrix2 _sigma;
+ matrix2 _cholesky;
+
+};
+
+/*
+ * We have a two options for wrapping get_mu and get_sigma into NumPy-returning Python methods:
+ * - we could deep-copy the data, making totally new NumPy arrays;
+ * - we could make NumPy arrays that point into the existing memory.
+ * The latter is often preferable, especially if the arrays are large, but it's dangerous unless
+ * the reference counting is correct: the returned NumPy array needs to hold a reference that
+ * keeps the memory it points to from being deallocated as long as it is alive. This is what the
+ * "owner" argument to from_data does - the NumPy array holds a reference to the owner, keeping it
+ * from being destroyed.
+ *
+ * Note that this mechanism isn't completely safe for data members that can have their internal
+ * storage reallocated. A std::vector, for instance, can be invalidated when it is resized,
+ * so holding a Python reference to a C++ class that holds a std::vector may not be a guarantee
+ * that the memory in the std::vector will remain valid.
+ */
+
+/**
+ * These two functions are custom wrappers for get_mu and get_sigma, providing the shallow-copy
+ * conversion with reference counting described above.
+ *
+ * It's also worth noting that these return NumPy arrays that cannot be modified in Python;
+ * the const overloads of vector::data() and matrix::data() return const references,
+ * and passing a const pointer to from_data causes NumPy's 'writeable' flag to be set to false.
+ */
+static bn::ndarray py_get_mu(bp::object const & self) {
+ vector2 const & mu = bp::extract<bivariate_gaussian const &>(self)().get_mu();
+ return bn::from_data(
+ mu.data(),
+ bn::dtype::get_builtin<double>(),
+ bp::make_tuple(2),
+ bp::make_tuple(sizeof(double)),
+ self
+ );
+}
+static bn::ndarray py_get_sigma(bp::object const & self) {
+ matrix2 const & sigma = bp::extract<bivariate_gaussian const &>(self)().get_sigma();
+ return bn::from_data(
+ sigma.data(),
+ bn::dtype::get_builtin<double>(),
+ bp::make_tuple(2, 2),
+ bp::make_tuple(2 * sizeof(double), sizeof(double)),
+ self
+ );
+}
+
+/**
+ * To allow the constructor to work, we need to define some from-Python converters from NumPy arrays
+ * to the matrix/vector types. The rvalue-from-python functionality is not well-documented in Boost.Python
+ * itself; you can learn more from boost/python/converter/rvalue_from_python_data.hpp.
+ */
+
+/**
+ * We start with two functions that just copy a NumPy array into matrix/vector objects. These will be used
+ * in the templated converted below. The first just uses the operator[] overloads provided by
+ * bp::object.
+ */
+static void copy_ndarray_to_mv2(bn::ndarray const & array, vector2 & vec) {
+ vec[0] = bp::extract<double>(array[0]);
+ vec[1] = bp::extract<double>(array[1]);
+}
+
+/**
+ * Here, we'll take the alternate approach of using the strides to access the array's memory directly.
+ * This can be much faster for large arrays.
+ */
+static void copy_ndarray_to_mv2(bn::ndarray const & array, matrix2 & mat) {
+ // Unfortunately, get_strides() can't be inlined, so it's best to call it once up-front.
+ Py_intptr_t const * strides = array.get_strides();
+ for (int i = 0; i < 2; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ mat(i, j) = *reinterpret_cast<double const *>(array.get_data() + i * strides[0] + j * strides[1]);
+ }
+ }
+}
+
+/**
+ * Here's the actual converter. Because we've separated the differences into the above functions,
+ * we can write a single template class that works for both matrix2 and vector2.
+ */
+template <typename T, int N>
+struct mv2_from_python {
+
+ /**
+ * Register the converter.
+ */
+ mv2_from_python() {
+ bp::converter::registry::push_back(
+ &convertible,
+ &construct,
+ bp::type_id< T >()
+ );
+ }
+
+ /**
+ * Test to see if we can convert this to the desired type; if not return zero.
+ * If we can convert, returned pointer can be used by construct().
+ */
+ static void * convertible(PyObject * p) {
+ try {
+ bp::object obj(bp::handle<>(bp::borrowed(p)));
+ std::auto_ptr<bn::ndarray> array(
+ new bn::ndarray(
+ bn::from_object(obj, bn::dtype::get_builtin<double>(), N, N, bn::ndarray::V_CONTIGUOUS)
+ )
+ );
+ if (array->shape(0) != 2) return 0;
+ if (N == 2 && array->shape(1) != 2) return 0;
+ return array.release();
+ } catch (bp::error_already_set & err) {
+ bp::handle_exception();
+ return 0;
+ }
+ }
+
+ /**
+ * Finish the conversion by initializing the C++ object into memory prepared by Boost.Python.
+ */
+ static void construct(PyObject * obj, bp::converter::rvalue_from_python_stage1_data * data) {
+ // Extract the array we passed out of the convertible() member function.
+ std::auto_ptr<bn::ndarray> array(reinterpret_cast<bn::ndarray*>(data->convertible));
+ // Find the memory block Boost.Python has prepared for the result.
+ typedef bp::converter::rvalue_from_python_storage<T> storage_t;
+ storage_t * storage = reinterpret_cast<storage_t*>(data);
+ // Use placement new to initialize the result.
+ T * m_or_v = new (storage->storage.bytes) T();
+ // Fill the result with the values from the NumPy array.
+ copy_ndarray_to_mv2(*array, *m_or_v);
+ // Finish up.
+ data->convertible = storage->storage.bytes;
+ }
+
+};
+
+
+BOOST_PYTHON_MODULE(gaussian) {
+ bn::initialize();
+
+ // Register the from-python converters
+ mv2_from_python< vector2, 1 >();
+ mv2_from_python< matrix2, 2 >();
+
+ typedef double (bivariate_gaussian::*call_vector)(vector2 const &) const;
+
+ bp::class_<bivariate_gaussian>("bivariate_gaussian", bp::init<bivariate_gaussian const &>())
+
+ // Declare the constructor (wouldn't work without the from-python converters).
+ .def(bp::init< vector2 const &, matrix2 const & >())
+
+ // Use our custom reference-counting getters
+ .add_property("mu", &py_get_mu)
+ .add_property("sigma", &py_get_sigma)
+
+ // First overload accepts a two-element array argument
+ .def("__call__", (call_vector)&bivariate_gaussian::operator())
+
+ // This overload works like a binary NumPy universal function: you can pass
+ // in scalars or arrays, and the C++ function will automatically be called
+ // on each element of an array argument.
+ .def("__call__", bn::binary_ufunc<bivariate_gaussian,double,double,double>::make())
+ ;
+}
diff --git a/src/boost/libs/python/example/numpy/ndarray.cpp b/src/boost/libs/python/example/numpy/ndarray.cpp
new file mode 100644
index 000000000..d7b57aa73
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/ndarray.cpp
@@ -0,0 +1,71 @@
+// Copyright Ankit Daftery 2011-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * @brief An example to show how to create ndarrays using arbitrary Python sequences.
+ *
+ * The Python sequence could be any object whose __array__ method returns an array, or any
+ * (nested) sequence. This example also shows how to create arrays using both unit and
+ * non-unit strides.
+ */
+
+#include <boost/python/numpy.hpp>
+#include <iostream>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+#if _MSC_VER
+using boost::uint8_t;
+#endif
+
+int main(int argc, char **argv)
+{
+ // Initialize the Python runtime.
+ Py_Initialize();
+ // Initialize NumPy
+ np::initialize();
+ // Create an ndarray from a simple tuple
+ p::object tu = p::make_tuple('a','b','c') ;
+ np::ndarray example_tuple = np::array (tu) ;
+ // and from a list
+ p::list l ;
+ np::ndarray example_list = np::array (l) ;
+ // Optionally, you can also specify a dtype
+ np::dtype dt = np::dtype::get_builtin<int>();
+ np::ndarray example_list1 = np::array (l,dt);
+ // You can also create an array by supplying data.First,create an integer array
+ int data[] = {1,2,3,4} ;
+ // Create a shape, and strides, needed by the function
+ p::tuple shape = p::make_tuple(4) ;
+ p::tuple stride = p::make_tuple(4) ;
+ // The function also needs an owner, to keep track of the data array passed. Passing none is dangerous
+ p::object own ;
+ // The from_data function takes the data array, datatype,shape,stride and owner as arguments
+ // and returns an ndarray
+ np::ndarray data_ex = np::from_data(data,dt,shape,stride,own);
+ // Print the ndarray we created
+ std::cout << "Single dimensional array ::" << std::endl << p::extract < char const * > (p::str(data_ex)) << std::endl ;
+ // Now lets make an 3x2 ndarray from a multi-dimensional array using non-unit strides
+ // First lets create a 3x4 array of 8-bit integers
+ uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
+ // Now let's create an array of 3x2 elements, picking the first and third elements from each row
+ // For that, the shape will be 3x2
+ shape = p::make_tuple(3,2) ;
+ // The strides will be 4x2 i.e. 4 bytes to go to the next desired row, and 2 bytes to go to the next desired column
+ stride = p::make_tuple(4,2) ;
+ // Get the numpy dtype for the built-in 8-bit integer data type
+ np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
+ // First lets create and print out the ndarray as is
+ np::ndarray mul_data_ex = np::from_data(mul_data,dt1, p::make_tuple(3,4),p::make_tuple(4,1),p::object());
+ std::cout << "Original multi dimensional array :: " << std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
+ // Now create the new ndarray using the shape and strides
+ mul_data_ex = np::from_data(mul_data,dt1, shape,stride,p::object());
+ // Print out the array we created using non-unit strides
+ std::cout << "Selective multidimensional array :: "<<std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
+
+}
+
+
diff --git a/src/boost/libs/python/example/numpy/simple.cpp b/src/boost/libs/python/example/numpy/simple.cpp
new file mode 100644
index 000000000..ad598bde4
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/simple.cpp
@@ -0,0 +1,32 @@
+// Copyright 2011 Stefan Seefeld.
+// Distributed under the 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/numpy.hpp>
+#include <iostream>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+int main(int argc, char **argv)
+{
+ // Initialize the Python runtime.
+ Py_Initialize();
+ // Initialize NumPy
+ np::initialize();
+ // Create a 3x3 shape...
+ p::tuple shape = p::make_tuple(3, 3);
+ // ...as well as a type for C++ float
+ np::dtype dtype = np::dtype::get_builtin<float>();
+ // Construct an array with the above shape and type
+ np::ndarray a = np::zeros(shape, dtype);
+ // Construct an empty array with the above shape and dtype as well
+ np::ndarray b = np::empty(shape,dtype);
+ // Print the array
+ std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
+ // Reshape the array into a 1D array
+ a = a.reshape(p::make_tuple(9));
+ // Print it again.
+ std::cout << "Reshaped array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
+}
diff --git a/src/boost/libs/python/example/numpy/ufunc.cpp b/src/boost/libs/python/example/numpy/ufunc.cpp
new file mode 100644
index 000000000..5fb692045
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/ufunc.cpp
@@ -0,0 +1,86 @@
+// Copyright Ankit Daftery 2011-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * @brief An example to demonstrate use of universal functions or ufuncs
+ *
+ *
+ * @todo Calling the overloaded () operator is in a roundabout manner, find a simpler way
+ * None of the methods like np::add, np::multiply etc are supported as yet
+ */
+
+#include <boost/python/numpy.hpp>
+#include <iostream>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+
+// Create the structs necessary to implement the ufuncs
+// The typedefs *must* be made
+
+struct UnarySquare
+{
+ typedef double argument_type;
+ typedef double result_type;
+
+ double operator()(double r) const { return r * r;}
+};
+
+struct BinarySquare
+{
+ typedef double first_argument_type;
+ typedef double second_argument_type;
+ typedef double result_type;
+
+ double operator()(double a,double b) const { return (a*a + b*b) ; }
+};
+
+int main(int argc, char **argv)
+{
+ // Initialize the Python runtime.
+ Py_Initialize();
+ // Initialize NumPy
+ np::initialize();
+ // Expose the struct UnarySquare to Python as a class, and let ud be the class object
+ p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare")
+ .def("__call__", np::unary_ufunc<UnarySquare>::make());
+ // Let inst be an instance of the class ud
+ p::object inst = ud();
+ // Use the "__call__" method to call the overloaded () operator and print the value
+ std::cout << "Square of unary scalar 1.0 is " << p::extract <char const * > (p::str(inst.attr("__call__")(1.0))) << std::endl ;
+ // Create an array in C++
+ int arr[] = {1,2,3,4} ;
+ // ..and use it to create the ndarray in Python
+ np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
+ // Print out the demo array
+ std::cout << "Demo array is " << p::extract <char const * > (p::str(demo_array)) << std::endl ;
+ // Call the "__call__" method to perform the operation and assign the value to result_array
+ p::object result_array = inst.attr("__call__")(demo_array) ;
+ // Print the resultant array
+ std::cout << "Square of demo array is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
+ // Lets try the same with a list
+ p::list li ;
+ li.append(3);
+ li.append(7);
+ // Print out the demo list
+ std::cout << "Demo list is " << p::extract <char const * > (p::str(li)) << std::endl ;
+ // Call the ufunc for the list
+ result_array = inst.attr("__call__")(li) ;
+ // And print the list out
+ std::cout << "Square of demo list is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
+ // Now lets try Binary ufuncs
+ // Expose the struct BinarySquare to Python as a class, and let ud be the class object
+ ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare")
+ .def("__call__", np::binary_ufunc<BinarySquare>::make());
+ // Again initialise inst as an instance of the class ud
+ inst = ud();
+ // Print the two input listsPrint the two input lists
+ std::cout << "The two input list for binary ufunc are " << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl ;
+ // Call the binary ufunc taking demo_array as both inputs
+ result_array = inst.attr("__call__")(demo_array,demo_array) ;
+ std::cout << "Square of list with binary ufunc is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
+}
+
diff --git a/src/boost/libs/python/example/numpy/wrap.cpp b/src/boost/libs/python/example/numpy/wrap.cpp
new file mode 100644
index 000000000..33f71c85a
--- /dev/null
+++ b/src/boost/libs/python/example/numpy/wrap.cpp
@@ -0,0 +1,135 @@
+// Copyright Jim Bosch 2011-2012.
+// Distributed under the 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 simple example showing how to wrap a couple of C++ functions that
+ * operate on 2-d arrays into Python functions that take NumPy arrays
+ * as arguments.
+ *
+ * If you find have a lot of such functions to wrap, you may want to
+ * create a C++ array type (or use one of the many existing C++ array
+ * libraries) that maps well to NumPy arrays and create Boost.Python
+ * converters. There's more work up front than the approach here,
+ * but much less boilerplate per function. See the "Gaussian" example
+ * included with Boost.NumPy for an example of custom converters, or
+ * take a look at the "ndarray" project on GitHub for a more complete,
+ * high-level solution.
+ *
+ * Note that we're using embedded Python here only to make a convenient
+ * self-contained example; you could just as easily put the wrappers
+ * in a regular C++-compiled module and imported them in regular
+ * Python. Again, see the Gaussian demo for an example.
+ */
+
+#include <boost/python/numpy.hpp>
+#include <boost/scoped_array.hpp>
+#include <iostream>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+// This is roughly the most efficient way to write a C/C++ function that operates
+// on a 2-d NumPy array - operate directly on the array by incrementing a pointer
+// with the strides.
+void fill1(double * array, int rows, int cols, int row_stride, int col_stride) {
+ double * row_iter = array;
+ double n = 0.0; // just a counter we'll fill the array with.
+ for (int i = 0; i < rows; ++i, row_iter += row_stride) {
+ double * col_iter = row_iter;
+ for (int j = 0; j < cols; ++j, col_iter += col_stride) {
+ *col_iter = ++n;
+ }
+ }
+}
+
+// Here's a simple wrapper function for fill1. It requires that the passed
+// NumPy array be exactly what we're looking for - no conversion from nested
+// sequences or arrays with other data types, because we want to modify it
+// in-place.
+void wrap_fill1(np::ndarray const & array) {
+ if (array.get_dtype() != np::dtype::get_builtin<double>()) {
+ PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
+ p::throw_error_already_set();
+ }
+ if (array.get_nd() != 2) {
+ PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
+ p::throw_error_already_set();
+ }
+ fill1(reinterpret_cast<double*>(array.get_data()),
+ array.shape(0), array.shape(1),
+ array.strides(0) / sizeof(double), array.strides(1) / sizeof(double));
+}
+
+// Another fill function that takes a double**. This is less efficient, because
+// it's not the native NumPy data layout, but it's common enough in C/C++ that
+// it's worth its own example. This time we don't pass the strides, and instead
+// in wrap_fill2 we'll require the C_CONTIGUOUS bitflag, which guarantees that
+// the column stride is 1 and the row stride is the number of columns. That
+// restricts the arrays that can be passed to fill2 (it won't work on most
+// subarray views or transposes, for instance).
+void fill2(double ** array, int rows, int cols) {
+ double n = 0.0; // just a counter we'll fill the array with.
+ for (int i = 0; i < rows; ++i) {
+ for (int j = 0; j < cols; ++j) {
+ array[i][j] = ++n;
+ }
+ }
+}
+// Here's the wrapper for fill2; it's a little more complicated because we need
+// to check the flags and create the array of pointers.
+void wrap_fill2(np::ndarray const & array) {
+ if (array.get_dtype() != np::dtype::get_builtin<double>()) {
+ PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
+ p::throw_error_already_set();
+ }
+ if (array.get_nd() != 2) {
+ PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
+ p::throw_error_already_set();
+ }
+ if (!(array.get_flags() & np::ndarray::C_CONTIGUOUS)) {
+ PyErr_SetString(PyExc_TypeError, "Array must be row-major contiguous");
+ p::throw_error_already_set();
+ }
+ double * iter = reinterpret_cast<double*>(array.get_data());
+ int rows = array.shape(0);
+ int cols = array.shape(1);
+ boost::scoped_array<double*> ptrs(new double*[rows]);
+ for (int i = 0; i < rows; ++i, iter += cols) {
+ ptrs[i] = iter;
+ }
+ fill2(ptrs.get(), array.shape(0), array.shape(1));
+}
+
+BOOST_PYTHON_MODULE(example) {
+ np::initialize(); // have to put this in any module that uses Boost.NumPy
+ p::def("fill1", wrap_fill1);
+ p::def("fill2", wrap_fill2);
+}
+
+int main(int argc, char **argv)
+{
+ // This line makes our module available to the embedded Python intepreter.
+# if PY_VERSION_HEX >= 0x03000000
+ PyImport_AppendInittab("example", &PyInit_example);
+# else
+ PyImport_AppendInittab("example", &initexample);
+# endif
+ // Initialize the Python runtime.
+ Py_Initialize();
+
+ PyRun_SimpleString(
+ "import example\n"
+ "import numpy\n"
+ "z1 = numpy.zeros((5,6), dtype=float)\n"
+ "z2 = numpy.zeros((4,3), dtype=float)\n"
+ "example.fill1(z1)\n"
+ "example.fill2(z2)\n"
+ "print z1\n"
+ "print z2\n"
+ );
+ Py_Finalize();
+}
+
+
diff --git a/src/boost/libs/python/example/quickstart/Jamfile b/src/boost/libs/python/example/quickstart/Jamfile
new file mode 100644
index 000000000..6dd351301
--- /dev/null
+++ b/src/boost/libs/python/example/quickstart/Jamfile
@@ -0,0 +1,35 @@
+# Copyright Stefan Seefeld 2016.
+# Distributed under the 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 testing ;
+
+project quickstart
+ : requirements
+ <location>.
+ ;
+
+# 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 ;
+
+# 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 embedding.cpp
+ : # 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/src/boost/libs/python/example/quickstart/embedding.cpp b/src/boost/libs/python/example/quickstart/embedding.cpp
new file mode 100644
index 000000000..65bcd16a0
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/example/quickstart/extending.cpp b/src/boost/libs/python/example/quickstart/extending.cpp
new file mode 100644
index 000000000..a539d3b4b
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/example/quickstart/script.py b/src/boost/libs/python/example/quickstart/script.py
new file mode 100644
index 000000000..c3e034ba8
--- /dev/null
+++ b/src/boost/libs/python/example/quickstart/script.py
@@ -0,0 +1,7 @@
+#! /usr/bin/env python
+# 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/src/boost/libs/python/example/quickstart/test_extending.py b/src/boost/libs/python/example/quickstart/test_extending.py
new file mode 100644
index 000000000..938c7b904
--- /dev/null
+++ b/src/boost/libs/python/example/quickstart/test_extending.py
@@ -0,0 +1,37 @@
+#! /usr/bin/env python
+# 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/src/boost/libs/python/example/tutorial/Jamfile b/src/boost/libs/python/example/tutorial/Jamfile
new file mode 100644
index 000000000..a32272e7f
--- /dev/null
+++ b/src/boost/libs/python/example/tutorial/Jamfile
@@ -0,0 +1,19 @@
+# Copyright Stefan Seefeld 2016.
+# Distributed under the 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 ;
+
+project tutorial
+ : requirements
+ <location>.
+ ;
+
+python-extension hello_ext : hello.cpp ;
+
+run-test hello : hello_ext hello.py ;
+
+alias test : hello ;
+explicit test ;
+
diff --git a/src/boost/libs/python/example/tutorial/hello.cpp b/src/boost/libs/python/example/tutorial/hello.cpp
new file mode 100644
index 000000000..d5114312b
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/example/tutorial/hello.py b/src/boost/libs/python/example/tutorial/hello.py
new file mode 100755
index 000000000..31f75565d
--- /dev/null
+++ b/src/boost/libs/python/example/tutorial/hello.py
@@ -0,0 +1,8 @@
+#! /usr/bin/env python
+# 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/src/boost/libs/python/fabscript b/src/boost/libs/python/fabscript
new file mode 100644
index 000000000..054ed90e5
--- /dev/null
+++ b/src/boost/libs/python/fabscript
@@ -0,0 +1,82 @@
+# -*- python -*-
+#
+# Copyright (c) 2016 Stefan Seefeld
+# All rights reserved.
+#
+# Distributed under the 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 faber.feature import set
+from faber.types import cxx
+from faber.tools.compiler import cxxflags, define, include
+from faber.tools.python import python
+from faber.config import report, cxx_checks
+from faber.config.try_run import try_run
+
+features += include('include')
+features += define('BOOST_ALL_NO_LIB') # disable auto-linking
+boost_include = options.get_with('boost-include')
+if boost_include:
+ features += include(boost_include)
+python = python.instance()
+py_suffix = '{}{}'.format(*python.version.split('.')[:2])
+features |= set(python.include, python.linkpath, python.libs)
+
+class has_numpy(try_run):
+
+ src = r"""
+// If defined, enforces linking against PythonXXd.lib, which
+// is usually not included in Python environments.
+#undef _DEBUG
+#include "Python.h"
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include "numpy/arrayobject.h"
+
+#if PY_VERSION_HEX >= 0x03000000
+void *initialize() { import_array();}
+#else
+void initialize() { import_array();}
+#endif
+
+int main()
+{
+ int result = 0;
+ Py_Initialize();
+ initialize();
+ if (PyErr_Occurred())
+ {
+ result = 1;
+ }
+ else
+ {
+ npy_intp dims = 2;
+ PyObject * a = PyArray_SimpleNew(1, &dims, NPY_INT);
+ if (!a) result = 1;
+ Py_DECREF(a);
+ }
+ Py_Finalize();
+ return result;
+}
+"""
+ def __init__(self, features=()):
+
+ inc = ''
+ try:
+ inc = python.check_python('import numpy; print(numpy.get_include())')
+ features |= include(inc)
+ except Exception:
+ # ignore errors, the check will fail during compilation...
+ pass
+ try_run.__init__(self, 'has_numpy', has_numpy.src, cxx, features,
+ if_=(include(inc), define('HAS_NUMPY')))
+
+checks = [cxx_checks.has_cxx11(features, define('HAS_CXX11')),
+ has_numpy(features)]
+config = report('config', checks)
+
+src = module('src', features=config.use)
+test = module('test', features=config.use)
+doc = module('doc', features=config.use)
+
+default = src.default
diff --git a/src/boost/libs/python/index.html b/src/boost/libs/python/index.html
new file mode 100644
index 000000000..1e1a27531
--- /dev/null
+++ b/src/boost/libs/python/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=doc/index.html">
+ </head>
+ <body>
+ Automatic redirection failed, click this
+ <a href="doc/index.html">link</a> &nbsp;<hr>
+ <p>© Copyright Stefan Seefeld, 2015</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)</p>
+ </body>
+</html>
diff --git a/src/boost/libs/python/meta/libraries.json b/src/boost/libs/python/meta/libraries.json
new file mode 100644
index 000000000..e2f2a0547
--- /dev/null
+++ b/src/boost/libs/python/meta/libraries.json
@@ -0,0 +1,14 @@
+{
+ "key": "python",
+ "name": "Python",
+ "authors": [
+ "Dave Abrahams"
+ ],
+ "description": "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.",
+ "category": [
+ "Inter-language"
+ ],
+ "maintainers": [
+ "Stefan Seefeld <stefan -at- seefeld.name>"
+ ]
+}
diff --git a/src/boost/libs/python/src/converter/arg_to_python_base.cpp b/src/boost/libs/python/src/converter/arg_to_python_base.cpp
new file mode 100644
index 000000000..d872314a7
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/converter/builtin_converters.cpp b/src/boost/libs/python/src/converter/builtin_converters.cpp
new file mode 100644
index 000000000..ee2d5b479
--- /dev/null
+++ b/src/boost/libs/python/src/converter/builtin_converters.cpp
@@ -0,0 +1,592 @@
+// 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;
+ }
+#elif PY_VERSION_HEX < 0x03070000
+ void* convert_to_cstring(PyObject* obj)
+ {
+ return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
+ }
+#else
+ void* convert_to_cstring(PyObject* obj)
+ {
+ return PyUnicode_Check(obj) ? const_cast<void*>(reinterpret_cast<const void*>(_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)
+ {
+ // On Windows, with Python >= 3.3, PyObject_Length cannot be used to get
+ // the size of the wchar_t string, because it will count the number of
+ // *code points*, but some characters not on the BMP will use two UTF-16
+ // *code units* (surrogate pairs).
+ // This is not a problem on Unix, since wchar_t is 32-bit.
+#if defined(_WIN32) && PY_VERSION_HEX >= 0x03030000
+ BOOST_STATIC_ASSERT(sizeof(wchar_t) == 2);
+
+ Py_ssize_t size = 0;
+ wchar_t *buf = PyUnicode_AsWideCharString(intermediate, &size);
+ if (buf == NULL) {
+ boost::python::throw_error_already_set();
+ }
+ std::wstring result(buf, size);
+ PyMem_Free(buf);
+#else
+ 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();
+ }
+#endif
+ 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/src/boost/libs/python/src/converter/from_python.cpp b/src/boost/libs/python/src/converter/from_python.cpp
new file mode 100644
index 000000000..9678be1cb
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/converter/registry.cpp b/src/boost/libs/python/src/converter/registry.cpp
new file mode 100644
index 000000000..aa20c3f68
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/converter/type_id.cpp b/src/boost/libs/python/src/converter/type_id.cpp
new file mode 100644
index 000000000..c6a8bf7a0
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/dict.cpp b/src/boost/libs/python/src/dict.cpp
new file mode 100644
index 000000000..77d840d45
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/errors.cpp b/src/boost/libs/python/src/errors.cpp
new file mode 100644
index 000000000..34ea22f43
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/exec.cpp b/src/boost/libs/python/src/exec.cpp
new file mode 100644
index 000000000..171c6f418
--- /dev/null
+++ b/src/boost/libs/python/src/exec.cpp
@@ -0,0 +1,129 @@
+// 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)
+{
+ return eval(python::extract<char const *>(string), global, local);
+}
+
+object BOOST_PYTHON_DECL eval(char const *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 = const_cast<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)
+{
+ return exec(python::extract<char const *>(string), global, local);
+}
+
+object BOOST_PYTHON_DECL exec(char const *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 = const_cast<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)
+{
+ return exec_statement(python::extract<char const *>(string), global, local);
+}
+
+object BOOST_PYTHON_DECL exec_statement(char const *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 = const_cast<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)
+{
+ return exec_file(python::extract<char const *>(filename), global, local);
+}
+
+object BOOST_PYTHON_DECL exec_file(char const *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 = const_cast<char *>(filename);
+ // Let python open the file to avoid potential binary incompatibilities.
+#if PY_VERSION_HEX >= 0x03040000
+ FILE *fs = _Py_fopen(f, "r");
+#elif PY_VERSION_HEX >= 0x03000000
+ PyObject *fo = Py_BuildValue("s", f);
+ FILE *fs = _Py_fopen(fo, "r");
+ Py_DECREF(fo);
+#else
+ 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/src/boost/libs/python/src/fabscript b/src/boost/libs/python/src/fabscript
new file mode 100644
index 000000000..0ebeac609
--- /dev/null
+++ b/src/boost/libs/python/src/fabscript
@@ -0,0 +1,58 @@
+# -*- python -*-
+#
+# Copyright (c) 2016 Stefan Seefeld
+# All rights reserved.
+#
+# Distributed under the 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 faber.feature import set
+from faber.artefacts.library import library
+from faber.tools.compiler import define
+
+root = module('..')
+
+bpl = library('boost_python' + root.py_suffix,
+ ['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'],
+ dependencies=root.config,
+ features=features + define('BOOST_PYTHON_SOURCE'))
+
+bnl = library('boost_numpy' + root.py_suffix,
+ ['numpy/dtype.cpp',
+ 'numpy/matrix.cpp',
+ 'numpy/ndarray.cpp',
+ 'numpy/numpy.cpp',
+ 'numpy/scalars.cpp',
+ 'numpy/ufunc.cpp',
+ bpl],
+ dependencies=root.config,
+ features=features + define('BOOST_NUMPY_SOURCE'),
+ condition=set.define.contains('HAS_NUMPY'))
+default = [bpl, bnl]
diff --git a/src/boost/libs/python/src/import.cpp b/src/boost/libs/python/src/import.cpp
new file mode 100644
index 000000000..0add79eea
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/list.cpp b/src/boost/libs/python/src/list.cpp
new file mode 100644
index 000000000..77e616881
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/long.cpp b/src/boost/libs/python/src/long.cpp
new file mode 100644
index 000000000..1ec8ebc01
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/module.cpp b/src/boost/libs/python/src/module.cpp
new file mode 100644
index 000000000..962848199
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/numpy/dtype.cpp b/src/boost/libs/python/src/numpy/dtype.cpp
new file mode 100644
index 000000000..88a20a27b
--- /dev/null
+++ b/src/boost/libs/python/src/numpy/dtype.cpp
@@ -0,0 +1,220 @@
+// Copyright Jim Bosch 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifdef _MSC_VER
+#include <boost/cstdint.hpp>
+#endif
+#define BOOST_PYTHON_NUMPY_INTERNAL
+#include <boost/python/numpy/internal.hpp>
+
+#define DTYPE_FROM_CODE(code) \
+ dtype(python::detail::new_reference(reinterpret_cast<PyObject*>(PyArray_DescrFromType(code))))
+
+#define BUILTIN_INT_DTYPE(bits) \
+ template <> struct builtin_int_dtype<bits, false> \
+ { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_INT ## bits);} \
+ }; \
+ template <> struct builtin_int_dtype<bits, true> \
+ { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_UINT ## bits);} \
+ }; \
+ template BOOST_NUMPY_DECL dtype get_int_dtype<bits, false>(); \
+ template BOOST_NUMPY_DECL dtype get_int_dtype<bits, true>()
+
+#define BUILTIN_FLOAT_DTYPE(bits) \
+ template <> struct builtin_float_dtype<bits> \
+ { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_FLOAT ## bits);} \
+ }; \
+ template BOOST_NUMPY_DECL dtype get_float_dtype<bits>()
+
+#define BUILTIN_COMPLEX_DTYPE(bits) \
+ template <> struct builtin_complex_dtype<bits> \
+ { \
+ static dtype get() { return DTYPE_FROM_CODE(NPY_COMPLEX ## bits);} \
+ }; \
+ template BOOST_NUMPY_DECL dtype get_complex_dtype<bits>()
+
+namespace boost { namespace python { namespace converter {
+NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArrayDescr_Type, numpy::dtype)
+} // namespace boost::python::converter
+
+namespace numpy {
+namespace detail {
+
+dtype builtin_dtype<bool,true>::get() { return DTYPE_FROM_CODE(NPY_BOOL); }
+
+template <int bits, bool isUnsigned> struct builtin_int_dtype;
+template <int bits> struct builtin_float_dtype;
+template <int bits> struct builtin_complex_dtype;
+
+template <int bits, bool isUnsigned> dtype get_int_dtype() {
+ return builtin_int_dtype<bits,isUnsigned>::get();
+}
+template <int bits> dtype get_float_dtype() { return builtin_float_dtype<bits>::get(); }
+template <int bits> dtype get_complex_dtype() { return builtin_complex_dtype<bits>::get(); }
+
+BUILTIN_INT_DTYPE(8);
+BUILTIN_INT_DTYPE(16);
+BUILTIN_INT_DTYPE(32);
+BUILTIN_INT_DTYPE(64);
+#ifdef NPY_FLOAT16
+BUILTIN_FLOAT_DTYPE(16);
+#endif
+BUILTIN_FLOAT_DTYPE(32);
+BUILTIN_FLOAT_DTYPE(64);
+BUILTIN_COMPLEX_DTYPE(64);
+BUILTIN_COMPLEX_DTYPE(128);
+#if NPY_BITSOF_LONGDOUBLE > NPY_BITSOF_DOUBLE
+template <> struct builtin_float_dtype< NPY_BITSOF_LONGDOUBLE > {
+ static dtype get() { return DTYPE_FROM_CODE(NPY_LONGDOUBLE); }
+};
+template dtype get_float_dtype< NPY_BITSOF_LONGDOUBLE >();
+template <> struct builtin_complex_dtype< 2 * NPY_BITSOF_LONGDOUBLE > {
+ static dtype get() { return DTYPE_FROM_CODE(NPY_CLONGDOUBLE); }
+};
+template dtype get_complex_dtype< 2 * NPY_BITSOF_LONGDOUBLE >();
+#endif
+
+} // namespace detail
+
+python::detail::new_reference dtype::convert(object const & arg, bool align)
+{
+ PyArray_Descr* obj=NULL;
+ if (align)
+ {
+ if (PyArray_DescrAlignConverter(arg.ptr(), &obj) < 0)
+ throw_error_already_set();
+ }
+ else
+ {
+ if (PyArray_DescrConverter(arg.ptr(), &obj) < 0)
+ throw_error_already_set();
+ }
+ return python::detail::new_reference(reinterpret_cast<PyObject*>(obj));
+}
+
+int dtype::get_itemsize() const { return reinterpret_cast<PyArray_Descr*>(ptr())->elsize;}
+
+bool equivalent(dtype const & a, dtype const & b) {
+ // On Windows x64, the behaviour described on
+ // http://docs.scipy.org/doc/numpy/reference/c-api.array.html for
+ // PyArray_EquivTypes unfortunately does not extend as expected:
+ // "For example, on 32-bit platforms, NPY_LONG and NPY_INT are equivalent".
+ // This should also hold for 64-bit platforms (and does on Linux), but not
+ // on Windows. Implement an alternative:
+#ifdef _MSC_VER
+ if (sizeof(long) == sizeof(int) &&
+ // Manually take care of the type equivalence.
+ ((a == dtype::get_builtin<long>() || a == dtype::get_builtin<int>()) &&
+ (b == dtype::get_builtin<long>() || b == dtype::get_builtin<int>()) ||
+ (a == dtype::get_builtin<unsigned int>() || a == dtype::get_builtin<unsigned long>()) &&
+ (b == dtype::get_builtin<unsigned int>() || b == dtype::get_builtin<unsigned long>()))) {
+ return true;
+ } else {
+ return PyArray_EquivTypes(
+ reinterpret_cast<PyArray_Descr*>(a.ptr()),
+ reinterpret_cast<PyArray_Descr*>(b.ptr())
+ );
+ }
+#else
+ return PyArray_EquivTypes(
+ reinterpret_cast<PyArray_Descr*>(a.ptr()),
+ reinterpret_cast<PyArray_Descr*>(b.ptr())
+ );
+#endif
+}
+
+namespace
+{
+
+namespace pyconv = boost::python::converter;
+
+template <typename T>
+class array_scalar_converter
+{
+public:
+
+ static PyTypeObject const * get_pytype()
+ {
+ // This implementation depends on the fact that get_builtin returns pointers to objects
+ // NumPy has declared statically, and that the typeobj member also refers to a static
+ // object. That means we don't need to do any reference counting.
+ // In fact, I'm somewhat concerned that increasing the reference count of any of these
+ // might cause leaks, because I don't think Boost.Python ever decrements it, but it's
+ // probably a moot point if everything is actually static.
+ return reinterpret_cast<PyArray_Descr*>(dtype::get_builtin<T>().ptr())->typeobj;
+ }
+
+ static void * convertible(PyObject * obj)
+ {
+ if (obj->ob_type == get_pytype())
+ {
+ return obj;
+ }
+ else
+ {
+ dtype dt(python::detail::borrowed_reference(obj->ob_type));
+ if (equivalent(dt, dtype::get_builtin<T>()))
+ {
+ return obj;
+ }
+ }
+ return 0;
+ }
+
+ static void convert(PyObject * obj, pyconv::rvalue_from_python_stage1_data* data)
+ {
+ void * storage = reinterpret_cast<pyconv::rvalue_from_python_storage<T>*>(data)->storage.bytes;
+ // We assume std::complex is a "standard layout" here and elsewhere; not guaranteed by
+ // C++03 standard, but true in every known implementation (and guaranteed by C++11).
+ PyArray_ScalarAsCtype(obj, reinterpret_cast<T*>(storage));
+ data->convertible = storage;
+ }
+
+ static void declare()
+ {
+ pyconv::registry::push_back(&convertible, &convert, python::type_id<T>()
+#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
+ , &get_pytype
+#endif
+ );
+ }
+
+};
+
+} // anonymous
+
+void dtype::register_scalar_converters()
+{
+ array_scalar_converter<bool>::declare();
+ array_scalar_converter<npy_uint8>::declare();
+ array_scalar_converter<npy_int8>::declare();
+ array_scalar_converter<npy_uint16>::declare();
+ array_scalar_converter<npy_int16>::declare();
+ array_scalar_converter<npy_uint32>::declare();
+ array_scalar_converter<npy_int32>::declare();
+#ifdef _MSC_VER
+ // Since the npy_(u)int32 types are defined as long types and treated
+ // as being different from the int32 types, these converters must be declared
+ // explicitely.
+ array_scalar_converter<boost::uint32_t>::declare();
+ array_scalar_converter<boost::int32_t>::declare();
+#endif
+ array_scalar_converter<npy_uint64>::declare();
+ array_scalar_converter<npy_int64>::declare();
+ array_scalar_converter<float>::declare();
+ array_scalar_converter<double>::declare();
+ array_scalar_converter< std::complex<float> >::declare();
+ array_scalar_converter< std::complex<double> >::declare();
+#if NPY_BITSOF_LONGDOUBLE > NPY_BITSOF_DOUBLE
+ array_scalar_converter<long double>::declare();
+ array_scalar_converter< std::complex<long double> >::declare();
+#endif
+}
+
+}}} // namespace boost::python::numpy
diff --git a/src/boost/libs/python/src/numpy/matrix.cpp b/src/boost/libs/python/src/numpy/matrix.cpp
new file mode 100644
index 000000000..47d226163
--- /dev/null
+++ b/src/boost/libs/python/src/numpy/matrix.cpp
@@ -0,0 +1,63 @@
+// Copyright Jim Bosch 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 BOOST_PYTHON_NUMPY_INTERNAL
+#include <boost/python/numpy/internal.hpp>
+#include <boost/python/numpy/matrix.hpp>
+
+namespace boost { namespace python { namespace numpy
+{
+namespace detail
+{
+inline object get_matrix_type()
+{
+ object module = import("numpy");
+ return module.attr("matrix");
+}
+} // namespace boost::python::numpy::detail
+} // namespace boost::python::numpy
+
+namespace converter
+{
+
+PyTypeObject const * object_manager_traits<numpy::matrix>::get_pytype()
+{
+ return reinterpret_cast<PyTypeObject*>(numpy::detail::get_matrix_type().ptr());
+}
+
+} // namespace boost::python::converter
+
+namespace numpy
+{
+
+object matrix::construct(object const & obj, dtype const & dt, bool copy)
+{
+ return numpy::detail::get_matrix_type()(obj, dt, copy);
+}
+
+object matrix::construct(object const & obj, bool copy)
+{
+ return numpy::detail::get_matrix_type()(obj, object(), copy);
+}
+
+matrix matrix::view(dtype const & dt) const
+{
+ return matrix(python::detail::new_reference
+ (PyObject_CallMethod(this->ptr(), const_cast<char*>("view"), const_cast<char*>("O"), dt.ptr())));
+}
+
+matrix matrix::copy() const
+{
+ return matrix(python::detail::new_reference
+ (PyObject_CallMethod(this->ptr(), const_cast<char*>("copy"), const_cast<char*>(""))));
+}
+
+matrix matrix::transpose() const
+{
+ return matrix(extract<matrix>(ndarray::transpose()));
+}
+
+}}} // namespace boost::python::numpy
diff --git a/src/boost/libs/python/src/numpy/ndarray.cpp b/src/boost/libs/python/src/numpy/ndarray.cpp
new file mode 100644
index 000000000..af09ecc33
--- /dev/null
+++ b/src/boost/libs/python/src/numpy/ndarray.cpp
@@ -0,0 +1,301 @@
+// Copyright Jim Bosch 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 BOOST_PYTHON_NUMPY_INTERNAL
+#include <boost/python/numpy/internal.hpp>
+#include <boost/scoped_array.hpp>
+
+namespace boost { namespace python {
+namespace converter
+{
+NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArray_Type, numpy::ndarray)
+} // namespace boost::python::converter
+
+namespace numpy
+{
+namespace detail
+{
+
+ndarray::bitflag numpy_to_bitflag(int const f)
+{
+ ndarray::bitflag r = ndarray::NONE;
+ if (f & NPY_ARRAY_C_CONTIGUOUS) r = (r | ndarray::C_CONTIGUOUS);
+ if (f & NPY_ARRAY_F_CONTIGUOUS) r = (r | ndarray::F_CONTIGUOUS);
+ if (f & NPY_ARRAY_ALIGNED) r = (r | ndarray::ALIGNED);
+ if (f & NPY_ARRAY_WRITEABLE) r = (r | ndarray::WRITEABLE);
+ return r;
+}
+
+int bitflag_to_numpy(ndarray::bitflag f)
+{
+ int r = 0;
+ if (f & ndarray::C_CONTIGUOUS) r |= NPY_ARRAY_C_CONTIGUOUS;
+ if (f & ndarray::F_CONTIGUOUS) r |= NPY_ARRAY_F_CONTIGUOUS;
+ if (f & ndarray::ALIGNED) r |= NPY_ARRAY_ALIGNED;
+ if (f & ndarray::WRITEABLE) r |= NPY_ARRAY_WRITEABLE;
+ return r;
+}
+
+bool is_c_contiguous(std::vector<Py_intptr_t> const & shape,
+ std::vector<Py_intptr_t> const & strides,
+ int itemsize)
+{
+ std::vector<Py_intptr_t>::const_reverse_iterator j = strides.rbegin();
+ int total = itemsize;
+ for (std::vector<Py_intptr_t>::const_reverse_iterator i = shape.rbegin(); i != shape.rend(); ++i, ++j)
+ {
+ if (total != *j) return false;
+ total *= (*i);
+ }
+ return true;
+}
+
+bool is_f_contiguous(std::vector<Py_intptr_t> const & shape,
+ std::vector<Py_intptr_t> const & strides,
+ int itemsize)
+{
+ std::vector<Py_intptr_t>::const_iterator j = strides.begin();
+ int total = itemsize;
+ for (std::vector<Py_intptr_t>::const_iterator i = shape.begin(); i != shape.end(); ++i, ++j)
+ {
+ if (total != *j) return false;
+ total *= (*i);
+ }
+ return true;
+}
+
+bool is_aligned(std::vector<Py_intptr_t> const & strides,
+ int itemsize)
+{
+ for (std::vector<Py_intptr_t>::const_iterator i = strides.begin(); i != strides.end(); ++i)
+ {
+ if (*i % itemsize) return false;
+ }
+ return true;
+}
+
+inline PyArray_Descr * incref_dtype(dtype const & dt)
+{
+ Py_INCREF(dt.ptr());
+ return reinterpret_cast<PyArray_Descr*>(dt.ptr());
+}
+
+ndarray from_data_impl(void * data,
+ dtype const & dt,
+ python::object const & shape,
+ python::object const & strides,
+ python::object const & owner,
+ bool writeable)
+{
+ std::vector<Py_intptr_t> shape_(len(shape));
+ std::vector<Py_intptr_t> strides_(len(strides));
+ if (shape_.size() != strides_.size())
+ {
+ PyErr_SetString(PyExc_ValueError, "Length of shape and strides arrays do not match.");
+ python::throw_error_already_set();
+ }
+ for (std::size_t i = 0; i < shape_.size(); ++i)
+ {
+ shape_[i] = python::extract<Py_intptr_t>(shape[i]);
+ strides_[i] = python::extract<Py_intptr_t>(strides[i]);
+ }
+ return from_data_impl(data, dt, shape_, strides_, owner, writeable);
+}
+
+ndarray from_data_impl(void * data,
+ dtype const & dt,
+ std::vector<Py_intptr_t> const & shape,
+ std::vector<Py_intptr_t> const & strides,
+ python::object const & owner,
+ bool writeable)
+{
+ if (shape.size() != strides.size())
+ {
+ PyErr_SetString(PyExc_ValueError, "Length of shape and strides arrays do not match.");
+ python::throw_error_already_set();
+ }
+ int itemsize = dt.get_itemsize();
+ int flags = 0;
+ if (writeable) flags |= NPY_ARRAY_WRITEABLE;
+ if (is_c_contiguous(shape, strides, itemsize)) flags |= NPY_ARRAY_C_CONTIGUOUS;
+ if (is_f_contiguous(shape, strides, itemsize)) flags |= NPY_ARRAY_F_CONTIGUOUS;
+ if (is_aligned(strides, itemsize)) flags |= NPY_ARRAY_ALIGNED;
+ ndarray r(python::detail::new_reference
+ (PyArray_NewFromDescr(&PyArray_Type,
+ incref_dtype(dt),
+ shape.size(),
+ const_cast<Py_intptr_t*>(&shape.front()),
+ const_cast<Py_intptr_t*>(&strides.front()),
+ data,
+ flags,
+ NULL)));
+ r.set_base(owner);
+ return r;
+}
+
+} // namespace detail
+
+namespace {
+ int normalize_index(int n,int nlim) // wraps [-nlim:nlim) into [0:nlim), throw IndexError otherwise
+ {
+ if (n<0)
+ n += nlim; // negative indices work backwards from end
+ if (n < 0 || n >= nlim)
+ {
+ PyErr_SetObject(PyExc_IndexError, Py_None);
+ throw_error_already_set();
+ }
+ return n;
+ }
+}
+
+Py_intptr_t ndarray::shape(int n) const
+{
+ return get_shape()[normalize_index(n,get_nd())];
+}
+
+Py_intptr_t ndarray::strides(int n) const
+{
+ return get_strides()[normalize_index(n,get_nd())];
+}
+
+ndarray ndarray::view(dtype const & dt) const
+{
+ return ndarray(python::detail::new_reference
+ (PyObject_CallMethod(this->ptr(), const_cast<char*>("view"), const_cast<char*>("O"), dt.ptr())));
+}
+
+ndarray ndarray::astype(dtype const & dt) const
+{
+ return ndarray(python::detail::new_reference
+ (PyObject_CallMethod(this->ptr(), const_cast<char*>("astype"), const_cast<char*>("O"), dt.ptr())));
+}
+
+ndarray ndarray::copy() const
+{
+ return ndarray(python::detail::new_reference
+ (PyObject_CallMethod(this->ptr(), const_cast<char*>("copy"), const_cast<char*>(""))));
+}
+
+dtype ndarray::get_dtype() const
+{
+ return dtype(python::detail::borrowed_reference(get_struct()->descr));
+}
+
+python::object ndarray::get_base() const
+{
+ if (get_struct()->base == NULL) return object();
+ return python::object(python::detail::borrowed_reference(get_struct()->base));
+}
+
+void ndarray::set_base(object const & base)
+{
+ Py_XDECREF(get_struct()->base);
+ if (base.ptr())
+ {
+ Py_INCREF(base.ptr());
+ get_struct()->base = base.ptr();
+ }
+ else
+ {
+ get_struct()->base = NULL;
+ }
+}
+
+ndarray::bitflag ndarray::get_flags() const
+{
+ return numpy::detail::numpy_to_bitflag(get_struct()->flags);
+}
+
+ndarray ndarray::transpose() const
+{
+ return ndarray(python::detail::new_reference
+ (PyArray_Transpose(reinterpret_cast<PyArrayObject*>(this->ptr()), NULL)));
+}
+
+ndarray ndarray::squeeze() const
+{
+ return ndarray(python::detail::new_reference
+ (PyArray_Squeeze(reinterpret_cast<PyArrayObject*>(this->ptr()))));
+}
+
+ndarray ndarray::reshape(python::tuple const & shape) const
+{
+ return ndarray(python::detail::new_reference
+ (PyArray_Reshape(reinterpret_cast<PyArrayObject*>(this->ptr()), shape.ptr())));
+}
+
+python::object ndarray::scalarize() const
+{
+ Py_INCREF(ptr());
+ return python::object(python::detail::new_reference(PyArray_Return(reinterpret_cast<PyArrayObject*>(ptr()))));
+}
+
+ndarray zeros(python::tuple const & shape, dtype const & dt)
+{
+ int nd = len(shape);
+ boost::scoped_array<Py_intptr_t> dims(new Py_intptr_t[nd]);
+ for (int n=0; n<nd; ++n) dims[n] = python::extract<Py_intptr_t>(shape[n]);
+ return ndarray(python::detail::new_reference
+ (PyArray_Zeros(nd, dims.get(), detail::incref_dtype(dt), 0)));
+}
+
+ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt)
+{
+ return ndarray(python::detail::new_reference
+ (PyArray_Zeros(nd, const_cast<Py_intptr_t*>(shape), detail::incref_dtype(dt), 0)));
+}
+
+ndarray empty(python::tuple const & shape, dtype const & dt)
+{
+ int nd = len(shape);
+ boost::scoped_array<Py_intptr_t> dims(new Py_intptr_t[nd]);
+ for (int n=0; n<nd; ++n) dims[n] = python::extract<Py_intptr_t>(shape[n]);
+ return ndarray(python::detail::new_reference
+ (PyArray_Empty(nd, dims.get(), detail::incref_dtype(dt), 0)));
+}
+
+ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt)
+{
+ return ndarray(python::detail::new_reference
+ (PyArray_Empty(nd, const_cast<Py_intptr_t*>(shape), detail::incref_dtype(dt), 0)));
+}
+
+ndarray array(python::object const & obj)
+{
+ return ndarray(python::detail::new_reference
+ (PyArray_FromAny(obj.ptr(), NULL, 0, 0, NPY_ARRAY_ENSUREARRAY, NULL)));
+}
+
+ndarray array(python::object const & obj, dtype const & dt)
+{
+ return ndarray(python::detail::new_reference
+ (PyArray_FromAny(obj.ptr(), detail::incref_dtype(dt), 0, 0, NPY_ARRAY_ENSUREARRAY, NULL)));
+}
+
+ndarray from_object(python::object const & obj, dtype const & dt, int nd_min, int nd_max, ndarray::bitflag flags)
+{
+ int requirements = detail::bitflag_to_numpy(flags);
+ return ndarray(python::detail::new_reference
+ (PyArray_FromAny(obj.ptr(),
+ detail::incref_dtype(dt),
+ nd_min, nd_max,
+ requirements,
+ NULL)));
+}
+
+ndarray from_object(python::object const & obj, int nd_min, int nd_max, ndarray::bitflag flags)
+{
+ int requirements = detail::bitflag_to_numpy(flags);
+ return ndarray(python::detail::new_reference
+ (PyArray_FromAny(obj.ptr(),
+ NULL,
+ nd_min, nd_max,
+ requirements,
+ NULL)));
+}
+
+}}} // namespace boost::python::numpy
diff --git a/src/boost/libs/python/src/numpy/numpy.cpp b/src/boost/libs/python/src/numpy/numpy.cpp
new file mode 100644
index 000000000..3ae2295e3
--- /dev/null
+++ b/src/boost/libs/python/src/numpy/numpy.cpp
@@ -0,0 +1,34 @@
+// Copyright Jim Bosch 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 BOOST_PYTHON_NUMPY_INTERNAL_MAIN
+#include <boost/python/numpy/internal.hpp>
+#include <boost/python/numpy/dtype.hpp>
+
+namespace boost { namespace python { namespace numpy {
+
+#if PY_MAJOR_VERSION == 2
+static void wrap_import_array()
+{
+ import_array();
+}
+#else
+static void * wrap_import_array()
+{
+ import_array();
+ return NULL;
+}
+#endif
+
+void initialize(bool register_scalar_converters)
+{
+ wrap_import_array();
+ import_ufunc();
+ if (register_scalar_converters)
+ dtype::register_scalar_converters();
+}
+
+}}} // namespace boost::python::numpy
diff --git a/src/boost/libs/python/src/numpy/scalars.cpp b/src/boost/libs/python/src/numpy/scalars.cpp
new file mode 100644
index 000000000..3947c06f2
--- /dev/null
+++ b/src/boost/libs/python/src/numpy/scalars.cpp
@@ -0,0 +1,36 @@
+// Copyright Jim Bosch 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 BOOST_PYTHON_NUMPY_INTERNAL
+#include <boost/python/numpy/internal.hpp>
+
+namespace boost { namespace python {
+namespace converter
+{
+NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyVoidArrType_Type, numpy::void_)
+} // namespace boost::python::converter
+
+namespace numpy
+{
+
+void_::void_(Py_ssize_t size)
+ : object(python::detail::new_reference
+ (PyObject_CallFunction((PyObject*)&PyVoidArrType_Type, const_cast<char*>("i"), size)))
+{}
+
+void_ void_::view(dtype const & dt) const
+{
+ return void_(python::detail::new_reference
+ (PyObject_CallMethod(this->ptr(), const_cast<char*>("view"), const_cast<char*>("O"), dt.ptr())));
+}
+
+void_ void_::copy() const
+{
+ return void_(python::detail::new_reference
+ (PyObject_CallMethod(this->ptr(), const_cast<char*>("copy"), const_cast<char*>(""))));
+}
+
+}}} // namespace boost::python::numpy
diff --git a/src/boost/libs/python/src/numpy/ufunc.cpp b/src/boost/libs/python/src/numpy/ufunc.cpp
new file mode 100644
index 000000000..173d7213e
--- /dev/null
+++ b/src/boost/libs/python/src/numpy/ufunc.cpp
@@ -0,0 +1,65 @@
+// Copyright Jim Bosch 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 BOOST_PYTHON_NUMPY_INTERNAL
+#include <boost/python/numpy/internal.hpp>
+#include <boost/python/numpy/ufunc.hpp>
+
+namespace boost { namespace python {
+namespace converter
+{
+NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArrayMultiIter_Type, numpy::multi_iter)
+} // namespace boost::python::converter
+
+namespace numpy
+{
+
+multi_iter make_multi_iter(object const & a1)
+{
+ return multi_iter(python::detail::new_reference(PyArray_MultiIterNew(1, a1.ptr())));
+}
+
+ multi_iter make_multi_iter(object const & a1, object const & a2)
+{
+ return multi_iter(python::detail::new_reference(PyArray_MultiIterNew(2, a1.ptr(), a2.ptr())));
+}
+
+multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3)
+{
+ return multi_iter(python::detail::new_reference(PyArray_MultiIterNew(3, a1.ptr(), a2.ptr(), a3.ptr())));
+}
+
+void multi_iter::next()
+{
+ PyArray_MultiIter_NEXT(ptr());
+}
+
+bool multi_iter::not_done() const
+{
+ return PyArray_MultiIter_NOTDONE(ptr());
+}
+
+char * multi_iter::get_data(int i) const
+{
+ return reinterpret_cast<char*>(PyArray_MultiIter_DATA(ptr(), i));
+}
+
+int multi_iter::get_nd() const
+{
+ return reinterpret_cast<PyArrayMultiIterObject*>(ptr())->nd;
+}
+
+Py_intptr_t const * multi_iter::get_shape() const
+{
+ return reinterpret_cast<PyArrayMultiIterObject*>(ptr())->dimensions;
+}
+
+Py_intptr_t multi_iter::shape(int n) const
+{
+ return reinterpret_cast<PyArrayMultiIterObject*>(ptr())->dimensions[n];
+}
+
+}}} // namespace boost::python::numpy
diff --git a/src/boost/libs/python/src/object/class.cpp b/src/boost/libs/python/src/object/class.cpp
new file mode 100644
index 000000000..9bb9683a3
--- /dev/null
+++ b/src/boost/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(), (char*)NULL, (char*)NULL, 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(), (char*)NULL, 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/src/boost/libs/python/src/object/enum.cpp b/src/boost/libs/python/src/object/enum.cpp
new file mode 100644
index 000000000..10122ad1d
--- /dev/null
+++ b/src/boost/libs/python/src/object/enum.cpp
@@ -0,0 +1,252 @@
+// 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 void
+ enum_dealloc(enum_object* self)
+ {
+ Py_XDECREF(self->name);
+ Py_TYPE(self)->tp_free((PyObject*)self);
+ }
+
+ static PyObject* enum_repr(PyObject* self_)
+ {
+ PyObject *mod = PyObject_GetAttrString( self_, "__module__");
+ object auto_free = object(handle<>(mod));
+ 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 */
+ (destructor) enum_dealloc, /* 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/src/boost/libs/python/src/object/function.cpp b/src/boost/libs/python/src/object/function.cpp
new file mode 100644
index 000000000..9d4745d10
--- /dev/null
+++ b/src/boost/libs/python/src/object/function.cpp
@@ -0,0 +1,789 @@
+// 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
+ {
+ // 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();
+
+ assert(!PyErr_Occurred());
+ handle<> existing(allow_null(::PyObject_GetItem(dict.get(), name.ptr())));
+ PyErr_Clear();
+
+ 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;
+
+ assert(!PyErr_Occurred());
+ handle<> name_space_name(
+ allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
+ PyErr_Clear();
+
+ if (name_space_name)
+ new_func->m_namespace = object(name_space_name);
+ }
+
+ 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/src/boost/libs/python/src/object/function_doc_signature.cpp b/src/boost/libs/python/src/object/function_doc_signature.cpp
new file mode 100644
index 000000000..41695285a
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/object/inheritance.cpp b/src/boost/libs/python/src/object/inheritance.cpp
new file mode 100644
index 000000000..7dc9db1cd
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/object/iterator.cpp b/src/boost/libs/python/src/object/iterator.cpp
new file mode 100644
index 000000000..3f6c4adac
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/object/life_support.cpp b/src/boost/libs/python/src/object/life_support.cpp
new file mode 100644
index 000000000..b7e9aa861
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/object/pickle_support.cpp b/src/boost/libs/python/src/object/pickle_support.cpp
new file mode 100644
index 000000000..428c07b6c
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/object/stl_iterator.cpp b/src/boost/libs/python/src/object/stl_iterator.cpp
new file mode 100644
index 000000000..e32d32145
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/object_operators.cpp b/src/boost/libs/python/src/object_operators.cpp
new file mode 100644
index 000000000..b993245fe
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/object_protocol.cpp b/src/boost/libs/python/src/object_protocol.cpp
new file mode 100644
index 000000000..95c8c73ee
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/slice.cpp b/src/boost/libs/python/src/slice.cpp
new file mode 100644
index 000000000..ee55f9484
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/str.cpp b/src/boost/libs/python/src/str.cpp
new file mode 100644
index 000000000..5122f7f57
--- /dev/null
+++ b/src/boost/libs/python/src/str.cpp
@@ -0,0 +1,419 @@
+// 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;
+}
+
+bool str_base::endswith(object_cref suffix, object_cref start) const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix,start).ptr());
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return result;
+}
+
+bool str_base::endswith(object_cref suffix, object_cref start, object_cref end) const
+{
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix,start,end).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/src/boost/libs/python/src/tuple.cpp b/src/boost/libs/python/src/tuple.cpp
new file mode 100644
index 000000000..6719713b7
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/src/wrapper.cpp b/src/boost/libs/python/src/wrapper.cpp
new file mode 100644
index 000000000..f8feaef94
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/Jamfile b/src/boost/libs/python/test/Jamfile
new file mode 100644
index 000000000..9a5c75695
--- /dev/null
+++ b/src/boost/libs/python/test/Jamfile
@@ -0,0 +1,257 @@
+# 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 ;
+import ../../config/checks/config : requires ;
+
+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 ;
+ }
+}
+
+if [ python.configured ]
+{
+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 boost_shared_ptr ]
+[ bpl-test shared_ptr
+ : # sources
+ : [ requires cxx11_smart_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
+ : [ requires auto_ptr ]
+]
+
+[ bpl-test polymorphism ]
+[ bpl-test polymorphism2 ]
+
+[ bpl-test auto_ptr
+ : # files
+ : [ requires auto_ptr ]
+]
+
+[ bpl-test minimal ]
+[ bpl-test args ]
+[ bpl-test raw_ctor ]
+[ bpl-test enum : test_enum.py enum_ext.cpp ]
+[ 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 : 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 ]
+
+# --- NumPy tests ---
+
+[ numpy-test numpy/dtype ]
+[ numpy-test numpy/ufunc ]
+[ numpy-test numpy/templates ]
+[ numpy-test numpy/ndarray ]
+[ numpy-test numpy/indexing ]
+[ numpy-test numpy/shapes ]
+
+
+ ;
+}
diff --git a/src/boost/libs/python/test/a_map_indexing_suite.cpp b/src/boost/libs/python/test/a_map_indexing_suite.cpp
new file mode 100644
index 000000000..07a0a6b97
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/andreas_beyer.cpp b/src/boost/libs/python/test/andreas_beyer.cpp
new file mode 100644
index 000000000..b28b15660
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/andreas_beyer.py b/src/boost/libs/python/test/andreas_beyer.py
new file mode 100644
index 000000000..0c24969bd
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/args.cpp b/src/boost/libs/python/test/args.cpp
new file mode 100644
index 000000000..592a8e505
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/args.py b/src/boost/libs/python/test/args.py
new file mode 100644
index 000000000..e884c06be
--- /dev/null
+++ b/src/boost/libs/python/test/args.py
@@ -0,0 +1,148 @@
+# 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 __future__ import print_function
+"""
+>>> 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(), end=' ')
+... print(f(q, n = 1).value(), end=' ')
+... print(f(q, n = 0).value(), end=' ')
+... 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/src/boost/libs/python/test/as_to_python_function.cpp b/src/boost/libs/python/test/as_to_python_function.cpp
new file mode 100644
index 000000000..cc083890a
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/auto_ptr.cpp b/src/boost/libs/python/test/auto_ptr.cpp
new file mode 100644
index 000000000..0f61e96dc
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/auto_ptr.py b/src/boost/libs/python/test/auto_ptr.py
new file mode 100644
index 000000000..12e977d06
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/back_reference.cpp b/src/boost/libs/python/test/back_reference.cpp
new file mode 100644
index 000000000..266ed2912
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/back_reference.py b/src/boost/libs/python/test/back_reference.py
new file mode 100644
index 000000000..4a283a3e3
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bases.cpp b/src/boost/libs/python/test/bases.cpp
new file mode 100644
index 000000000..4e00f5448
--- /dev/null
+++ b/src/boost/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/python/detail/type_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::python::detail::is_same<collected1::type,boost::python::bases<> >::value));
+ BOOST_STATIC_ASSERT((boost::python::detail::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::python::detail::is_same<collected2::type,boost::python::bases<A,B> >::value));
+ BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose_bases<int,boost::python::bases<A,B>,long>::type,boost::python::bases<A,B> >::value));
+
+ return 0;
+}
diff --git a/src/boost/libs/python/test/ben_scott1.cpp b/src/boost/libs/python/test/ben_scott1.cpp
new file mode 100644
index 000000000..5a675e230
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/ben_scott1.py b/src/boost/libs/python/test/ben_scott1.py
new file mode 100644
index 000000000..79130757a
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman1.cpp b/src/boost/libs/python/test/bienstman1.cpp
new file mode 100644
index 000000000..dc0065784
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman1.py b/src/boost/libs/python/test/bienstman1.py
new file mode 100644
index 000000000..16dc47b2d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman2.cpp b/src/boost/libs/python/test/bienstman2.cpp
new file mode 100644
index 000000000..10f99923d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman2.py b/src/boost/libs/python/test/bienstman2.py
new file mode 100644
index 000000000..931fae8f7
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman3.cpp b/src/boost/libs/python/test/bienstman3.cpp
new file mode 100644
index 000000000..d765b303d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman3.py b/src/boost/libs/python/test/bienstman3.py
new file mode 100644
index 000000000..d0d250aea
--- /dev/null
+++ b/src/boost/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 as 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/src/boost/libs/python/test/bienstman4.cpp b/src/boost/libs/python/test/bienstman4.cpp
new file mode 100644
index 000000000..34b9e211f
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman4.py b/src/boost/libs/python/test/bienstman4.py
new file mode 100644
index 000000000..eea33ba2a
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman5.cpp b/src/boost/libs/python/test/bienstman5.cpp
new file mode 100644
index 000000000..657dadd12
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/bienstman5.py b/src/boost/libs/python/test/bienstman5.py
new file mode 100644
index 000000000..a6735d942
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/boost_shared_ptr.cpp b/src/boost/libs/python/test/boost_shared_ptr.cpp
new file mode 100644
index 000000000..57e50aa3c
--- /dev/null
+++ b/src/boost/libs/python/test/boost_shared_ptr.cpp
@@ -0,0 +1,20 @@
+// Copyright David Abrahams 2002.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 <memory>
+
+using boost::shared_ptr;
+#define MODULE boost_shared_ptr_ext
+
+#include "shared_ptr.hpp"
+#include "module_tail.cpp"
+
diff --git a/src/boost/libs/python/test/boost_shared_ptr.py b/src/boost/libs/python/test/boost_shared_ptr.py
new file mode 100644
index 000000000..31a2ad3d2
--- /dev/null
+++ b/src/boost/libs/python/test/boost_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 boost_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 'boost_shared_ptr_ext.Y'>
+>>> type(factory(42))
+<class 'boost_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/src/boost/libs/python/test/borrowed.cpp b/src/boost/libs/python/test/borrowed.cpp
new file mode 100644
index 000000000..2c1bd1b7a
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/builtin_converters.cpp b/src/boost/libs/python/test/builtin_converters.cpp
new file mode 100644
index 000000000..f66e61bd8
--- /dev/null
+++ b/src/boost/libs/python/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/src/boost/libs/python/test/callbacks.cpp b/src/boost/libs/python/test/callbacks.cpp
new file mode 100644
index 000000000..66bd35240
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/callbacks.py b/src/boost/libs/python/test/callbacks.py
new file mode 100644
index 000000000..cf876a89d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/calling_conventions.cpp b/src/boost/libs/python/test/calling_conventions.cpp
new file mode 100644
index 000000000..c1c2b5a41
--- /dev/null
+++ b/src/boost/libs/python/test/calling_conventions.cpp
@@ -0,0 +1,160 @@
+//
+// 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
+
+#if defined(_WIN32) && !defined(_WIN64)
+# define BOOST_PYTHON_ENABLE_CDECL
+# define BOOST_PYTHON_ENABLE_STDCALL
+# define BOOST_PYTHON_ENABLE_FASTCALL
+#endif
+#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/src/boost/libs/python/test/calling_conventions.py b/src/boost/libs/python/test/calling_conventions.py
new file mode 100644
index 000000000..c57142448
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/calling_conventions_mf.cpp b/src/boost/libs/python/test/calling_conventions_mf.cpp
new file mode 100644
index 000000000..83a97acfe
--- /dev/null
+++ b/src/boost/libs/python/test/calling_conventions_mf.cpp
@@ -0,0 +1,161 @@
+//
+// 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
+
+#if defined(_WIN32) && !defined(_WIN64)
+# define BOOST_PYTHON_ENABLE_CDECL
+# define BOOST_PYTHON_ENABLE_STDCALL
+# define BOOST_PYTHON_ENABLE_FASTCALL
+#endif
+#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/src/boost/libs/python/test/calling_conventions_mf.py b/src/boost/libs/python/test/calling_conventions_mf.py
new file mode 100644
index 000000000..7e28484b9
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/class.cpp b/src/boost/libs/python/test/class.cpp
new file mode 100644
index 000000000..078bebdf6
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/class.py b/src/boost/libs/python/test/class.py
new file mode 100644
index 000000000..15594a105
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/cltree.cpp b/src/boost/libs/python/test/cltree.cpp
new file mode 100644
index 000000000..518ae37fe
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/complicated.hpp b/src/boost/libs/python/test/complicated.hpp
new file mode 100644
index 000000000..5ff19aea0
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/const_argument.cpp b/src/boost/libs/python/test/const_argument.cpp
new file mode 100644
index 000000000..279c3dc1a
--- /dev/null
+++ b/src/boost/libs/python/test/const_argument.cpp
@@ -0,0 +1,28 @@
+/* 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>
+using namespace boost::python;
+
+
+#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/src/boost/libs/python/test/const_argument.py b/src/boost/libs/python/test/const_argument.py
new file mode 100644
index 000000000..1d241953b
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/copy_ctor_mutates_rhs.cpp b/src/boost/libs/python/test/copy_ctor_mutates_rhs.cpp
new file mode 100644
index 000000000..41eac495e
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/crossmod_exception.py b/src/boost/libs/python/test/crossmod_exception.py
new file mode 100644
index 000000000..4820f29e9
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/crossmod_exception_a.cpp b/src/boost/libs/python/test/crossmod_exception_a.cpp
new file mode 100644
index 000000000..9526129af
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/crossmod_exception_b.cpp b/src/boost/libs/python/test/crossmod_exception_b.cpp
new file mode 100644
index 000000000..e2ea491ca
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/crossmod_opaque.py b/src/boost/libs/python/test/crossmod_opaque.py
new file mode 100644
index 000000000..533ac16fe
--- /dev/null
+++ b/src/boost/libs/python/test/crossmod_opaque.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# 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/src/boost/libs/python/test/crossmod_opaque_a.cpp b/src/boost/libs/python/test/crossmod_opaque_a.cpp
new file mode 100644
index 000000000..62ed43311
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/crossmod_opaque_b.cpp b/src/boost/libs/python/test/crossmod_opaque_b.cpp
new file mode 100644
index 000000000..3d661339c
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/data_members.cpp b/src/boost/libs/python/test/data_members.cpp
new file mode 100644
index 000000000..6d2cc7bd4
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/data_members.py b/src/boost/libs/python/test/data_members.py
new file mode 100644
index 000000000..74b655eb5
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/defaults.cpp b/src/boost/libs/python/test/defaults.cpp
new file mode 100644
index 000000000..6d87e5d6e
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/defaults.py b/src/boost/libs/python/test/defaults.py
new file mode 100644
index 000000000..cf3cfd38f
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/destroy_test.cpp b/src/boost/libs/python/test/destroy_test.cpp
new file mode 100644
index 000000000..57501604b
--- /dev/null
+++ b/src/boost/libs/python/test/destroy_test.cpp
@@ -0,0 +1,58 @@
+// 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);
+
+ 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/src/boost/libs/python/test/dict.cpp b/src/boost/libs/python/test/dict.cpp
new file mode 100644
index 000000000..375905d69
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/dict.py b/src/boost/libs/python/test/dict.py
new file mode 100644
index 000000000..72c37d99e
--- /dev/null
+++ b/src/boost/libs/python/test/dict.py
@@ -0,0 +1,46 @@
+# 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 __future__ import print_function
+"""
+>>> from dict_ext import *
+>>> def printer(*args):
+... for x in args: print(x, end='')
+... 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/src/boost/libs/python/test/docstring.cpp b/src/boost/libs/python/test/docstring.cpp
new file mode 100644
index 000000000..c6cc0252b
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/docstring.py b/src/boost/libs/python/test/docstring.py
new file mode 100644
index 000000000..2727bd6d5
--- /dev/null
+++ b/src/boost/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 as 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/src/boost/libs/python/test/enable_shared_from_this.cpp b/src/boost/libs/python/test/enable_shared_from_this.cpp
new file mode 100644
index 000000000..c246284a1
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/enable_shared_from_this.py b/src/boost/libs/python/test/enable_shared_from_this.py
new file mode 100644
index 000000000..d7ac7a999
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/enum_ext.cpp b/src/boost/libs/python/test/enum_ext.cpp
new file mode 100644
index 000000000..74224f1d7
--- /dev/null
+++ b/src/boost/libs/python/test/enum_ext.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/python/detail/type_traits.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 boost::python::detail::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/src/boost/libs/python/test/exception_translator.cpp b/src/boost/libs/python/test/exception_translator.cpp
new file mode 100644
index 000000000..1e91c9296
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/exception_translator.py b/src/boost/libs/python/test/exception_translator.py
new file mode 100644
index 000000000..1d80aba3a
--- /dev/null
+++ b/src/boost/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 as 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/src/boost/libs/python/test/exec.cpp b/src/boost/libs/python/test/exec.cpp
new file mode 100644
index 000000000..72ff571bd
--- /dev/null
+++ b/src/boost/libs/python/test/exec.cpp
@@ -0,0 +1,197 @@
+// 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()
+{
+ // 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];
+
+ // 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)
+ {
+ BOOST_ERROR("Failed to add embedded_hello to the interpreter's "
+ "builtin modules");
+ }
+
+ // 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/src/boost/libs/python/test/exec.py b/src/boost/libs/python/test/exec.py
new file mode 100644
index 000000000..c7bf28f35
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/extract.cpp b/src/boost/libs/python/test/extract.cpp
new file mode 100644
index 000000000..40584a077
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/extract.py b/src/boost/libs/python/test/extract.py
new file mode 100644
index 000000000..feda93a1d
--- /dev/null
+++ b/src/boost/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 as 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/src/boost/libs/python/test/fabscript b/src/boost/libs/python/test/fabscript
new file mode 100644
index 000000000..1989cc0d1
--- /dev/null
+++ b/src/boost/libs/python/test/fabscript
@@ -0,0 +1,173 @@
+# -*- python -*-
+#
+# Copyright (c) 2016 Stefan Seefeld
+# All rights reserved.
+#
+# Distributed under the 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 faber import platform
+from faber.feature import set
+from faber.tools.compiler import runpath
+from faber.tools.python import python, pythonpath
+from faber.artefacts.object import object
+from faber.artefacts.binary import binary
+from faber.artefacts.python import extension
+from faber.test import test, report, fail
+
+src = module('..src')
+
+python_libs=python.instance().libs
+features |= runpath(src.bpl.path, base='')
+
+def extension_test(name, ext=[], script=None, np=False,
+ features=features, condition=None):
+ """Create a Python extension test `name`.
+ Arguments:
+ * name: the name of the test.
+ * ext: extensions to be compiled, <name> if none are given.
+ * script: the test script to execute, <name>.py if none is given.
+ * np: if true, add boost_numpy to sources
+ * features: pre-defined features
+ * condition: any condition under which to run the test
+ Return:
+ * the test artefact"""
+
+ features=features.copy()
+ extensions = []
+ libs = [src.bnl, src.bpl] if np else [src.bpl]
+ for e in ext or [name]:
+ if type(e) is str: # build from a single source file
+ n = e if e != name else e + '_ext'
+ s = [e + '.cpp']
+ else: # build from a list of source files
+ n = e[0] if e[0] != name else e[0] + '_ext'
+ s = [n + '.cpp' for n in e]
+ e = extension(n, s + libs, features=features)
+ features |= pythonpath(e.path, base='')
+ extensions.append(e)
+ if not script:
+ script = name+'.py'
+ return test(name, script, run=python.run, dependencies=extensions,
+ features=features, condition=condition)
+
+tests = []
+for t in [('injected',),
+ ('properties',),
+ ('return_arg',),
+ ('staticmethod',),
+ ('boost_shared_ptr',),
+ ('enable_shared_from_this',),
+ ('andreas_beyer',),
+ ('polymorphism',),
+ ('polymorphism2',),
+ ('wrapper_held_type',),
+ ('minimal',),
+ ('args',),
+ ('raw_ctor',),
+ ('exception_translator',),
+ ('test_enum', ['enum_ext']),
+ ('test_cltree', ['cltree']),
+ ('newtest', ['m1', 'm2']),
+ ('const_argument',),
+ ('keywords_test', ['keywords']),
+ ('test_pointer_adoption',),
+ ('operators',),
+ ('operators_wrapper',),
+ ('callbacks',),
+ ('defaults',),
+ ('object',),
+ ('list',),
+ ('long',),
+ ('dict',),
+ ('tuple',),
+ ('str',),
+ ('slice',),
+ ('virtual_functions',),
+ ('back_reference',),
+ ('implicit',),
+ ('data_members',),
+ ('ben_scott1',),
+ ('bienstman1',),
+ ('bienstman2',),
+ ('bienstman3',),
+ ('multi_arg_constructor',),
+ ('iterator', ['iterator', 'input_iterator']),
+ ('stl_iterator',),
+ ('extract',),
+ ('crossmod_opaque', ['crossmod_opaque_a', 'crossmod_opaque_b']),
+ ('opaque',),
+ ('voidptr',),
+ ('pickle1',),
+ ('pickle2',),
+ ('pickle3',),
+ ('pickle4',),
+ ('nested',),
+ ('docstring',),
+ ('pytype_function',),
+ ('vector_indexing_suite',),
+ ('pointer_vector',),
+ ('builtin_converters', [], 'test_builtin_converters.py'),
+ ('map_indexing_suite',
+ [['map_indexing_suite', 'int_map_indexing_suite', 'a_map_indexing_suite']])]:
+ tests.append(extension_test(*t))
+
+tests.append(extension_test('shared_ptr',
+ condition=set.define.contains('HAS_CXX11')))
+tests.append(extension_test('polymorphism2_auto_ptr',
+ condition=set.define.contains('HAS_CXX11').not_()))
+tests.append(extension_test('auto_ptr',
+ condition=set.define.contains('HAS_CXX11')))
+
+import_ = binary('import_', ['import_.cpp', src.bpl], features=features|python_libs)
+if platform.os == 'Windows':
+ command = """set PATH=$(runpath);%PATH%
+$(>[1]) $(>[2])"""
+else:
+ command = 'LD_LIBRARY_PATH=$(runpath) $(>[1]) $(>[2])'
+
+tests.append(test('import', [import_, 'import_.py'],
+ run=action('run', command),
+ features=features))
+
+tests.append(extension_test('calling_conventions',
+ condition=platform.os == 'Windows'))
+tests.append(extension_test('calling_conventions_mf',
+ condition=platform.os == 'Windows'))
+
+for t in ['destroy_test',
+ 'pointer_type_id_test',
+ 'bases',
+ 'pointee',
+ 'if_else',
+ 'pointee',
+ 'result',
+ 'upcast',
+ 'select_from_python_test']:
+ tests.append(test(t, binary(t, [t + '.cpp', src.bpl], features=features), features=features, run=True))
+for t in ['indirect_traits_test',
+ 'string_literal',
+ 'borrowed',
+ 'object_manager',
+ 'copy_ctor_mutates_rhs',
+ 'select_holder',
+ 'select_arg_to_python_test']:
+ tests.append(test(t, object(t, [t + '.cpp'], features=features)))
+
+for t in ['raw_pyobject_fail1',
+ 'raw_pyobject_fail2',
+ 'as_to_python_function',
+ 'object_fail1']:
+ tests.append(test(t, object(t, [t + '.cpp'], features=features), expected=fail))
+
+for t in ['numpy/dtype',
+ 'numpy/ufunc',
+ 'numpy/templates',
+ 'numpy/ndarray',
+ 'numpy/indexing',
+ 'numpy/shapes']:
+ tests.append(extension_test(t, np=True,
+ condition=set.define.contains('HAS_NUMPY')))
+
+default = report('report', tests, fail_on_failures=True)
diff --git a/src/boost/libs/python/test/if_else.cpp b/src/boost/libs/python/test/if_else.cpp
new file mode 100644
index 000000000..60cc53192
--- /dev/null
+++ b/src/boost/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/python/detail/type_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::python::detail::is_same<choose<1>::type,c1>::value));
+ BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<2>::type,c2>::value));
+ BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<3>::type,c3>::value));
+ BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<4>::type,c4>::value));
+ BOOST_STATIC_ASSERT((boost::python::detail::is_same<choose<5>::type,void*>::value));
+ return 0;
+}
diff --git a/src/boost/libs/python/test/implicit.cpp b/src/boost/libs/python/test/implicit.cpp
new file mode 100644
index 000000000..a1bae59e8
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/implicit.py b/src/boost/libs/python/test/implicit.py
new file mode 100644
index 000000000..f2aa3e1d3
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/import_.cpp b/src/boost/libs/python/test/import_.cpp
new file mode 100644
index 000000000..3e21de0ba
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/import_.py b/src/boost/libs/python/test/import_.py
new file mode 100644
index 000000000..48de6e5ec
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/indirect_traits_test.cpp b/src/boost/libs/python/test/indirect_traits_test.cpp
new file mode 100644
index 000000000..da4cc2456
--- /dev/null
+++ b/src/boost/libs/python/test/indirect_traits_test.cpp
@@ -0,0 +1,116 @@
+// 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/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/src/boost/libs/python/test/injected.cpp b/src/boost/libs/python/test/injected.cpp
new file mode 100644
index 000000000..73e1e14ba
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/injected.py b/src/boost/libs/python/test/injected.py
new file mode 100644
index 000000000..c50215048
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/input_iterator.cpp b/src/boost/libs/python/test/input_iterator.cpp
new file mode 100644
index 000000000..70b994186
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/int_map_indexing_suite.cpp b/src/boost/libs/python/test/int_map_indexing_suite.cpp
new file mode 100644
index 000000000..397850131
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/iterator.cpp b/src/boost/libs/python/test/iterator.cpp
new file mode 100644
index 000000000..458ba2926
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/iterator.py b/src/boost/libs/python/test/iterator.py
new file mode 100644
index 000000000..314a35676
--- /dev/null
+++ b/src/boost/libs/python/test/iterator.py
@@ -0,0 +1,78 @@
+# 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 __future__ import print_function
+'''
+>>> 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, end='')
+... 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/src/boost/libs/python/test/keywords.cpp b/src/boost/libs/python/test/keywords.cpp
new file mode 100644
index 000000000..39bac0627
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/keywords_test.py b/src/boost/libs/python/test/keywords_test.py
new file mode 100644
index 000000000..bac7d17c1
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/list.cpp b/src/boost/libs/python/test/list.cpp
new file mode 100644
index 000000000..3e9fcbe66
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/list.py b/src/boost/libs/python/test/list.py
new file mode 100644
index 000000000..913032db8
--- /dev/null
+++ b/src/boost/libs/python/test/list.py
@@ -0,0 +1,119 @@
+# 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 __future__ import print_function
+'''
+>>> 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/src/boost/libs/python/test/long.cpp b/src/boost/libs/python/test/long.cpp
new file mode 100644
index 000000000..61e4518ff
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/long.py b/src/boost/libs/python/test/long.py
new file mode 100644
index 000000000..f63923632
--- /dev/null
+++ b/src/boost/libs/python/test/long.py
@@ -0,0 +1,36 @@
+# 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 sys
+if (sys.version_info.major >= 3):
+ long = int
+'''
+>>> from long_ext import *
+>>> print(new_long())
+0
+>>> print(longify(42))
+42
+>>> print(longify_string('300'))
+300
+>>> is_long(long(20))
+'yes'
+>>> is_long('20')
+0
+
+>>> x = Y(long(4294967295))
+'''
+
+def run(args = None):
+ import sys
+ import doctest
+
+ if args is not None:
+ sys.argv = args
+ return doctest.testmod(sys.modules.get(__name__))
+
+if __name__ == '__main__':
+ print("running...")
+ import sys
+ status = run()[0]
+ if (status == 0): print("Done.")
+ sys.exit(status)
diff --git a/src/boost/libs/python/test/m1.cpp b/src/boost/libs/python/test/m1.cpp
new file mode 100644
index 000000000..a873bc35d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/m2.cpp b/src/boost/libs/python/test/m2.cpp
new file mode 100644
index 000000000..5bcdea604
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/map_indexing_suite.cpp b/src/boost/libs/python/test/map_indexing_suite.cpp
new file mode 100644
index 000000000..b8771cf41
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/map_indexing_suite.py b/src/boost/libs/python/test/map_indexing_suite.py
new file mode 100644
index 000000000..a5750a833
--- /dev/null
+++ b/src/boost/libs/python/test/map_indexing_suite.py
@@ -0,0 +1,243 @@
+# 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)
+from __future__ import print_function
+'''
+
+#####################################################################
+# 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(), end='')
+... 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/src/boost/libs/python/test/minimal.cpp b/src/boost/libs/python/test/minimal.cpp
new file mode 100644
index 000000000..5efee26bc
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/minimal.py b/src/boost/libs/python/test/minimal.py
new file mode 100644
index 000000000..ee75e3705
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/module_tail.cpp b/src/boost/libs/python/test/module_tail.cpp
new file mode 100644
index 000000000..f9cdca189
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/multi_arg_constructor.cpp b/src/boost/libs/python/test/multi_arg_constructor.cpp
new file mode 100644
index 000000000..7d49bb556
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/multi_arg_constructor.py b/src/boost/libs/python/test/multi_arg_constructor.py
new file mode 100644
index 000000000..5d8b4a516
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/nested.cpp b/src/boost/libs/python/test/nested.cpp
new file mode 100644
index 000000000..de656d2b8
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/nested.py b/src/boost/libs/python/test/nested.py
new file mode 100644
index 000000000..720790173
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/newtest.py b/src/boost/libs/python/test/newtest.py
new file mode 100644
index 000000000..b878d5192
--- /dev/null
+++ b/src/boost/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 as 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/src/boost/libs/python/test/numpy/dtype.cpp b/src/boost/libs/python/test/numpy/dtype.cpp
new file mode 100644
index 000000000..3a011a25e
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/dtype.cpp
@@ -0,0 +1,49 @@
+// Copyright Jim Bosch & Ankit Daftery 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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/numpy.hpp>
+#include <boost/cstdint.hpp>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+template <typename T>
+np::dtype accept(T) {
+ return np::dtype::get_builtin<T>();
+}
+
+BOOST_PYTHON_MODULE(dtype_ext)
+{
+ np::initialize();
+ // wrap dtype equivalence test, since it isn't available in Python API.
+ p::def("equivalent", np::equivalent);
+ // integers, by number of bits
+ p::def("accept_int8", accept<boost::int8_t>);
+ p::def("accept_uint8", accept<boost::uint8_t>);
+ p::def("accept_int16", accept<boost::int16_t>);
+ p::def("accept_uint16", accept<boost::uint16_t>);
+ p::def("accept_int32", accept<boost::int32_t>);
+ p::def("accept_uint32", accept<boost::uint32_t>);
+ p::def("accept_int64", accept<boost::int64_t>);
+ p::def("accept_uint64", accept<boost::uint64_t>);
+ // integers, by C name according to NumPy
+ p::def("accept_bool_", accept<bool>);
+ p::def("accept_byte", accept<signed char>);
+ p::def("accept_ubyte", accept<unsigned char>);
+ p::def("accept_short", accept<short>);
+ p::def("accept_ushort", accept<unsigned short>);
+ p::def("accept_intc", accept<int>);
+ p::def("accept_uintc", accept<unsigned int>);
+ // floats and complex
+ p::def("accept_float32", accept<float>);
+ p::def("accept_complex64", accept< std::complex<float> >);
+ p::def("accept_float64", accept<double>);
+ p::def("accept_complex128", accept< std::complex<double> >);
+ if (sizeof(long double) > sizeof(double)) {
+ p::def("accept_longdouble", accept<long double>);
+ p::def("accept_clongdouble", accept< std::complex<long double> >);
+ }
+}
diff --git a/src/boost/libs/python/test/numpy/dtype.py b/src/boost/libs/python/test/numpy/dtype.py
new file mode 100644
index 000000000..a27ee0f55
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/dtype.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+# Copyright Jim Bosch & Ankit Daftery 2010-2012.
+# Distributed under the 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 dtype_ext
+import unittest
+import numpy
+import sys
+if (sys.version_info.major >= 3):
+ long = int
+
+class DtypeTestCase(unittest.TestCase):
+
+ def assertEquivalent(self, a, b):
+ return self.assert_(dtype_ext.equivalent(a, b), "%r is not equivalent to %r")
+
+ def testIntegers(self):
+ for bits in (8, 16, 32, 64):
+ s = getattr(numpy, "int%d" % bits)
+ u = getattr(numpy, "uint%d" % bits)
+ fs = getattr(dtype_ext, "accept_int%d" % bits)
+ fu = getattr(dtype_ext, "accept_uint%d" % bits)
+ self.assertEquivalent(fs(s(1)), numpy.dtype(s))
+ self.assertEquivalent(fu(u(1)), numpy.dtype(u))
+ # these should just use the regular Boost.Python converters
+ self.assertEquivalent(fs(True), numpy.dtype(s))
+ self.assertEquivalent(fu(True), numpy.dtype(u))
+ self.assertEquivalent(fs(int(1)), numpy.dtype(s))
+ self.assertEquivalent(fu(int(1)), numpy.dtype(u))
+ self.assertEquivalent(fs(long(1)), numpy.dtype(s))
+ self.assertEquivalent(fu(long(1)), numpy.dtype(u))
+ for name in ("bool_", "byte", "ubyte", "short", "ushort", "intc", "uintc"):
+ t = getattr(numpy, name)
+ ft = getattr(dtype_ext, "accept_%s" % name)
+ self.assertEquivalent(ft(t(1)), numpy.dtype(t))
+ # these should just use the regular Boost.Python converters
+ self.assertEquivalent(ft(True), numpy.dtype(t))
+ if name != "bool_":
+ self.assertEquivalent(ft(int(1)), numpy.dtype(t))
+ self.assertEquivalent(ft(long(1)), numpy.dtype(t))
+
+
+ def testFloats(self):
+ f = numpy.float32
+ c = numpy.complex64
+ self.assertEquivalent(dtype_ext.accept_float32(f(numpy.pi)), numpy.dtype(f))
+ self.assertEquivalent(dtype_ext.accept_complex64(c(1+2j)), numpy.dtype(c))
+ f = numpy.float64
+ c = numpy.complex128
+ self.assertEquivalent(dtype_ext.accept_float64(f(numpy.pi)), numpy.dtype(f))
+ self.assertEquivalent(dtype_ext.accept_complex128(c(1+2j)), numpy.dtype(c))
+ if hasattr(numpy, "longdouble") and hasattr(dtype_ext, "accept_longdouble"):
+ f = numpy.longdouble
+ c = numpy.clongdouble
+ self.assertEquivalent(dtype_ext.accept_longdouble(f(numpy.pi)), numpy.dtype(f))
+ self.assertEquivalent(dtype_ext.accept_clongdouble(c(1+2j)), numpy.dtype(c))
+
+
+if __name__=="__main__":
+ unittest.main()
diff --git a/src/boost/libs/python/test/numpy/indexing.cpp b/src/boost/libs/python/test/numpy/indexing.cpp
new file mode 100644
index 000000000..f3cc45717
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/indexing.cpp
@@ -0,0 +1,28 @@
+// Copyright Jim Bosch & Ankit Daftery 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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/numpy.hpp>
+#include <boost/python/slice.hpp>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+p::object single(np::ndarray ndarr, int i) { return ndarr[i];}
+p::object slice(np::ndarray ndarr, p::slice sl) { return ndarr[sl];}
+p::object indexarray(np::ndarray ndarr, np::ndarray d1) { return ndarr[d1];}
+p::object indexarray_2d(np::ndarray ndarr, np::ndarray d1,np::ndarray d2) { return ndarr[p::make_tuple(d1,d2)];}
+p::object indexslice(np::ndarray ndarr, np::ndarray d1, p::slice sl) { return ndarr[p::make_tuple(d1, sl)];}
+
+BOOST_PYTHON_MODULE(indexing_ext)
+{
+ np::initialize();
+ p::def("single", single);
+ p::def("slice", slice);
+ p::def("indexarray", indexarray);
+ p::def("indexarray", indexarray_2d);
+ p::def("indexslice", indexslice);
+
+}
diff --git a/src/boost/libs/python/test/numpy/indexing.py b/src/boost/libs/python/test/numpy/indexing.py
new file mode 100644
index 000000000..ebd9dcbab
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/indexing.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+# Copyright Jim Bosch & Ankit Daftery 2010-2012.
+# Distributed under the 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 numpy
+import indexing_ext
+
+class TestIndexing(unittest.TestCase):
+
+ def testSingle(self):
+ x = numpy.arange(0,10)
+ for i in range(0,10):
+ numpy.testing.assert_equal(indexing_ext.single(x,i), i)
+ for i in range(-10,0):
+ numpy.testing.assert_equal(indexing_ext.single(x,i),10+i)
+
+ def testSlice(self):
+ x = numpy.arange(0,10)
+ sl = slice(3,8)
+ b = [3,4,5,6,7]
+ numpy.testing.assert_equal(indexing_ext.slice(x,sl), b)
+
+ def testStepSlice(self):
+ x = numpy.arange(0,10)
+ sl = slice(3,8,2)
+ b = [3,5,7]
+ numpy.testing.assert_equal(indexing_ext.slice(x,sl), b)
+
+ def testIndex(self):
+ x = numpy.arange(0,10)
+ chk = numpy.array([3,4,5,6])
+ numpy.testing.assert_equal(indexing_ext.indexarray(x,chk),chk)
+ chk = numpy.array([[0,1],[2,3]])
+ numpy.testing.assert_equal(indexing_ext.indexarray(x,chk),chk)
+ x = numpy.arange(9).reshape(3,3)
+ y = numpy.array([0,1])
+ z = numpy.array([0,2])
+ chk = numpy.array([0,5])
+ numpy.testing.assert_equal(indexing_ext.indexarray(x,y,z),chk)
+ x = numpy.arange(0,10)
+ b = x>4
+ chk = numpy.array([5,6,7,8,9])
+ numpy.testing.assert_equal(indexing_ext.indexarray(x,b),chk)
+ x = numpy.arange(9).reshape(3,3)
+ b = numpy.array([0,2])
+ sl = slice(0,3)
+ chk = numpy.array([[0,1,2],[6,7,8]])
+ numpy.testing.assert_equal(indexing_ext.indexslice(x,b,sl),chk)
+
+if __name__=="__main__":
+ unittest.main()
diff --git a/src/boost/libs/python/test/numpy/ndarray.cpp b/src/boost/libs/python/test/numpy/ndarray.cpp
new file mode 100644
index 000000000..75a101043
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/ndarray.cpp
@@ -0,0 +1,51 @@
+// Copyright Jim Bosch & Ankit Daftery 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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/numpy.hpp>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+np::ndarray zeros(p::tuple shape, np::dtype dt) { return np::zeros(shape, dt);}
+np::ndarray array2(p::object obj, np::dtype dt) { return np::array(obj,dt);}
+np::ndarray array1(p::object obj) { return np::array(obj);}
+np::ndarray empty1(p::tuple shape, np::dtype dt) { return np::empty(shape,dt);}
+
+np::ndarray c_empty(p::tuple shape, np::dtype dt)
+{
+ // convert 'shape' to a C array so we can test the corresponding
+ // version of the constructor
+ unsigned len = p::len(shape);
+ Py_intptr_t *c_shape = new Py_intptr_t[len];
+ for (unsigned i = 0; i != len; ++i)
+ c_shape[i] = p::extract<Py_intptr_t>(shape[i]);
+ np::ndarray result = np::empty(len, c_shape, dt);
+ delete [] c_shape;
+ return result;
+}
+
+np::ndarray transpose(np::ndarray arr) { return arr.transpose();}
+np::ndarray squeeze(np::ndarray arr) { return arr.squeeze();}
+np::ndarray reshape(np::ndarray arr,p::tuple tup) { return arr.reshape(tup);}
+
+Py_intptr_t shape_index(np::ndarray arr,int k) { return arr.shape(k); }
+Py_intptr_t strides_index(np::ndarray arr,int k) { return arr.strides(k); }
+
+BOOST_PYTHON_MODULE(ndarray_ext)
+{
+ np::initialize();
+ p::def("zeros", zeros);
+ p::def("zeros_matrix", zeros, np::as_matrix<>());
+ p::def("array", array2);
+ p::def("array", array1);
+ p::def("empty", empty1);
+ p::def("c_empty", c_empty);
+ p::def("transpose", transpose);
+ p::def("squeeze", squeeze);
+ p::def("reshape", reshape);
+ p::def("shape_index", shape_index);
+ p::def("strides_index", strides_index);
+}
diff --git a/src/boost/libs/python/test/numpy/ndarray.py b/src/boost/libs/python/test/numpy/ndarray.py
new file mode 100644
index 000000000..2acc384a5
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/ndarray.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+
+# Copyright Jim Bosch & Ankit Daftery 2010-2012.
+# Distributed under the 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 ndarray_ext
+import unittest
+import numpy
+
+class TestNdarray(unittest.TestCase):
+
+ def testNdzeros(self):
+ for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ v = numpy.zeros(60, dtype=dtp)
+ dt = numpy.dtype(dtp)
+ for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)):
+ a1 = ndarray_ext.zeros(shape,dt)
+ a2 = v.reshape(a1.shape)
+ self.assertEqual(shape,a1.shape)
+ self.assert_((a1 == a2).all())
+
+ def testNdzeros_matrix(self):
+ for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ dt = numpy.dtype(dtp)
+ shape = (6, 10)
+ a1 = ndarray_ext.zeros_matrix(shape, dt)
+ a2 = numpy.matrix(numpy.zeros(shape, dtype=dtp))
+ self.assertEqual(shape,a1.shape)
+ self.assert_((a1 == a2).all())
+ self.assertEqual(type(a1), type(a2))
+
+ def testNdarray(self):
+ a = range(0,60)
+ for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ v = numpy.array(a, dtype=dtp)
+ dt = numpy.dtype(dtp)
+ a1 = ndarray_ext.array(a)
+ a2 = ndarray_ext.array(a,dt)
+ self.assert_((a1 == v).all())
+ self.assert_((a2 == v).all())
+ for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)):
+ a1 = a1.reshape(shape)
+ self.assertEqual(shape,a1.shape)
+ a2 = a2.reshape(shape)
+ self.assertEqual(shape,a2.shape)
+
+ def testNdempty(self):
+ for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ dt = numpy.dtype(dtp)
+ for shape in ((60,),(6,10),(4,3,5),(2,2,3,5)):
+ a1 = ndarray_ext.empty(shape,dt)
+ a2 = ndarray_ext.c_empty(shape,dt)
+ self.assertEqual(shape,a1.shape)
+ self.assertEqual(shape,a2.shape)
+
+ def testTranspose(self):
+ for dtp in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ dt = numpy.dtype(dtp)
+ for shape in ((6,10),(4,3,5),(2,2,3,5)):
+ a1 = numpy.empty(shape,dt)
+ a2 = a1.transpose()
+ a1 = ndarray_ext.transpose(a1)
+ self.assertEqual(a1.shape,a2.shape)
+
+ def testSqueeze(self):
+ a1 = numpy.array([[[3,4,5]]])
+ a2 = a1.squeeze()
+ a1 = ndarray_ext.squeeze(a1)
+ self.assertEqual(a1.shape,a2.shape)
+
+ def testReshape(self):
+ a1 = numpy.empty((2,2))
+ a2 = ndarray_ext.reshape(a1,(1,4))
+ self.assertEqual(a2.shape,(1,4))
+
+ def testShapeIndex(self):
+ a = numpy.arange(24)
+ a.shape = (1,2,3,4)
+ def shape_check(i):
+ print(i)
+ self.assertEqual(ndarray_ext.shape_index(a,i) ,a.shape[i] )
+ for i in range(4):
+ shape_check(i)
+ for i in range(-1,-5,-1):
+ shape_check(i)
+ try:
+ ndarray_ext.shape_index(a,4) # out of bounds -- should raise IndexError
+ self.assertTrue(False)
+ except IndexError:
+ pass
+
+ def testStridesIndex(self):
+ a = numpy.arange(24)
+ a.shape = (1,2,3,4)
+ def strides_check(i):
+ print(i)
+ self.assertEqual(ndarray_ext.strides_index(a,i) ,a.strides[i] )
+ for i in range(4):
+ strides_check(i)
+ for i in range(-1,-5,-1):
+ strides_check(i)
+ try:
+ ndarray_ext.strides_index(a,4) # out of bounds -- should raise IndexError
+ self.assertTrue(False)
+ except IndexError:
+ pass
+
+
+if __name__=="__main__":
+ unittest.main()
diff --git a/src/boost/libs/python/test/numpy/shapes.cpp b/src/boost/libs/python/test/numpy/shapes.cpp
new file mode 100644
index 000000000..a245df155
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/shapes.cpp
@@ -0,0 +1,22 @@
+// Copyright Jim Bosch & Ankit Daftery 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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/numpy.hpp>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+np::ndarray reshape(np::ndarray old_array, p::tuple shape)
+{
+ np::ndarray local_shape = old_array.reshape(shape);
+ return local_shape;
+}
+
+BOOST_PYTHON_MODULE(shapes_ext)
+{
+ np::initialize();
+ p::def("reshape", reshape);
+}
diff --git a/src/boost/libs/python/test/numpy/shapes.py b/src/boost/libs/python/test/numpy/shapes.py
new file mode 100644
index 000000000..d0a0099ca
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/shapes.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+# Copyright Jim Bosch & Ankit Daftery 2010-2012.
+# Distributed under the 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 shapes_ext
+import unittest
+import numpy
+
+class TestShapes(unittest.TestCase):
+
+ def testShapes(self):
+ a1 = numpy.array([(0,1),(2,3)])
+ a1_shape = (1,4)
+ a1 = shapes_ext.reshape(a1,a1_shape)
+ self.assertEqual(a1_shape,a1.shape)
+
+if __name__=="__main__":
+ unittest.main()
diff --git a/src/boost/libs/python/test/numpy/templates.cpp b/src/boost/libs/python/test/numpy/templates.cpp
new file mode 100644
index 000000000..83de6bd2f
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/templates.cpp
@@ -0,0 +1,63 @@
+// Copyright Jim Bosch & Ankit Daftery 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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/numpy.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/vector_c.hpp>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+struct ArrayFiller
+{
+
+ typedef boost::mpl::vector< short, int, float, std::complex<double> > TypeSequence;
+ typedef boost::mpl::vector_c< int, 1, 2 > DimSequence;
+
+ explicit ArrayFiller(np::ndarray const & arg) : argument(arg) {}
+
+ template <typename T, int N>
+ void apply() const
+ {
+ if (N == 1)
+ {
+ char * p = argument.get_data();
+ int stride = argument.strides(0);
+ int size = argument.shape(0);
+ for (int n = 0; n != size; ++n, p += stride)
+ *reinterpret_cast<T*>(p) = static_cast<T>(n);
+ }
+ else
+ {
+ char * row_p = argument.get_data();
+ int row_stride = argument.strides(0);
+ int col_stride = argument.strides(1);
+ int rows = argument.shape(0);
+ int cols = argument.shape(1);
+ int i = 0;
+ for (int n = 0; n != rows; ++n, row_p += row_stride)
+ {
+ char * col_p = row_p;
+ for (int m = 0; m != cols; ++i, ++m, col_p += col_stride)
+ *reinterpret_cast<T*>(col_p) = static_cast<T>(i);
+ }
+ }
+ }
+
+ np::ndarray argument;
+};
+
+void fill(np::ndarray const & arg)
+{
+ ArrayFiller filler(arg);
+ np::invoke_matching_array<ArrayFiller::TypeSequence, ArrayFiller::DimSequence >(arg, filler);
+}
+
+BOOST_PYTHON_MODULE(templates_ext)
+{
+ np::initialize();
+ p::def("fill", fill);
+}
diff --git a/src/boost/libs/python/test/numpy/templates.py b/src/boost/libs/python/test/numpy/templates.py
new file mode 100755
index 000000000..8290b13a0
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/templates.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+# Copyright Jim Bosch & Ankit Daftery 2010-2012.
+# Distributed under the 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 templates_ext
+import unittest
+import numpy
+
+class TestTemplates(unittest.TestCase):
+
+ def testTemplates(self):
+ for dtype in (numpy.int16, numpy.int32, numpy.float32, numpy.complex128):
+ v = numpy.arange(12, dtype=dtype)
+ for shape in ((12,), (4, 3), (2, 6)):
+ a1 = numpy.zeros(shape, dtype=dtype)
+ a2 = v.reshape(a1.shape)
+ templates_ext.fill(a1)
+ self.assert_((a1 == a2).all())
+ a1 = numpy.zeros((12,), dtype=numpy.float64)
+ self.assertRaises(TypeError, templates_ext.fill, a1)
+ a1 = numpy.zeros((12,2,3), dtype=numpy.float32)
+ self.assertRaises(TypeError, templates_ext.fill, a1)
+
+if __name__=="__main__":
+ unittest.main()
diff --git a/src/boost/libs/python/test/numpy/ufunc.cpp b/src/boost/libs/python/test/numpy/ufunc.cpp
new file mode 100644
index 000000000..3a9d43cbb
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/ufunc.cpp
@@ -0,0 +1,36 @@
+// Copyright Jim Bosch & Ankit Daftery 2010-2012.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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/numpy.hpp>
+
+namespace p = boost::python;
+namespace np = boost::python::numpy;
+
+struct UnaryCallable
+{
+ typedef double argument_type;
+ typedef double result_type;
+
+ double operator()(double r) const { return r * 2;}
+};
+
+struct BinaryCallable
+{
+ typedef double first_argument_type;
+ typedef double second_argument_type;
+ typedef double result_type;
+
+ double operator()(double a, double b) const { return a * 2 + b * 3;}
+};
+
+BOOST_PYTHON_MODULE(ufunc_ext)
+{
+ np::initialize();
+ p::class_<UnaryCallable>("UnaryCallable")
+ .def("__call__", np::unary_ufunc<UnaryCallable>::make());
+ p::class_< BinaryCallable>("BinaryCallable")
+ .def("__call__", np::binary_ufunc<BinaryCallable>::make());
+}
diff --git a/src/boost/libs/python/test/numpy/ufunc.py b/src/boost/libs/python/test/numpy/ufunc.py
new file mode 100755
index 000000000..e820121ee
--- /dev/null
+++ b/src/boost/libs/python/test/numpy/ufunc.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+
+# Copyright Jim Bosch & Ankit Daftery 2010-2012.
+# Distributed under the 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 ufunc_ext
+import unittest
+import numpy
+from numpy.testing.utils import assert_array_almost_equal
+
+class TestUnary(unittest.TestCase):
+
+ def testScalar(self):
+ f = ufunc_ext.UnaryCallable()
+ assert_array_almost_equal(f(1.0), 2.0)
+ assert_array_almost_equal(f(3.0), 6.0)
+
+ def testArray(self):
+ f = ufunc_ext.UnaryCallable()
+ a = numpy.arange(5, dtype=float)
+ b = f(a)
+ assert_array_almost_equal(b, a*2.0)
+ c = numpy.zeros(5, dtype=float)
+ d = f(a,output=c)
+ self.assert_(c is d)
+ assert_array_almost_equal(d, a*2.0)
+
+ def testList(self):
+ f = ufunc_ext.UnaryCallable()
+ a = range(5)
+ b = f(a)
+ assert_array_almost_equal(b/2.0, a)
+
+class TestBinary(unittest.TestCase):
+
+ def testScalar(self):
+ f = ufunc_ext.BinaryCallable()
+ assert_array_almost_equal(f(1.0, 3.0), 11.0)
+ assert_array_almost_equal(f(3.0, 2.0), 12.0)
+
+ def testArray(self):
+ f = ufunc_ext.BinaryCallable()
+ a = numpy.random.randn(5)
+ b = numpy.random.randn(5)
+ assert_array_almost_equal(f(a,b), (a*2+b*3))
+ c = numpy.zeros(5, dtype=float)
+ d = f(a,b,output=c)
+ self.assert_(c is d)
+ assert_array_almost_equal(d, a*2 + b*3)
+ assert_array_almost_equal(f(a, 2.0), a*2 + 6.0)
+ assert_array_almost_equal(f(1.0, b), 2.0 + b*3)
+
+
+if __name__=="__main__":
+ unittest.main()
diff --git a/src/boost/libs/python/test/object.cpp b/src/boost/libs/python/test/object.cpp
new file mode 100644
index 000000000..b1f015187
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/object.py b/src/boost/libs/python/test/object.py
new file mode 100644
index 000000000..67a46d936
--- /dev/null
+++ b/src/boost/libs/python/test/object.py
@@ -0,0 +1,180 @@
+# 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 __future__ import print_function
+'''
+>>> 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(list(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/src/boost/libs/python/test/object_fail1.cpp b/src/boost/libs/python/test/object_fail1.cpp
new file mode 100644
index 000000000..6bb2eda5c
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/object_manager.cpp b/src/boost/libs/python/test/object_manager.cpp
new file mode 100644
index 000000000..e3608c1f1
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/opaque.cpp b/src/boost/libs/python/test/opaque.cpp
new file mode 100644
index 000000000..f15e9458f
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/opaque.py b/src/boost/libs/python/test/opaque.py
new file mode 100644
index 000000000..9f5663723
--- /dev/null
+++ b/src/boost/libs/python/test/opaque.py
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+# 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/src/boost/libs/python/test/operators.cpp b/src/boost/libs/python/test/operators.cpp
new file mode 100644
index 000000000..c58f2b005
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/operators.py b/src/boost/libs/python/test/operators.py
new file mode 100644
index 000000000..5b369803c
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/operators_wrapper.cpp b/src/boost/libs/python/test/operators_wrapper.cpp
new file mode 100644
index 000000000..12f30048d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/operators_wrapper.py b/src/boost/libs/python/test/operators_wrapper.py
new file mode 100644
index 000000000..6c889b0a3
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pickle1.cpp b/src/boost/libs/python/test/pickle1.cpp
new file mode 100644
index 000000000..cc4ad6795
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pickle1.py b/src/boost/libs/python/test/pickle1.py
new file mode 100644
index 000000000..b8f4efd9b
--- /dev/null
+++ b/src/boost/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 as 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/src/boost/libs/python/test/pickle2.cpp b/src/boost/libs/python/test/pickle2.cpp
new file mode 100644
index 000000000..c9610946e
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pickle2.py b/src/boost/libs/python/test/pickle2.py
new file mode 100644
index 000000000..f4788d3b8
--- /dev/null
+++ b/src/boost/libs/python/test/pickle2.py
@@ -0,0 +1,51 @@
+# 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 __future__ import print_function
+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 as 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/src/boost/libs/python/test/pickle3.cpp b/src/boost/libs/python/test/pickle3.cpp
new file mode 100644
index 000000000..7afe2dbfa
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pickle3.py b/src/boost/libs/python/test/pickle3.py
new file mode 100644
index 000000000..932e30f3c
--- /dev/null
+++ b/src/boost/libs/python/test/pickle3.py
@@ -0,0 +1,46 @@
+# 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 __future__ import print_function
+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/src/boost/libs/python/test/pickle4.cpp b/src/boost/libs/python/test/pickle4.cpp
new file mode 100644
index 000000000..1374cc7dc
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pickle4.py b/src/boost/libs/python/test/pickle4.py
new file mode 100644
index 000000000..be813bbb1
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pointee.cpp b/src/boost/libs/python/test/pointee.cpp
new file mode 100644
index 000000000..2aa5dc3d8
--- /dev/null
+++ b/src/boost/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/python/detail/type_traits.hpp>
+#include <memory>
+#include <boost/shared_ptr.hpp>
+#include <boost/static_assert.hpp>
+
+struct A;
+
+int main()
+{
+ BOOST_STATIC_ASSERT(
+ (boost::python::detail::is_same<
+ boost::python::pointee<std::auto_ptr<char**> >::type
+ , char**
+ >::value));
+
+ BOOST_STATIC_ASSERT(
+ (boost::python::detail::is_same<
+ boost::python::pointee<boost::shared_ptr<A> >::type
+ , A>::value));
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ BOOST_STATIC_ASSERT(
+ (boost::python::detail::is_same<
+ boost::python::pointee<char*>::type
+ , char
+ >::value));
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/python/test/pointer_type_id_test.cpp b/src/boost/libs/python/test/pointer_type_id_test.cpp
new file mode 100644
index 000000000..02e168c7e
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pointer_vector.cpp b/src/boost/libs/python/test/pointer_vector.cpp
new file mode 100644
index 000000000..08cd48619
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pointer_vector.py b/src/boost/libs/python/test/pointer_vector.py
new file mode 100644
index 000000000..234eff2c0
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/polymorphism.cpp b/src/boost/libs/python/test/polymorphism.cpp
new file mode 100644
index 000000000..02713ae26
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/polymorphism.py b/src/boost/libs/python/test/polymorphism.py
new file mode 100644
index 000000000..e3c66ea27
--- /dev/null
+++ b/src/boost/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.assertEqual ('B::f()', a.f())
+ self.assertEqual ('B::f()', call_f(a))
+ self.assertEqual ('A::f()', call_f(A()))
+
+ def test_references(self):
+ # B is not exposed to Python
+ a = getBCppObj()
+ self.assertEqual(type(a), A)
+
+ # C is exposed to Python
+ c = getCCppObj()
+ self.assertEqual(type(c), C)
+
+ def test_factory(self):
+ self.assertEqual(type(factory(0)), A)
+ self.assertEqual(type(factory(1)), A)
+ self.assertEqual(type(factory(2)), C)
+
+ def test_return_py(self):
+
+ class X(A):
+ def f(self):
+ return 'X.f'
+
+ x = X()
+
+ self.assertEqual ('X.f', x.f())
+ self.assertEqual ('X.f', call_f(x))
+
+ def test_wrapper_downcast(self):
+ a = pass_a(D())
+ self.assertEqual('D::g()', a.g())
+
+ def test_pure_virtual(self):
+ p = P()
+ self.assertRaises(RuntimeError, p.f)
+
+ q = Q()
+ self.assertEqual ('Q::f()', q.f())
+
+ class R(P):
+ def f(self):
+ return 'R.f'
+
+ r = R()
+ self.assertEqual ('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/src/boost/libs/python/test/polymorphism2.cpp b/src/boost/libs/python/test/polymorphism2.cpp
new file mode 100644
index 000000000..8aefbc3af
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/polymorphism2.py b/src/boost/libs/python/test/polymorphism2.py
new file mode 100644
index 000000000..cf7384fab
--- /dev/null
+++ b/src/boost/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.assertEqual ('B::f()', a.f())
+ self.assertEqual ('B::f()', call_f(a))
+ self.assertEqual ('A::f()', call_f(A()))
+
+ def test_references(self):
+ # B is not exposed to Python
+ a = getBCppObj()
+ self.assertEqual(type(a), A)
+
+ # C is exposed to Python
+ c = getCCppObj()
+ self.assertEqual(type(c), C)
+
+ def test_factory(self):
+ self.assertEqual(type(factory(0)), A)
+ self.assertEqual(type(factory(1)), A)
+ self.assertEqual(type(factory(2)), C)
+
+ def test_return_py(self):
+
+ class X(A):
+ def f(self):
+ return 'X.f'
+
+ x = X()
+
+ self.assertEqual ('X.f', x.f())
+ self.assertEqual ('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.assertEqual ('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.assertEqual('D::g()', a.g())
+
+ def test_pure_virtual(self):
+ p = P()
+ self.assertRaises(RuntimeError, p.f)
+
+ q = Q()
+ self.assertEqual ('Q::f()', q.f())
+
+ class R(P):
+ def f(self):
+ return 'R.f'
+
+ r = R()
+ self.assertEqual ('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/src/boost/libs/python/test/polymorphism2_auto_ptr.cpp b/src/boost/libs/python/test/polymorphism2_auto_ptr.cpp
new file mode 100644
index 000000000..8cd5ef247
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/polymorphism2_auto_ptr.py b/src/boost/libs/python/test/polymorphism2_auto_ptr.py
new file mode 100644
index 000000000..88cf664ab
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/properties.cpp b/src/boost/libs/python/test/properties.cpp
new file mode 100644
index 000000000..d338beb91
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/properties.py b/src/boost/libs/python/test/properties.py
new file mode 100644
index 000000000..1bc7a624b
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pyrun.py b/src/boost/libs/python/test/pyrun.py
new file mode 100644
index 000000000..d330773ea
--- /dev/null
+++ b/src/boost/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)
+exec(compile(open(scriptfile).read(), scriptfile, 'exec'))
diff --git a/src/boost/libs/python/test/pytype_function.cpp b/src/boost/libs/python/test/pytype_function.cpp
new file mode 100644
index 000000000..46cce19e6
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/pytype_function.py b/src/boost/libs/python/test/pytype_function.py
new file mode 100644
index 000000000..a7101fb99
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/raw_ctor.cpp b/src/boost/libs/python/test/raw_ctor.cpp
new file mode 100644
index 000000000..a825ae019
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/raw_ctor.py b/src/boost/libs/python/test/raw_ctor.py
new file mode 100644
index 000000000..1e9a9192a
--- /dev/null
+++ b/src/boost/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')
+>>> sorted(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/src/boost/libs/python/test/raw_pyobject_fail1.cpp b/src/boost/libs/python/test/raw_pyobject_fail1.cpp
new file mode 100644
index 000000000..f9dd54bc3
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/raw_pyobject_fail2.cpp b/src/boost/libs/python/test/raw_pyobject_fail2.cpp
new file mode 100644
index 000000000..62c57ae74
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/register_ptr.cpp b/src/boost/libs/python/test/register_ptr.cpp
new file mode 100644
index 000000000..6cd4d7856
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/register_ptr_test.py b/src/boost/libs/python/test/register_ptr_test.py
new file mode 100644
index 000000000..674e5572f
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/result.cpp b/src/boost/libs/python/test/result.cpp
new file mode 100644
index 000000000..d5f43cc3d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/return_arg.cpp b/src/boost/libs/python/test/return_arg.cpp
new file mode 100644
index 000000000..d8d3c1ddb
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/return_arg.py b/src/boost/libs/python/test/return_arg.py
new file mode 100644
index 000000000..e66a0b8d9
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/select_arg_to_python_test.cpp b/src/boost/libs/python/test/select_arg_to_python_test.cpp
new file mode 100644
index 000000000..c5faace36
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/select_from_python_test.cpp b/src/boost/libs/python/test/select_from_python_test.cpp
new file mode 100644
index 000000000..bb60962a3
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/select_holder.cpp b/src/boost/libs/python/test/select_holder.cpp
new file mode 100644
index 000000000..8650bd06a
--- /dev/null
+++ b/src/boost/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/python/detail/type_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::python::detail::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/src/boost/libs/python/test/shared_ptr.cpp b/src/boost/libs/python/test/shared_ptr.cpp
new file mode 100644
index 000000000..f72e6f029
--- /dev/null
+++ b/src/boost/libs/python/test/shared_ptr.cpp
@@ -0,0 +1,19 @@
+// Copyright David Abrahams 2002.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 <memory>
+
+using std::shared_ptr;
+#define MODULE shared_ptr_ext
+
+#include "shared_ptr.hpp"
+#include "module_tail.cpp"
+
diff --git a/src/boost/libs/python/test/shared_ptr.hpp b/src/boost/libs/python/test/shared_ptr.hpp
new file mode 100644
index 000000000..9f9a4b69e
--- /dev/null
+++ b/src/boost/libs/python/test/shared_ptr.hpp
@@ -0,0 +1,206 @@
+// Copyright David Abrahams 2002.
+// Copyright Stefan Seefeld 2016.
+// Distributed under the 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 "test_class.hpp"
+
+using namespace boost::python;
+
+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; }
+ };
+
+ shared_ptr<A> New(bool make)
+ {
+ return 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 {
+ shared_ptr<X> x;
+};
+// ------
+
+
+BOOST_PYTHON_MODULE(MODULE)
+{
+ class_<A, 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, 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")
+ ;
+// ------
+}
diff --git a/src/boost/libs/python/test/shared_ptr.py b/src/boost/libs/python/test/shared_ptr.py
new file mode 100644
index 000000000..d250ae7ec
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/simple_type.hpp b/src/boost/libs/python/test/simple_type.hpp
new file mode 100644
index 000000000..d1314ff97
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/slice.cpp b/src/boost/libs/python/test/slice.cpp
new file mode 100644
index 000000000..b1b965fa1
--- /dev/null
+++ b/src/boost/libs/python/test/slice.cpp
@@ -0,0 +1,98 @@
+#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
+
+// 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_string_rich_slice", check_string_rich_slice);
+ def( "check_slice_get_indices", check_slice_get_indices);
+}
diff --git a/src/boost/libs/python/test/slice.py b/src/boost/libs/python/test/slice.py
new file mode 100644
index 000000000..c58bbc029
--- /dev/null
+++ b/src/boost/libs/python/test/slice.py
@@ -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)
+"""
+>>> 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
+>>> 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 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/src/boost/libs/python/test/staticmethod.cpp b/src/boost/libs/python/test/staticmethod.cpp
new file mode 100644
index 000000000..dcd75ca82
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/staticmethod.py b/src/boost/libs/python/test/staticmethod.py
new file mode 100644
index 000000000..3dd355b13
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/stl_iterator.cpp b/src/boost/libs/python/test/stl_iterator.cpp
new file mode 100644
index 000000000..409e0da84
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/stl_iterator.py b/src/boost/libs/python/test/stl_iterator.py
new file mode 100644
index 000000000..4743ed632
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/str.cpp b/src/boost/libs/python/test/str.cpp
new file mode 100644
index 000000000..0505b250a
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/str.py b/src/boost/libs/python/test/str.py
new file mode 100644
index 000000000..4eba0e876
--- /dev/null
+++ b/src/boost/libs/python/test/str.py
@@ -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)
+from __future__ import print_function
+"""
+>>> from str_ext import *
+>>> def printer(*args):
+... for x in args: print(x, end='')
+... 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/src/boost/libs/python/test/string_literal.cpp b/src/boost/libs/python/test/string_literal.cpp
new file mode 100644
index 000000000..7a349d6c2
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/test_builtin_converters.py b/src/boost/libs/python/test/test_builtin_converters.py
new file mode 100644
index 000000000..e612ed23d
--- /dev/null
+++ b/src/boost/libs/python/test/test_builtin_converters.py
@@ -0,0 +1,312 @@
+# 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 sys
+if (sys.version_info.major >= 3):
+ long = int
+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], [long(-1), -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(long(0x80000001))).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?
+
+>>> print(rewrap_value_wstring(u'\U0001f4a9'))
+\U0001f4a9
+
+ 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(long(42))
+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
+"""
+
+import sys
+if (sys.version_info.major >= 3):
+ long = int
+
+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/src/boost/libs/python/test/test_class.hpp b/src/boost/libs/python/test/test_class.hpp
new file mode 100644
index 000000000..5404fdba2
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/test_cltree.py b/src/boost/libs/python/test/test_cltree.py
new file mode 100644
index 000000000..2127b7cdb
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/test_enum.py b/src/boost/libs/python/test/test_enum.py
new file mode 100644
index 000000000..e4ad70bd5
--- /dev/null
+++ b/src/boost/libs/python/test/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/src/boost/libs/python/test/test_overload_resolution.cpp b/src/boost/libs/python/test/test_overload_resolution.cpp
new file mode 100644
index 000000000..e15bcc6a7
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/test_pointer_adoption.cpp b/src/boost/libs/python/test/test_pointer_adoption.cpp
new file mode 100644
index 000000000..a4e14af5d
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/test_pointer_adoption.py b/src/boost/libs/python/test/test_pointer_adoption.py
new file mode 100644
index 000000000..0fdf3b98e
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/tuple.cpp b/src/boost/libs/python/test/tuple.cpp
new file mode 100644
index 000000000..d48e91d88
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/tuple.py b/src/boost/libs/python/test/tuple.py
new file mode 100644
index 000000000..1aec5fded
--- /dev/null
+++ b/src/boost/libs/python/test/tuple.py
@@ -0,0 +1,38 @@
+# 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 __future__ import print_function
+"""
+>>> 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/src/boost/libs/python/test/upcast.cpp b/src/boost/libs/python/test/upcast.cpp
new file mode 100644
index 000000000..255429f16
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/vector_indexing_suite.cpp b/src/boost/libs/python/test/vector_indexing_suite.cpp
new file mode 100644
index 000000000..0f9cd74ca
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/vector_indexing_suite.py b/src/boost/libs/python/test/vector_indexing_suite.py
new file mode 100644
index 000000000..478cd0151
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/virtual_functions.cpp b/src/boost/libs/python/test/virtual_functions.cpp
new file mode 100644
index 000000000..774b11b12
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/virtual_functions.py b/src/boost/libs/python/test/virtual_functions.py
new file mode 100644
index 000000000..cba21edd6
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/voidptr.cpp b/src/boost/libs/python/test/voidptr.cpp
new file mode 100644
index 000000000..82e412bea
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/voidptr.py b/src/boost/libs/python/test/voidptr.py
new file mode 100644
index 000000000..0e189c965
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/wrapper_held_type.cpp b/src/boost/libs/python/test/wrapper_held_type.cpp
new file mode 100644
index 000000000..e99422796
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/test/wrapper_held_type.py b/src/boost/libs/python/test/wrapper_held_type.py
new file mode 100644
index 000000000..ff1bd1d24
--- /dev/null
+++ b/src/boost/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/src/boost/libs/python/todo.txt b/src/boost/libs/python/todo.txt
new file mode 100644
index 000000000..fb4f1c3c3
--- /dev/null
+++ b/src/boost/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
+