2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 04:42:28 +00:00

Compare commits

...

121 Commits

Author SHA1 Message Date
nobody
b2e04cd704 This commit was manufactured by cvs2svn to create tag 'minmax'.
[SVN r22393]
2004-02-26 10:35:28 +00:00
Daniel Wallin
a9c2a95366 boost logo css class
[SVN r22352]
2004-02-21 18:42:52 +00:00
Bruno da Silva de Oliveira
29f3891a68 - Generates the unique number for UniqueInt using the hash of the filename
[SVN r22329]
2004-02-19 22:26:54 +00:00
Bruno da Silva de Oliveira
7b602ef607 - now warns that AllFromHeader is not working in all cases
[SVN r22316]
2004-02-18 22:32:58 +00:00
Bruno da Silva de Oliveira
15e555c7f1 - Fixed UniqueInt bug across different compilation units.
[SVN r22315]
2004-02-18 22:28:28 +00:00
Bruno da Silva de Oliveira
f4fb49d32f - reverted previous commit
[SVN r22313]
2004-02-18 15:33:34 +00:00
Bruno da Silva de Oliveira
89be2fb736 - no_init is now generated for abstract classes
[SVN r22312]
2004-02-18 15:27:59 +00:00
Ralf W. Grosse-Kunstleve
62f0885852 Requires: n/a removed
[SVN r22257]
2004-02-13 18:20:43 +00:00
Ralf W. Grosse-Kunstleve
355e155e69 gcc 3.4 from gcc.gnu.org still suffers from the old static initialization bug under Mac OS 10: workaround adjusted accordingly
[SVN r22255]
2004-02-13 07:10:59 +00:00
Ralf W. Grosse-Kunstleve
ae1584ff3c class_::enable_pickling() in publicized interface; tested with everything incl. VC6 and 7.0
[SVN r22254]
2004-02-13 05:32:38 +00:00
Jonathan Brandmeyer
4a7686cd33 Check rich slicing of Numeric arrays only if Numeric or numarray is
installed.


[SVN r22252]
2004-02-13 02:07:21 +00:00
Jonathan Brandmeyer
799eeb0cb8 Fix a build error on Tru64. Thanks to Ralf W. Grosse-Kunstleve for this
fix.


[SVN r22250]
2004-02-12 23:09:10 +00:00
Jonathan Brandmeyer
8452e275d0 New implementation, tests, and documentation for a PySliceObject
objectmanager.


[SVN r22192]
2004-02-07 21:38:24 +00:00
Joel de Guzman
53268000e7 small typo
[SVN r22067]
2004-01-30 06:15:32 +00:00
Dave Abrahams
52febfe3fc Improved and alphabetized news format, added Python news, updated
iterator news.

Corrections in the Python documentation


[SVN r22039]
2004-01-29 03:34:23 +00:00
Dave Abrahams
8fcfed495a Fixes for intel-linux
added <default> feature handling for specifying build defaults in requirement sets.


[SVN r22027]
2004-01-28 22:50:18 +00:00
Joel de Guzman
2dfe76b082 small typo
[SVN r22026]
2004-01-28 22:45:35 +00:00
Ralf W. Grosse-Kunstleve
11d8751d29 workaround for gcc 3.4 bug when using precompiled header support
[SVN r21715]
2004-01-14 01:37:54 +00:00
Ralf W. Grosse-Kunstleve
b03c3a29e0 previous revision (1.10) of this file restored because http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13530 is fixed
[SVN r21633]
2004-01-12 18:02:28 +00:00
Joel de Guzman
53e8982e05 fix typo
[SVN r21571]
2004-01-10 02:53:06 +00:00
Ralf W. Grosse-Kunstleve
4a30841ad8 fix for Tru64 cxx problems incl. workaround for gcc 2.96 problems; patch by David Abrahams; thanks Dave!
[SVN r21558]
2004-01-09 07:25:17 +00:00
Dave Abrahams
234ebadb8d pro9 workarounds; some ADL protection for is_xxx
[SVN r21529]
2004-01-07 14:07:21 +00:00
Dave Abrahams
11ee20fa36 Test full slicing.
[SVN r21497]
2004-01-05 12:34:25 +00:00
Dave Abrahams
440599545f Workaround for gcc-3.4 quirks
[SVN r21493]
2004-01-05 11:46:30 +00:00
Dave Abrahams
44ba088cb4 Fix problem with [:] slices on python::objects
[SVN r21472]
2004-01-04 13:41:00 +00:00
Dave Abrahams
08d3798722 .
[SVN r21449]
2004-01-02 18:34:17 +00:00
Ralf W. Grosse-Kunstleve
56ff8e438e fix use of incomplete type (Tru64 cxx diagnostic)
[SVN r21444]
2004-01-02 08:31:21 +00:00
Dave Abrahams
3590a3589d Fix 2-phase lookup bug
[SVN r21442]
2004-01-01 12:46:04 +00:00
Dave Abrahams
7674c82e1f Fix bug with (arg("x"), "y") construct.
[SVN r21437]
2003-12-31 19:20:31 +00:00
Ralf W. Grosse-Kunstleve
b93b21a7f2 work around Visual C++ 6 internal compiler errors
[SVN r21435]
2003-12-31 17:18:03 +00:00
Ralf W. Grosse-Kunstleve
f53925848c work around g++ (GCC) 3.4.0 20031230 (experimental) internal compiler error
[SVN r21432]
2003-12-31 09:37:31 +00:00
Dave Abrahams
eedc88b56a Bug fixes in property handling
[SVN r21429]
2003-12-31 00:23:52 +00:00
Ralf W. Grosse-Kunstleve
1102fec2a0 links to pickle and indexing suites
[SVN r21423]
2003-12-30 03:54:21 +00:00
Ralf W. Grosse-Kunstleve
589fefe4b9 tabs -> spaces
[SVN r21405]
2003-12-27 06:22:29 +00:00
Rene Rivera
cfc867bd18 Fix broken links.
[SVN r21404]
2003-12-27 02:37:02 +00:00
Rene Rivera
5bc28e3016 Fix broken links.
[SVN r21403]
2003-12-27 01:46:04 +00:00
Rene Rivera
23b7ccca7f Fix broken links. And some minor consistency changes.
[SVN r21402]
2003-12-27 01:31:00 +00:00
Dave Abrahams
e9d6286a1d Fix Dereferenceable concept to require pointee, and
register_ptr_to_python to require Dereferenceable.


[SVN r21327]
2003-12-18 19:25:14 +00:00
Dave Abrahams
48321857e4 consistent use of get_pointer
[SVN r21326]
2003-12-18 19:23:38 +00:00
Ralf W. Grosse-Kunstleve
156da15715 unused member function removed (to avoid Linux Intel C++ 8.0 warning)
[SVN r21278]
2003-12-16 04:14:28 +00:00
Ralf W. Grosse-Kunstleve
4a0d7965cb consolidation of workarounds for missing "not" keyword
[SVN r21276]
2003-12-15 17:55:38 +00:00
Dave Abrahams
1f522823ff gcc2 workaround
[SVN r21274]
2003-12-15 14:45:07 +00:00
Beman Dawes
6795a280fd tabs to spaces
[SVN r21080]
2003-12-02 13:32:47 +00:00
Dave Abrahams
f369e22638 Cleaner code using object instead of handle
[SVN r21018]
2003-11-30 21:12:30 +00:00
Dave Abrahams
a278da2eba correct get_pointer usage
[SVN r21017]
2003-11-30 21:10:15 +00:00
Dave Abrahams
37b2bdba79 Workaround gcc-2.x ICE
[SVN r21016]
2003-11-30 21:08:19 +00:00
Dave Abrahams
e9519db974 Make Dereferenceable use get_pointer
Re-enable map_indexing_suite iteration for vc6.


[SVN r21008]
2003-11-29 22:12:18 +00:00
Ralf W. Grosse-Kunstleve
dd7a24ebce links to newly generated tutorial sections
[SVN r20934]
2003-11-24 05:53:13 +00:00
Bruno da Silva de Oliveira
bc92a7d155 - added new "General Techniques" section
[SVN r20927]
2003-11-23 21:24:54 +00:00
Dave Abrahams
a68db84df6 * Fixed Boost.Thread jamfile to add the missing #include paths
* Modified Python testing code to use the facilities of testing.jam,
  so that it can be processed with process_jam_log

* Updated Python library tests to use a test suite

* Added Python test suite to status/Jamfile

* Added --run-all-tests option to force tests to run even when up-to-date.


Also,
boost-base.jam:

    Added some missing rule signatures

    RUN_LD_LIBRARY_PATH became LINK_LIBPATH because it was only really
    used during linking.

    Reformed the movement of path variables up the dependency graph

    Removed the defunct Run rule

    Set up generalized constants for path manipulation

darwin-tools.jam, gcc-tools.jam:

   use LINK_LIBPATH

python.jam:

   Reformed the choice of Python executable

testing.jam:

   Refactored testing code so it could be used for Python

   Now building all environment variable setup code ahead of time

   RUN_TEST became TEST_EXE


[SVN r20815]
2003-11-15 15:41:41 +00:00
Dave Abrahams
7b9bba3190 vc6 workaround
[SVN r20814]
2003-11-15 15:16:27 +00:00
Ralf W. Grosse-Kunstleve
bcec0af232 minor fix for otherwise confusing debug output
[SVN r20796]
2003-11-12 19:55:22 +00:00
Ralf W. Grosse-Kunstleve
0d437c4102 MIPSpro 7.41 workaround
[SVN r20795]
2003-11-12 19:49:18 +00:00
Raoul Gough
feff7bccd3 Fix MSVC6 duplicate comdat (LNK1179) with multiple python::range instances
[SVN r20794]
2003-11-12 16:50:17 +00:00
Ralf W. Grosse-Kunstleve
b12de3f01b additions by Niall Douglas with heavy edits by Ralf
[SVN r20780]
2003-11-10 20:39:13 +00:00
Dave Abrahams
0d108f12e4 Better error reporting for overload resolution failures, ideas thanks
to Nikolay Mladenov.


[SVN r20770]
2003-11-10 01:02:45 +00:00
Dave Abrahams
4aca2ca33b change to binary
[SVN r20689]
2003-11-06 01:14:50 +00:00
Dave Abrahams
9a967ae514 change to binary
[SVN r20688]
2003-11-06 01:13:26 +00:00
Ralf W. Grosse-Kunstleve
9481c39874 explain workaround for a bug in Apple's compiler
[SVN r20684]
2003-11-05 19:19:50 +00:00
Dave Abrahams
1e02065982 Fix Mike Rovner's warning suppression.
[SVN r20673]
2003-11-05 00:43:13 +00:00
Ralf W. Grosse-Kunstleve
1fee0da689 patch by Mike Rovner: work around gcc 3.3.1 bug (http://gcc.gnu.org/PR12163)
[SVN r20672]
2003-11-05 00:30:46 +00:00
Ralf W. Grosse-Kunstleve
c760cf8418 workaround for MIPSpro 7.3.1; old workaround for VC7.1 visible only to that particular compiler
[SVN r20668]
2003-11-04 20:20:07 +00:00
Ralf W. Grosse-Kunstleve
cdee5997af obsolete MIPSpro workaround removed
[SVN r20667]
2003-11-04 20:17:48 +00:00
Ralf W. Grosse-Kunstleve
4289280cdc Mac OS 10 answer updated
[SVN r20666]
2003-11-04 20:05:09 +00:00
Rene Rivera
962dfa17c5 Add -bind_at_load option for MacOSX Darwin build, this prevents semaphore_wait_trap erros when loaded by extensions.
[SVN r20665]
2003-11-04 18:30:37 +00:00
Ralf W. Grosse-Kunstleve
0a21aef601 fix expected output; tested with Python 2.2.1 (Redhat8) and Python 2.3 (Mac OS 10.2.8)
[SVN r20658]
2003-11-04 17:38:13 +00:00
Rene Rivera
8cbbd504cf Point to the new location for Boost.Build v1; tools/build/v1.
[SVN r20654]
2003-11-04 17:07:15 +00:00
Dave Abrahams
91b23c8367 Warning suppression thanks to Mike Rovner <mike-at-bindkey.com>
[SVN r20617]
2003-11-03 20:45:21 +00:00
Dave Abrahams
3729be263f Bug fix
[SVN r20566]
2003-10-30 18:40:37 +00:00
Dave Abrahams
ea91f4217a suppress a warning
[SVN r20555]
2003-10-29 23:16:36 +00:00
Raoul Gough
7fab3ce0b1 Add info on using gdb under Windows
[SVN r20554]
2003-10-29 21:38:06 +00:00
Dave Abrahams
ef7d675d67 bug fix for a single use of arg with no comma operator
[SVN r20533]
2003-10-29 00:46:08 +00:00
Rene Rivera
2b9d29a0fc Improve unused variable warning supperssion with multi-compiler friendly code.
[SVN r20466]
2003-10-24 01:19:16 +00:00
Bruno da Silva de Oliveira
95b95d012c - Fixed bug where a class would appear more than one in the generated code.
[SVN r20464]
2003-10-23 22:56:33 +00:00
Rene Rivera
4af7d5bca7 Remove unused var warning on non-debug compilation.
[SVN r20463]
2003-10-23 20:15:50 +00:00
Rene Rivera
d879eb235f Add install definitions for new common install configuration.
[SVN r20409]
2003-10-19 19:52:56 +00:00
Dave Abrahams
4f129d035b Bug fix, thanks to Nicolas LELONG, nlelong-at-mgdesign.org for the report.
[SVN r20401]
2003-10-17 14:13:48 +00:00
Dave Abrahams
7a354c4ff4 Warning suppression for GCC.
[SVN r20396]
2003-10-15 23:19:48 +00:00
Dave Abrahams
364826b3b3 Include @group directives for Synopsis
[SVN r20364]
2003-10-13 21:04:11 +00:00
Raoul Gough
e9b308da46 Use msvc_typeid only if _MSV_VER is set, to avoid problems with Intel compiler on Linux
[SVN r20340]
2003-10-10 14:55:13 +00:00
Dave Abrahams
94cfa2602f Fix typo
[SVN r20324]
2003-10-09 14:15:20 +00:00
Bruno da Silva de Oliveira
3533bd0504 no message
[SVN r20266]
2003-10-06 19:10:50 +00:00
Bruno da Silva de Oliveira
1a51a7df9e - added missing <boost/python/return_arg.hpp>
[SVN r20257]
2003-10-04 21:44:24 +00:00
Dave Abrahams
615be89951 Support for logical negation operator via __nonzero__
[SVN r20256]
2003-10-04 15:40:09 +00:00
Dave Abrahams
912ca36a1f fixed broken link
[SVN r20255]
2003-10-04 12:06:19 +00:00
Dave Abrahams
fba93805dc Work with gcc2
[SVN r20168]
2003-09-23 23:57:23 +00:00
Dave Abrahams
96d66f4624 Correct integral constant overflow
[SVN r20136]
2003-09-21 18:49:04 +00:00
Dave Abrahams
c3bae63e41 Fix const-correctness problem
[SVN r20135]
2003-09-21 17:24:37 +00:00
Bruno da Silva de Oliveira
6c22aceabc - added return_by_value
[SVN r20127]
2003-09-21 02:07:07 +00:00
Dave Abrahams
92a77dfe7f Implemented injected constructors.
Eliminated _DEBUG redefinition warning for CWPro8.


[SVN r20126]
2003-09-21 01:35:19 +00:00
Bruno da Silva de Oliveira
4f2dbeda28 bugs in Enum and export_values option
[SVN r20121]
2003-09-19 23:07:14 +00:00
Dave Abrahams
bec2de08fe Use make_function uniformly to build callable objects.
Fix wstring support so it doesn't break gcc2.95.x, which has no wstring.

Modify CallPolicies protocol so it can safely adjust the argument tuple.


[SVN r20090]
2003-09-17 21:36:53 +00:00
Raoul Gough
db192e1e01 Remove incref of Py_None in make_nurse_and_patient - inc already done in detail::none()
[SVN r20079]
2003-09-16 17:31:06 +00:00
Dave Abrahams
454654a9cc Try to ward off personal emails
[SVN r20041]
2003-09-12 20:08:05 +00:00
Dave Abrahams
1018bc56eb put newlines in the list of links
[SVN r20037]
2003-09-12 14:54:34 +00:00
Dave Abrahams
f920dc87d0 Added std::wstring conversion support
Added std::out_of_range => Python IndexError exception conversion,
thanks to Raoul Gough


[SVN r20027]
2003-09-11 19:19:55 +00:00
Dave Abrahams
8b97caae46 Warn about duplicate to-python converters and show the name of the
offending type.


[SVN r20023]
2003-09-11 15:09:11 +00:00
Dave Abrahams
3b74aab818 add pyfinalize safety
[SVN r20022]
2003-09-11 11:07:05 +00:00
Dave Abrahams
e78b4939b3 Added new str constructors which take a range of characters, allowing
strings containing nul ('\0') characters.


[SVN r20006]
2003-09-11 02:57:24 +00:00
Bruno da Silva de Oliveira
621b5fc2db - added INTERFACE_FILE
[SVN r20005]
2003-09-10 21:55:50 +00:00
Dave Abrahams
6ada069d5a Update for cross-project capability
[SVN r20002]
2003-09-10 16:08:41 +00:00
Joel de Guzman
50db384be1 Used BOOST_WORKAROUND
[SVN r19980]
2003-09-09 13:13:44 +00:00
Dave Abrahams
ae7225ae83 Updates for cross-project dependencies
[SVN r19977]
2003-09-09 03:14:01 +00:00
Dave Abrahams
911ba333a2 restored python test drivers
[SVN r19976]
2003-09-09 02:55:39 +00:00
Dave Abrahams
5cd8cce531 Set up BOOST_ROOT before import python has a chance to use it.
[SVN r19974]
2003-09-09 02:42:17 +00:00
Dave Abrahams
6a2a76cea9 Use new cross-project feature
[SVN r19969]
2003-09-08 19:36:06 +00:00
Dave Abrahams
7a9a3d30c9 Use the import rule
[SVN r19968]
2003-09-08 17:38:49 +00:00
Joel de Guzman
034ca4d5eb mscv workaround
[SVN r19962]
2003-09-08 12:56:33 +00:00
Dave Abrahams
00e3fa32fb Fix typo
[SVN r19949]
2003-09-07 19:45:21 +00:00
Dave Abrahams
0133bdfbe3 Removed unused ConverterGenerators arguments.
Updated arg_from_python<T> so that its operator() is nullary -- it
already gets everything it needs in its constructor.


[SVN r19948]
2003-09-07 19:44:44 +00:00
Dave Abrahams
e563def5ba Update documentation for the use of function objects.
[SVN r19947]
2003-09-07 18:03:20 +00:00
Dave Abrahams
b3910f4e4d Support for wrapping function objects and classes which use virtual
inheritance.  Completely killed off member_function_cast!


[SVN r19945]
2003-09-07 16:56:05 +00:00
Bruno da Silva de Oliveira
4a7b8fe839 - Wrapper for protected and private pure virtual functions are now generated
[SVN r19922]
2003-09-04 22:47:04 +00:00
Joel de Guzman
fc56544da4 added note to use bjam as the preferred build tool
[SVN r19889]
2003-09-01 03:12:34 +00:00
Dave Abrahams
c839d25722 Add module_tail for JIT debugging
[SVN r19863]
2003-08-29 19:42:39 +00:00
Dave Abrahams
c6b5ecbbdb Update for select_holder changes
[SVN r19862]
2003-08-29 19:03:14 +00:00
Joel de Guzman
d3473afa23 Take 2
[SVN r19805]
2003-08-27 12:10:49 +00:00
Joel de Guzman
379b28eb85 Some more tweaks
[SVN r19803]
2003-08-27 10:18:37 +00:00
Joel de Guzman
7f5bd33ead Tweaks
[SVN r19802]
2003-08-27 10:14:14 +00:00
Joel de Guzman
eef6fb9891 def_visitor linked in the reference
[SVN r19801]
2003-08-27 10:09:08 +00:00
Joel de Guzman
4a7f52ab2c Initial commit of def_visitor doc
[SVN r19800]
2003-08-27 10:00:23 +00:00
186 changed files with 5365 additions and 2214 deletions

View File

@@ -10,8 +10,7 @@
subproject libs/python/build ;
# bring in the rules for python
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
import python ;
if [ check-python-config ]
{
@@ -35,6 +34,7 @@ if [ check-python-config ]
dict.cpp
tuple.cpp
str.cpp
slice.cpp
aix_init_module.cpp
converter/from_python.cpp
@@ -61,8 +61,14 @@ if [ check-python-config ]
<define>BOOST_PYTHON_SOURCE
$(bpl-linkflags)
<msvc-stlport><release>$(msvc-stlport-workarounds)
<darwin><*><linkflags>-bind_at_load
;
template extension
: <dll>boost_python
: <sysinclude>../../..
;
lib boost_python
: # sources
../src/$(sources)
@@ -81,4 +87,8 @@ if [ check-python-config ]
:
debug release
;
}
install python lib
: <dll>boost_python <lib>boost_python
;
}

View File

@@ -1,8 +1,11 @@
import os ;
import modules ;
# Use a very crude way to sense there python is locatted
local PYTHON_PATH ;
local PYTHON_PATH = [ modules.peek : PYTHON_PATH ] ;
ECHO "XXX" $(PYTHON_PATH) ;
if [ GLOB /usr/local/include/python2.2 : * ]
{
@@ -19,7 +22,7 @@ if [ os.name ] in CYGWIN NT
defines = USE_DL_IMPORT ;
# Declare a target for the python interpreter library
lib python : : <name>python2.2.dll ;
lib python : : <name>python22 <search>$(PYTHON_PATH)/libs ;
PYTHON_LIB = python ;
}
else
@@ -35,12 +38,12 @@ if $(PYTHON_PATH) {
project boost/python
: source-location ../src
: requirements <include>$(PYTHON_PATH)/include/python2.2
$(lib_condition)<library-path>$(PYTHON_PATH)/lib/python2.2/config
: requirements <include>$(PYTHON_PATH)/include
$(lib_condition)<library-path>$(PYTHON_PATH)/libs
<link>shared:<library>$(PYTHON_LIB)
<define>$(defines)
: usage-requirements # requirement that will be propageted to *users* of this library
<include>$(PYTHON_PATH)/include/python2.2
<include>$(PYTHON_PATH)/include
# We have a bug which causes us to conclude that conditionalized
# properties in this section are not free.

Binary file not shown.

View File

@@ -55,15 +55,6 @@
<dt><a href="#building_ext">Building your Extension Module</a></dt>
<dd>
<dl>
<dt><a href="#easy">The Easy Way</a></dt>
<dt><a href="#outside">Building your module outside the Boost
project tree</a></dt>
</dl>
</dd>
<dt><a href="#variants">Build Variants</a></dt>
<dt><a href="#VisualStudio">Building Using the Microsoft Visual Studio
@@ -83,10 +74,10 @@
<p>Normally, Boost.Python extension modules must be linked with the
<code>boost_python</code> shared library. In special circumstances you
may want to link to a static version of the <code>boost_python</code>
library, but if multiple Boost.Pythone extension modules are used
library, but if multiple Boost.Python extension modules are used
together, it will prevent sharing of types across extension modules, and
consume extra code space. To build <code>boost_python</code>, use <a
href="../../../tools/build/index.html">Boost.Build</a> in the usual way
href="../../../tools/build/v1/build_system.htm">Boost.Build</a> in the usual way
from the <code>libs/python/build</code> subdirectory of your boost
installation (if you have already built boost from the top level this may
have no effect, since the work is already done).</p>
@@ -258,7 +249,7 @@
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> test
"../../../more/getting_started.html#Tools">toolset</a></i> test
</pre>
</blockquote>
This will update all of the Boost.Python v1 test and example targets. The
@@ -268,58 +259,62 @@ bjam -sTOOLS=<i><a href=
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
"../../../more/getting_started.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
</pre>
</blockquote>
which will print each test's Python code with the expected output as it
passes.
<h2><a name="building_ext">Building your Extension Module</a></h2>
Though there are other approaches, the best way to build an extension
module using Boost.Python is with Boost.Build. If you have to use another
build system, you should use Boost.Build at least once with the
Though there are other approaches, the smoothest and most reliable
way to build an extension module using Boost.Python is with
Boost.Build. If you have to use another build system, you should
use Boost.Build at least once with the
"<code><b>-n</b></code>" option so you can see the command-lines it uses,
and replicate them. You are likely to run into compilation or linking
problems otherwise.
<h3><a name="easy">The Easy Way</a></h3>
Until Boost.Build v2 is released, cross-project build dependencies are
not supported, so it works most smoothly if you add a new subproject to
your boost installation. The <code>libs/python/example</code>
subdirectory of your boost installation contains a minimal example (along
with many extra sources). To copy the example subproject:
The <code><a href="../example">libs/python/example</a></code>
subdirectory of your boost installation contains a small example
which builds and tests two extensions. To build your own
extensions copy the example subproject and make the following two edits:
<ol>
<li>Create a new subdirectory in, <code>libs/python</code>, say
<code>libs/python/my_project</code>.</li>
<ol>
<li><code><a
href="../example/boost-build.jam"><b>boost-build.jam</b></a></code> -
edit the line which reads
<li>Copy <code><a href=
"../example/Jamfile">libs/python/example/Jamfile</a></code> to your new
directory.</li>
<blockquote>
<pre>
boost-build ../../../tools/build/v1 ;
</pre>
</blockquote>
<li>Edit the Jamfile as appropriate for your project. You'll want to
change the "<code>subproject</code>" rule invocation at the top, and
the names of some of the source files and/or targets.</li>
</ol>
so that the path refers to the <code>tools/build/v1</code> subdirectory
of your Boost installation.
<li><code><a href="../example/Jamrules"><b>Jamrules</b></a></code> -
edit the line which reads
<blockquote>
<pre>
path-global BOOST_ROOT : ../../.. ;
</pre>
</blockquote>
so that the path refers to the root directory of your Boost installation.
</ol>
<p>
The instructions <a href="#testing">above</a> for testing Boost.Python
apply equally to your new extension modules in this subproject.
<h3><a name="outside">Building your module outside the Boost project
tree</a></h3>
If you can't (or don't wish to) modify your boost installation, the
alternative is to create your own Boost.Build project. A similar example
you can use as a starting point is available in <code><a href=
"../example/project.zip">this archive</a></code>. You'll need to edit the
Jamfile and Jamrules files, depending on the relative location of your
Boost installation and the new project. Note that automatic testing of
extension modules is not available in this configuration.
<h2><a name="variants">Build Variants</a></h2>
Three <a href=
"../../../tools/build/build_system.htm#variants">variant</a>
"../../../tools/build/v1/build_system.htm#variants">variant</a>
configurations of all python-related targets are supported, and can be
selected by setting the <code><a href=
"../../../tools/build/build_system.htm#user_globals">BUILD</a></code>
"../../../tools/build/v1/build_system.htm#user_globals">BUILD</a></code>
variable:
<ul>

View File

@@ -73,6 +73,14 @@
<dt><a href="v2/reference.html">Reference Manual</a></dt>
<dt>Suites:</dt>
<dd>
<ul>
<li><a href="v2/pickle.html">Pickle</a></li>
<li><a href="v2/indexing.html">Indexing</a></li>
</ul>
</dd>
<dt><a href="v2/configuration.html">Configuration Information</a></dt>
<dt><a href="v2/platforms.html">Known Working Platforms and
@@ -114,7 +122,7 @@
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../people/dave_abrahams.htm">Dave
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -4,21 +4,21 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
<title>Boost Python Internals</title>
<meta name="copyright" content="Copyright Brett Calcott and David Abrahams 2003. All rights reserved." />
<title>Boost.Python Internals Boost</title>
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="boost-python-internals">
<h1 class="title">Boost Python Internals</h1>
<h2 class="subtitle" id="a-conversation-between-brett-calcott-and-david-abrahams">A conversation between Brett Calcott and David Abrahams</h2>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<div class="document" id="boost-python-internals-logo">
<h1 class="title"><a class="reference" href="index.html">Boost.Python</a> Internals <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../c++boost.gif" /></a></h1>
<div class="section" id="a-conversation-between-brett-calcott-and-david-abrahams">
<h1><a name="a-conversation-between-brett-calcott-and-david-abrahams">A conversation between Brett Calcott and David Abrahams</a></h1>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright Brett Calcott and David Abrahams 2003. All
rights reserved.</td></tr>
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams and Brett Calcott 2003. See
accompanying <a class="reference" href="../../../LICENSE_1_0.txt">license</a> for terms of use.</td>
</tr>
</tbody>
</table>
<p>In both of these cases, I'm quite capable of reading code - but the
@@ -118,10 +118,11 @@ way from c++ to python and back again.</p>
info in the LLNL progress reports and the messages they link to.
Also,</p>
<blockquote>
<a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a>
<a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-December/003115.html">http://mail.python.org/pipermail/c++-sig/2002-December/003115.html</a>
<a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1280898">http://aspn.activestate.com/ASPN/Mail/Message/1280898</a>
<a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-July/001755.html">http://mail.python.org/pipermail/c++-sig/2002-July/001755.html</a></blockquote>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a></p>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-December/003115.html">http://mail.python.org/pipermail/c++-sig/2002-December/003115.html</a></p>
<p><a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1280898">http://aspn.activestate.com/ASPN/Mail/Message/1280898</a></p>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-July/001755.html">http://mail.python.org/pipermail/c++-sig/2002-July/001755.html</a></p>
</blockquote>
<p>from c++ to python:</p>
<blockquote>
<p>It depends on the type and the call policies in use or, for
@@ -174,10 +175,11 @@ possible, then construct the converted object as a second step.</p>
</blockquote>
</blockquote>
</div>
</div>
<hr class="footer"/>
<div class="footer">
<a class="reference" href="internals.rst">View document source</a>.
Generated on: 2003-07-31 17:58 UTC.
Generated on: 2003-09-12 14:51 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>

View File

@@ -1,13 +1,24 @@
========================
Boost Python Internals
========================
===================================
Boost.Python_ Internals |(logo)|__
===================================
.. |(logo)| image:: ../../../c++boost.gif
:alt: Boost
:class: boost-logo
__ ../../../index.htm
.. _`Boost.Python`: index.html
.. _license: ../../../LICENSE_1_0.txt
-------------------------------------------------------
A conversation between Brett Calcott and David Abrahams
-------------------------------------------------------
:copyright: Copyright Brett Calcott and David Abrahams 2003. All
rights reserved.
:copyright: Copyright David Abrahams and Brett Calcott 2003. See
accompanying license_ for terms of use.
In both of these cases, I'm quite capable of reading code - but the
thing I don't get from scanning the source is a sense of the
@@ -107,8 +118,11 @@ Can you gesture in the general direction where these things are done?
Also,
http://mail.python.org/pipermail/c++-sig/2002-May/001023.html
http://mail.python.org/pipermail/c++-sig/2002-December/003115.html
http://aspn.activestate.com/ASPN/Mail/Message/1280898
http://mail.python.org/pipermail/c++-sig/2002-July/001755.html
from c++ to python:

View File

@@ -29,6 +29,36 @@
<hr>
<dl class="page-index">
<dt>11 Sept 2003</dt>
<dd>
<ul>
<li>Changed the response to multiple to-python converters being
registered for the same type from a hard error into warning;
Boost.Python now reports the offending type in the message.</li>
<li>Added builtin <code>std::wstring</code> conversions</li>
<li>Added <code>std::out_of_range</code> =&gt; Python
<code>IndexError</code> exception conversion, thanks to <a href=
"mailto:RaoulGough-at-yahoo.co.uk">Raoul Gough</a></li>
</ul>
</dd>
<dt>9 Sept 2003</dt>
<dd>Added new <code><a href="v2/str.html#str-spec">str</a></code></dd>
<dt>constructors which take a range of characters, allowing strings
containing nul (<code>'\0'</code>) characters.</dt>
<dt>8 Sept 2003</dt>
<dd>Added the ability to create methods from function objects (with an
<code>operator()</code>); see the <a href=
"v2/make_function.html#make_function-spec">make_function</a> docs for
more info.</dd>
<dt>10 August 2003</dt>
<dd>Added the new <code>properties</code> unit tests contributed by <a
@@ -78,7 +108,7 @@ BOOST_PYTHON_MODULE(test)
<dd><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
Gan&szlig;auge</a> has contributed <a href=
"v2/opaque_pointer_converter.html">opaque pointer support</a>.<br>
<a href="nicodemus-at-globalite.com.br">Bruno da Silva de Oliveira</a>
<a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de Oliveira</a>
has contributed the exciting <a href="../pyste/index.html">Pyste</a>
("Pie-steh") package.</dd>
@@ -150,7 +180,8 @@ BOOST_PYTHON_MODULE(test)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
1 August 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
11 September 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
@@ -31,7 +31,9 @@
<h2>Synopsis</h2>
<p>This is a list of available resources for support with Boost.Python
problems and feature requests.</p>
problems and feature requests. <b>Please try to resist emailing the
Boost.Python developers directly for support.</b> Use the following
resources instead; the developers are listening!</p>
<hr>
<dl class="page-index">
@@ -41,9 +43,11 @@
you Boost.Python.<br>
&nbsp;</dt>
<dt><b><a href="http://www.python.org/sigs/c++-sig/">The Python
<dt><b><a href=
"http://www.boost.org/more/mailing_lists.htm#cplussig">The Python
C++-sig</a></b> mailing list is a forum for discussing Python/C++
interoperability, and Boost.Python in particular.<br>
interoperability, and Boost.Python in particular. Post your
Boost.Python questions here.<br>
&nbsp;</dt>
<dt>The <b>Boost.Python <a href=
@@ -51,18 +55,17 @@
Pages</a></b> established by Mike Rovner as part of the <a href=
"http://www.python.org/cgi-bin/moinmoin">PythonInfo Wiki</a> serves as
a forum to gather peoples' experience and as a cookbook.<br>
&nbsp;</dt>
&nbsp;</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
17 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
12 Sept, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i></p>
Abrahams</a> 2003.</i></p>
</body>
</html>

View File

@@ -26,7 +26,7 @@
</table>
<p>
It was mentioned in passing in the previous section that
<tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt> and <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
<tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt> and <tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
can also be used for overloaded functions and member functions with a
common sequence of initial arguments. Here is an example:</p>
<code><pre>

View File

@@ -37,6 +37,11 @@ with every boost distribution: <b>bjam</b>.</p>
Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as &quot;the one and only way&quot;.
There are of course other build tools apart from <tt>bjam</tt>.
Take note however that the preferred build tool for Boost.Python is bjam.
There are so many ways to set up the build incorrectly. Experience shows
that 90% of the &quot;I can't build Boost.Python&quot; problems come from people
who had to use a different tool.
</td>
</tr>
</table>

View File

@@ -0,0 +1,210 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Creating Packages</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="general_techniques.html">
<link rel="next" href="extending_wrapped_objects_in_python.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Creating Packages</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="general_techniques.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="extending_wrapped_objects_in_python.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
A Python package is a collection of modules that provide to the user a certain
functionality. If you're not familiar on how to create packages, a good
introduction to them is provided in the
<a href="http://www.python.org/doc/current/tut/node8.html">
Python Tutorial</a>.</p>
<p>
But we are wrapping C++ code, using Boost.Python. How can we provide a nice
package interface to our users? To better explain some concepts, let's work
with an example.</p>
<p>
We have a C++ library that works with sounds: reading and writing various
formats, applying filters to the sound data, etc. It is named (conveniently)
<tt>sounds</tt>. Our library already has a neat C++ namespace hierarchy, like so: </p>
<code><pre>
<span class=identifier>sounds</span><span class=special>::</span><span class=identifier>core
</span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>io
</span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>filters
</span></pre></code>
<p>
We would like to present this same hierarchy to the Python user, allowing him
to write code like this:</p>
<code><pre>
<span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(...) </span>##<span class=identifier>echo </span><span class=identifier>is </span><span class=identifier>a </span><span class=identifier>C</span><span class=special>++ </span><span class=identifier>function
</span></pre></code>
<p>
The first step is to write the wrapping code. We have to export each module
separately with Boost.Python, like this:</p>
<code><pre>
<span class=comment>/* file core.cpp */
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>core</span><span class=special>)
{
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>core </span><span class=keyword>namespace </span><span class=special>*/
...
}
/* </span><span class=identifier>file </span><span class=identifier>io</span><span class=special>.</span><span class=identifier>cpp </span><span class=special>*/
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>io</span><span class=special>)
{
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>io </span><span class=keyword>namespace </span><span class=special>*/
...
}
/* </span><span class=identifier>file </span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>cpp </span><span class=special>*/
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>filters</span><span class=special>)
{
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>filters </span><span class=keyword>namespace </span><span class=special>*/
...
}
</span></pre></code>
<p>
Compiling these files will generate the following Python extensions:
<tt>core.pyd</tt>, <tt>io.pyd</tt> and <tt>filters.pyd</tt>.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> The extension <tt>.pyd</tt> is used for python extension modules, which
are just shared libraries. Using the default for your system, like <tt>.so</tt> for
Unix and <tt>.dll</tt> for Windows, works just as well. </td>
</tr>
</table>
<p>
Now, we create this directory structure for our Python package:</p>
<code><pre>
sounds/
__init__.py
core.pyd
filters.pyd
io.pyd
</pre></code><p>
The file <tt>__init__.py</tt> is what tells Python that the directory <tt>sounds/</tt> is
actually a Python package. It can be a empty file, but can also perform some
magic, that will be shown later. </p>
<p>
Now our package is ready. All the user has to do is put <tt>sounds</tt> into his
<a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000">
PYTHONPATH</a> and fire up the interpreter:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>io
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sound </span><span class=special>= </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>io</span><span class=special>.</span><span class=identifier>open</span><span class=special>(</span><span class=literal>'file.mp3'</span><span class=special>)
&gt;&gt;&gt; </span><span class=identifier>new_sound </span><span class=special>= </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(</span><span class=identifier>sound</span><span class=special>, </span><span class=number>1.0</span><span class=special>)
</span></pre></code>
<p>
Nice heh? </p>
<p>
This is the simplest way to create hierarchies of packages, but it is not very
flexible. What if we want to add a <i>pure</i> Python function to the filters
package, for instance, one that applies 3 filters in a sound object at once?
Sure, you can do this in C++ and export it, but why not do so in Python? You
don't have to recompile the extension modules, plus it will be easier to write
it.</p>
<p>
If we want this flexibility, we will have to complicate our package hierarchy a
little. First, we will have to change the name of the extension modules:</p>
<code><pre>
<span class=comment>/* file core.cpp */
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_core</span><span class=special>)
{
...
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>core </span><span class=keyword>namespace </span><span class=special>*/
}
</span></pre></code>
<p>
Note that we added an underscore to the module name. The filename will have to
be changed to <tt>_core.pyd</tt> as well, and we do the same to the other extension modules.
Now, we change our package hierarchy like so:</p>
<code><pre>
sounds/
__init__.py
core/
__init__.py
_core.pyd
filters/
__init__.py
_filters.pyd
io/
__init__.py
_io.pyd
</pre></code><p>
Note that we created a directory for each extension module, and added a
__init__.py to each one. But if we leave it that way, the user will have to
access the functions in the core module with this syntax: </p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>core</span><span class=special>.</span><span class=identifier>_core
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>core</span><span class=special>.</span><span class=identifier>_core</span><span class=special>.</span><span class=identifier>foo</span><span class=special>(...)
</span></pre></code>
<p>
which is not what we want. But here enters the <tt>__init__.py</tt> magic: everything
that is brought to the <tt>__init__.py</tt> namespace can be accessed directly by the
user. So, all we have to do is bring the entire namespace from <tt>_core.pyd</tt>
to <tt>core/__init__.py</tt>. So add this line of code to <tt>sounds/core/__init__.py</tt>:</p>
<code><pre>
<span class=identifier>from </span><span class=identifier>_core </span><span class=identifier>import </span><span class=special>*
</span></pre></code>
<p>
We do the same for the other packages. Now the user accesses the functions and
classes in the extension modules like before:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(...)
</span></pre></code>
<p>
with the additional benefit that we can easily add pure Python functions to
any module, in a way that the user can't tell the difference between a C++
function and a Python function. Let's add a <i>pure</i> Python function,
<tt>echo_noise</tt>, to the <tt>filters</tt> package. This function applies both the
<tt>echo</tt> and <tt>noise</tt> filters in sequence in the given <tt>sound</tt> object. We
create a file named <tt>sounds/filters/echo_noise.py</tt> and code our function:</p>
<code><pre>
<span class=identifier>import </span><span class=identifier>_filters
</span><span class=identifier>def </span><span class=identifier>echo_noise</span><span class=special>(</span><span class=identifier>sound</span><span class=special>):
</span><span class=identifier>s </span><span class=special>= </span><span class=identifier>_filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(</span><span class=identifier>sound</span><span class=special>)
</span><span class=identifier>s </span><span class=special>= </span><span class=identifier>_filters</span><span class=special>.</span><span class=identifier>noise</span><span class=special>(</span><span class=identifier>sound</span><span class=special>)
</span><span class=keyword>return </span><span class=identifier>s
</span></pre></code>
<p>
Next, we add this line to <tt>sounds/filters/__init__.py</tt>:</p>
<code><pre>
<span class=identifier>from </span><span class=identifier>echo_noise </span><span class=identifier>import </span><span class=identifier>echo_noise
</span></pre></code>
<p>
And that's it. The user now accesses this function like any other function
from the <tt>filters</tt> package:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo_noise</span><span class=special>(...)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="general_techniques.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="extending_wrapped_objects_in_python.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -93,7 +93,7 @@ arguments or overloads with a common sequence of initial arguments come
into play. Another macro is provided to make this a breeze.</p>
<p>
Like <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>,
<tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt> may be used to automatically create
<tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> may be used to automatically create
the thin wrappers for wrapping member functions. Let's have an example:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>george

View File

@@ -44,10 +44,9 @@ both Boost.Python's and Python's static link library.</p>
Boost.Python's static link library comes in two variants. Both are located
in Boost's <tt>/libs/python/build/bin-stage</tt> subdirectory. On Windows, the
variants are called <tt>boost_python.lib</tt> (for release builds) and
<tt>boost_python_debug.lib</tt> (for debugging). If you can't find the
libraries, you probably haven't built Boost.Python yet. See <a
href="../../building.html">Building and Testing</a> on how to do
this.</p>
<tt>boost_python_debug.lib</tt> (for debugging). If you can't find the libraries,
you probably haven't built Boost.Python yet. See <a href="../../building.html">
Building and Testing</a> on how to do this.</p>
<p>
Python's static link library can be found in the <tt>/libs</tt> subdirectory of
your Python directory. On Windows it is called pythonXY.lib where X.Y is
@@ -88,7 +87,7 @@ Py_Finalize</a>() to stop the interpreter and release its resources.</li></ol><p
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 Dirk Gerrits<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -4,6 +4,7 @@
<title>Exception Translation</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="iterators.html">
<link rel="next" href="general_techniques.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -20,7 +21,7 @@
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
<td width="20"><a href="general_techniques.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -47,7 +48,7 @@ Users may provide custom translation. Here's an example:</p>
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
<td width="20"><a href="general_techniques.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>

View File

@@ -0,0 +1,134 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Extending Wrapped Objects in Python</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="creating_packages.html">
<link rel="next" href="reducing_compiling_time.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Extending Wrapped Objects in Python</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="creating_packages.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="reducing_compiling_time.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Thanks to Python's flexibility, you can easily add new methods to a class,
even after it was already created:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>C</span><span class=special>(</span><span class=identifier>object</span><span class=special>): </span><span class=identifier>pass
</span><span class=special>&gt;&gt;&gt;
&gt;&gt;&gt; </span>##<span class=identifier>a </span><span class=identifier>regular </span><span class=identifier>function
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>def </span><span class=identifier>C_str</span><span class=special>(</span><span class=identifier>self</span><span class=special>): </span><span class=keyword>return </span><span class=literal>'A C instance!'
</span><span class=special>&gt;&gt;&gt;
&gt;&gt;&gt; </span>##<span class=identifier>now </span><span class=identifier>we </span><span class=identifier>turn </span><span class=identifier>it </span><span class=identifier>in </span><span class=identifier>a </span><span class=identifier>member </span><span class=identifier>function
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>C</span><span class=special>.</span><span class=identifier>__str__ </span><span class=special>= </span><span class=identifier>C_str
</span><span class=special>&gt;&gt;&gt;
&gt;&gt;&gt; </span><span class=identifier>c </span><span class=special>= </span><span class=identifier>C</span><span class=special>()
&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>c
</span><span class=identifier>A </span><span class=identifier>C </span><span class=identifier>instance</span><span class=special>!
&gt;&gt;&gt; </span><span class=identifier>C_str</span><span class=special>(</span><span class=identifier>c</span><span class=special>)
</span><span class=identifier>A </span><span class=identifier>C </span><span class=identifier>instance</span><span class=special>!
</span></pre></code>
<p>
Yes, Python rox. <img src="theme/smiley.gif"></img></p>
<p>
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class <tt>point</tt> in C++:</p>
<code><pre>
<span class=keyword>class </span><span class=identifier>point </span><span class=special>{...};
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_geom</span><span class=special>)
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>&gt;(</span><span class=string>&quot;point&quot;</span><span class=special>)...;
}
</span></pre></code>
<p>
If we are using the technique from the previous session, <a href="creating_packages.html">
Creating Packages</a>, we can code directly into <tt>geom/__init__.py</tt>:</p>
<code><pre>
<span class=identifier>from </span><span class=identifier>_geom </span><span class=identifier>import </span><span class=special>*
</span>##<span class=identifier>a </span><span class=identifier>regular </span><span class=identifier>function
</span><span class=identifier>def </span><span class=identifier>point_str</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=keyword>return </span><span class=identifier>str</span><span class=special>((</span><span class=identifier>self</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>self</span><span class=special>.</span><span class=identifier>y</span><span class=special>))
</span>##<span class=identifier>now </span><span class=identifier>we </span><span class=identifier>turn </span><span class=identifier>it </span><span class=identifier>into </span><span class=identifier>a </span><span class=identifier>member </span><span class=identifier>function
</span><span class=identifier>point</span><span class=special>.</span><span class=identifier>__str__ </span><span class=special>= </span><span class=identifier>point_str
</span></pre></code>
<p>
<b>All</b> point instances created from C++ will also have this member function!
This technique has several advantages:</p>
<ul><li>Cut down compile times to zero for these additional functions</li><li>Reduce the memory footprint to virtually zero</li><li>Minimize the need to recompile</li><li>Rapid prototyping (you can move the code to C++ if required without changing the interface)</li></ul><p>
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that &quot;injects&quot; methods in other classes.</p>
<code><pre>
##<span class=identifier>The </span><span class=identifier>one </span><span class=identifier>Boost</span><span class=special>.</span><span class=identifier>Python </span><span class=identifier>uses </span><span class=keyword>for </span><span class=identifier>all </span><span class=identifier>wrapped </span><span class=identifier>classes</span><span class=special>.
</span>##<span class=identifier>You </span><span class=identifier>can </span><span class=identifier>use </span><span class=identifier>here </span><span class=identifier>any </span><span class=keyword>class </span><span class=identifier>exported </span><span class=identifier>by </span><span class=identifier>Boost </span><span class=identifier>instead </span><span class=identifier>of </span><span class=string>&quot;point&quot;
</span><span class=identifier>BoostPythonMetaclass </span><span class=special>= </span><span class=identifier>point</span><span class=special>.</span><span class=identifier>__class__
</span><span class=keyword>class </span><span class=identifier>injector</span><span class=special>(</span><span class=identifier>object</span><span class=special>):
</span><span class=keyword>class </span><span class=identifier>__metaclass__</span><span class=special>(</span><span class=identifier>BoostPythonMetaclass</span><span class=special>):
</span><span class=identifier>def </span><span class=identifier>__init__</span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>name</span><span class=special>, </span><span class=identifier>bases</span><span class=special>, </span><span class=identifier>dict</span><span class=special>):
</span><span class=keyword>for </span><span class=identifier>b </span><span class=identifier>in </span><span class=identifier>bases</span><span class=special>:
</span><span class=keyword>if </span><span class=identifier>type</span><span class=special>(</span><span class=identifier>b</span><span class=special>) </span><span class=keyword>not </span><span class=identifier>in </span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>type</span><span class=special>):
</span><span class=keyword>for </span><span class=identifier>k</span><span class=special>,</span><span class=identifier>v </span><span class=identifier>in </span><span class=identifier>dict</span><span class=special>.</span><span class=identifier>items</span><span class=special>():
</span><span class=identifier>setattr</span><span class=special>(</span><span class=identifier>b</span><span class=special>,</span><span class=identifier>k</span><span class=special>,</span><span class=identifier>v</span><span class=special>)
</span><span class=keyword>return </span><span class=identifier>type</span><span class=special>.</span><span class=identifier>__init__</span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>name</span><span class=special>, </span><span class=identifier>bases</span><span class=special>, </span><span class=identifier>dict</span><span class=special>)
</span>##<span class=identifier>inject </span><span class=identifier>some </span><span class=identifier>methods </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>point </span><span class=identifier>foo
</span><span class=keyword>class </span><span class=identifier>more_point</span><span class=special>(</span><span class=identifier>injector</span><span class=special>, </span><span class=identifier>point</span><span class=special>):
</span><span class=identifier>def </span><span class=identifier>__repr__</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=keyword>return </span><span class=literal>'Point(x=%s, y=%s)' </span><span class=special>% (</span><span class=identifier>self</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>self</span><span class=special>.</span><span class=identifier>y</span><span class=special>)
</span><span class=identifier>def </span><span class=identifier>foo</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=identifier>print </span><span class=literal>'foo!'
</span></pre></code>
<p>
Now let's see how it got:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>point</span><span class=special>()
</span><span class=identifier>Point</span><span class=special>(</span><span class=identifier>x</span><span class=special>=</span><span class=number>10</span><span class=special>, </span><span class=identifier>y</span><span class=special>=</span><span class=number>10</span><span class=special>)
&gt;&gt;&gt; </span><span class=identifier>point</span><span class=special>().</span><span class=identifier>foo</span><span class=special>()
</span><span class=identifier>foo</span><span class=special>!
</span></pre></code>
<p>
Another useful idea is to replace constructors with factory functions:</p>
<code><pre>
<span class=identifier>_point </span><span class=special>= </span><span class=identifier>point
</span><span class=identifier>def </span><span class=identifier>point</span><span class=special>(</span><span class=identifier>x</span><span class=special>=</span><span class=number>0</span><span class=special>, </span><span class=identifier>y</span><span class=special>=</span><span class=number>0</span><span class=special>):
</span><span class=keyword>return </span><span class=identifier>_point</span><span class=special>(</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>y</span><span class=special>)
</span></pre></code>
<p>
In this simple case there is not much gained, but for constructurs with
many overloads and/or arguments this is often a great simplification, again
with virtually zero memory footprint and zero compile-time overhead for
the keyword support.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="creating_packages.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="reducing_compiling_time.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -0,0 +1,43 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>General Techniques</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="exception_translation.html">
<link rel="next" href="creating_packages.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>General Techniques</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exception_translation.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="creating_packages.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Here are presented some useful techniques that you can use while wrapping code with Boost.Python.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exception_translation.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="creating_packages.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -62,6 +62,11 @@ with every boost distribution: [*bjam].
Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as "the one and only way".
There are of course other build tools apart from [^bjam].
Take note however that the preferred build tool for Boost.Python is bjam.
There are so many ways to set up the build incorrectly. Experience shows
that 90% of the "I can't build Boost.Python" problems come from people
who had to use a different tool.
]
We shall skip over the details. Our objective will be to simply create the
@@ -1005,7 +1010,7 @@ arguments or overloads with a common sequence of initial arguments come
into play. Another macro is provided to make this a breeze.
Like [^BOOST_PYTHON_FUNCTION_OVERLOADS],
[^BOOST_PYTHON_FUNCTION_OVERLOADS] may be used to automatically create
[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] may be used to automatically create
the thin wrappers for wrapping member functions. Let's have an example:
struct george
@@ -1053,7 +1058,7 @@ Notice the use of [^init<...>] and [^optional<...>] to signify the default
[page:1 Auto-Overloading]
It was mentioned in passing in the previous section that
[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_FUNCTION_OVERLOADS]
[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
can also be used for overloaded functions and member functions with a
common sequence of initial arguments. Here is an example:
@@ -1693,7 +1698,7 @@ with an example.
We have a C++ library that works with sounds: reading and writing various
formats, applying filters to the sound data, etc. It is named (conveniently)
[^sounds]. Our library already has a neat C++ namespace hierarchy, like so:
[^sounds]. Our library already has a neat C++ namespace hierarchy, like so:
sounds::core
sounds::io
@@ -1713,21 +1718,21 @@ separately with Boost.Python, like this:
{
/* export everything in the sounds::core namespace */
...
}
}
/* file io.cpp */
BOOST_PYTHON_MODULE(io)
{
/* export everything in the sounds::io namespace */
...
}
}
/* file filters.cpp */
BOOST_PYTHON_MODULE(filters)
{
/* export everything in the sounds::filters namespace */
...
}
}
Compiling these files will generate the following Python extensions:
[^core.pyd], [^io.pyd] and [^filters.pyd].
@@ -1748,7 +1753,7 @@ Now, we create this directory structure for our Python package:
The file [^__init__.py] is what tells Python that the directory [^sounds/] is
actually a Python package. It can be a empty file, but can also perform some
magic, that will be shown later.
magic, that will be shown later.
Now our package is ready. All the user has to do is put [^sounds] into his
[@http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000 PYTHONPATH] and fire up the interpreter:
@@ -1758,7 +1763,7 @@ Now our package is ready. All the user has to do is put [^sounds] into his
>>> sound = sounds.io.open('file.mp3')
>>> new_sound = sounds.filters.echo(sound, 1.0)
Nice heh?
Nice heh?
This is the simplest way to create hierarchies of packages, but it is not very
flexible. What if we want to add a ['pure] Python function to the filters
@@ -1775,7 +1780,7 @@ little. First, we will have to change the name of the extension modules:
{
...
/* export everything in the sounds::core namespace */
}
}
Note that we added an underscore to the module name. The filename will have to
be changed to [^_core.pyd] as well, and we do the same to the other extension modules.
@@ -1797,7 +1802,7 @@ Now, we change our package hierarchy like so:
Note that we created a directory for each extension module, and added a
__init__.py to each one. But if we leave it that way, the user will have to
access the functions in the core module with this syntax:
access the functions in the core module with this syntax:
>>> import sounds.core._core
>>> sounds.core._core.foo(...)
@@ -1849,7 +1854,7 @@ even after it was already created:
>>> def C_str(self): return 'A C instance!'
>>>
>>> # now we turn it in a member function
>>> C.__str__ = C_str
>>> C.__str__ = C_str
>>>
>>> c = C()
>>> print c
@@ -1869,7 +1874,7 @@ we have a class [^point] in C++:
class_<point>("point")...;
}
If we are using the technique from the previous session, [@creating_packages.html
If we are using the technique from the previous session, [@creating_packages.html
Creating Packages], we can code directly into [^geom/__init__.py]:
from _geom import *
@@ -1877,7 +1882,7 @@ Creating Packages], we can code directly into [^geom/__init__.py]:
# a regular function
def point_str(self):
return str((self.x, self.y))
# now we turn it into a member function
point.__str__ = point_str
@@ -1892,9 +1897,9 @@ This technique has several advantages:
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.
# The one Boost.Python uses for all wrapped classes.
# The one Boost.Python uses for all wrapped classes.
# You can use here any class exported by Boost instead of "point"
BoostPythonMetaclass = point.__class__
BoostPythonMetaclass = point.__class__
class injector(object):
class __metaclass__(BoostPythonMetaclass):
@@ -1941,10 +1946,10 @@ class_ definitions in multiple files:
/* file point.cpp */
#include <point.h>
#include <boost/python.hpp>
void export_point()
{
class_<point>("point")...;
class_<point>("point")...;
}
/* file triangle.cpp */
@@ -1957,11 +1962,11 @@ class_ definitions in multiple files:
}
Now you create a file [^main.cpp], which contains the [^BOOST_PYTHON_MODULE]
macro, and call the various export functions inside it.
macro, and call the various export functions inside it.
void export_point();
void export_triangle();
BOOST_PYTHON_MODULE(_geom)
{
export_point();
@@ -1979,15 +1984,15 @@ usual approach:
{
class_<point>("point")...;
class_<triangle>("triangle")...;
}
}
but the memory is kept under control.
but the memory is kept under control.
This method is recommended too if you are developing the C++ library and
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.
[blurb __note__ If you're exporting your classes with [@../../../pyste/index.html Pyste],
[blurb __note__ If you're exporting your classes with [@../../../pyste/index.html Pyste],
take a look at the [^--multiple] option, that generates the wrappers in
various files as demonstrated here.]

View File

@@ -0,0 +1,115 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Reducing Compiling Time</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="extending_wrapped_objects_in_python.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Reducing Compiling Time</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extending_wrapped_objects_in_python.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<p>
If you have ever exported a lot of classes, you know that it takes quite a good
time to compile the Boost.Python wrappers. Plus the memory consumption can
easily become too high. If this is causing you problems, you can split the
class_ definitions in multiple files:</p>
<code><pre>
<span class=comment>/* file point.cpp */
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=keyword>void </span><span class=identifier>export_point</span><span class=special>()
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>&gt;(</span><span class=string>&quot;point&quot;</span><span class=special>)...;
}
/* </span><span class=identifier>file </span><span class=identifier>triangle</span><span class=special>.</span><span class=identifier>cpp </span><span class=special>*/
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=keyword>void </span><span class=identifier>export_triangle</span><span class=special>()
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>&gt;(</span><span class=string>&quot;triangle&quot;</span><span class=special>)...;
}
</span></pre></code>
<p>
Now you create a file <tt>main.cpp</tt>, which contains the <tt>BOOST_PYTHON_MODULE</tt>
macro, and call the various export functions inside it. </p>
<code><pre>
<span class=keyword>void </span><span class=identifier>export_point</span><span class=special>();
</span><span class=keyword>void </span><span class=identifier>export_triangle</span><span class=special>();
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_geom</span><span class=special>)
{
</span><span class=identifier>export_point</span><span class=special>();
</span><span class=identifier>export_triangle</span><span class=special>();
}
</span></pre></code>
<p>
Compiling and linking together all this files produces the same result as the
usual approach:</p>
<code><pre>
<span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_geom</span><span class=special>)
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>&gt;(</span><span class=string>&quot;point&quot;</span><span class=special>)...;
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>&gt;(</span><span class=string>&quot;triangle&quot;</span><span class=special>)...;
}
</span></pre></code>
<p>
but the memory is kept under control. </p>
<p>
This method is recommended too if you are developing the C++ library and
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> If you're exporting your classes with <a href="../../../pyste/index.html">
Pyste</a>,
take a look at the <tt>--multiple</tt> option, that generates the wrappers in
various files as demonstrated here. </td>
</tr>
</table>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> This method is useful too if you are getting the error message
<i>&quot;fatal error C1204:Compiler limit:internal structure overflow&quot;</i> when compiling
a large source file, as explained in the <a href="../../v2/faq.html#c1204">
FAQ</a>. </td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extending_wrapped_objects_in_python.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -145,15 +145,13 @@ previous section</a>: the aptly named <tt>object</tt>
class and it's derivatives. What we haven't seen, is that they can be
constructed from a <tt>handle</tt>. The following examples should illustrate this
fact:</p>
<code>
<pre>
<code><pre>
<span class=identifier>handle</span><span class=special>&lt;&gt; </span><span class=identifier>main_module</span><span class=special>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyImport_AddModule</span><span class=special>(</span><span class=string>&quot;__main__&quot;</span><span class=special>) ));
</span><span class=identifier>dict </span><span class=identifier>main_namespace</span><span class=special>(</span><span class=identifier>handle</span><span class=special>&lt;&gt;(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyModule_GetDict</span><span class=special>(</span><span class=identifier>main_module</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) )));
</span><span class=identifier>handle</span><span class=special>&lt;&gt;( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>&quot;result = 5 ** 2&quot;</span><span class=special>, </span><span class=identifier>Py_file_input</span><span class=special>,
</span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>()) );
</span><span class=keyword>int </span><span class=identifier>five_squared </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;( </span><span class=identifier>main_namespace</span><span class=special>[</span><span class=string>&quot;result&quot;</span><span class=special>] );
</span></pre>
</code>
</span></pre></code>
<p>
Here we create a dictionary object for the <tt>__main__</tt> module's namespace.
Then we assign 5 squared to the result variable and read this variable from
@@ -229,7 +227,7 @@ allow_null</a> function in the same way you'd use borrowed:</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 Dirk Gerrits<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -145,6 +145,26 @@
<a href="doc/exception_translation.html">Exception Translation</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/general_techniques.html">General Techniques</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/creating_packages.html">Creating Packages</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/extending_wrapped_objects_in_python.html">Extending Wrapped Objects in Python</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/reducing_compiling_time.html">Reducing Compiling Time</a>
</td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>

View File

@@ -45,7 +45,7 @@ of work got done...
<h3><a name="arity">Arbitrary Arity Support</a></h3>
I began using the <a
href="../../../preprocessor/doc/index.htm">Boost.Preprocessor</a>
href="../../../preprocessor/doc/index.html">Boost.Preprocessor</a>
metaprogramming library to generate support for functions and member
functions of arbitrary arity, which was, to say the least, quite an
adventure. The feedback cycle resulting from my foray into

View File

@@ -28,50 +28,40 @@
<h2><a name="introduction"></a>Introduction</h2>
<p>Instances of a dereferenceable type can be used like a pointer to access an lvalue.
<p>Instances of a Dereferenceable type can be used like a pointer to access an lvalue.
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="Dereferenceable-concept"></a>Dereferenceable Concept</h3>
<p>In the table below, <code><b>x</b></code> denotes an object whose
type is a model of Dereferenceable.
<table summary="Dereferenceable expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Requirements</b></td>
</tr>
<tr>
<td valign="top"><code>*x</code></td>
<td>An lvalue
</tr>
</table>
If <code><b>x</b></code> is not a pointer type, it also must satsify the following expression:
<p>In the table below, <code><b>T</b></code> is a model of
Dereferenceable, and <code><b>x</b></code> denotes an object of
type <code>T</code>. In addition, all pointers are Dereferenceable.
<table summary="Dereferenceable expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Result</b></td>
<td><b>Operational Semantics</b></td>
</tr>
<tr>
<td valign="top"><code>x.get()</code></td>
<td><code>get_pointer(x)</code></td>
<td>convertible to <code><a href="pointee.html#pointee-spec">pointee</a>&lt;T&gt;::type*</code>
<td><code>&amp;*x</code>, or a null pointer
</tr>
<tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 November, 2002
18 December, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>
Abrahams</a> 2002-2003. All Rights Reserved.</i>
<p>Permission to copy, use, modify, sell
and distribute this software is granted provided this copyright notice appears

View File

@@ -54,7 +54,7 @@ focused on reducing the support burden. In recent weeks, responding to
requests for support, espcially surrounding building the library, had
begun to impede progress on development. There was a major push to
release a stable 1.28.0 of Boost, including documentation of <a
href="../../../../tools/build/index.html">Boost.Build</a> and specific
href="../../../../tools/build/v1/build_system.htm">Boost.Build</a> and specific
<a href="../building.html">instructions</a> for building Boost.Python
v1. The documentation for Boost.Python v2 was also updated as
described <a href="#documentation">here</a>.
@@ -70,7 +70,7 @@ described <a href="#documentation">here</a>.
Martin Casado which uncovered the key mechanism required to allow
shared libraries to use functions from the Python executable. The
current solution used in Boost.Build relies on a <a
href="../../../../tools/build/gen_aix_import_file.py">Python
href="../../../../tools/build/v1/gen_aix_import_file.py">Python
Script</a> as part of the build process. This is not a problem for
Boost.Python, as Python will be available. However, the commands
issued by the script are so simple that a 100%-pure-Boost.Jam
@@ -84,8 +84,7 @@ described <a href="#documentation">here</a>.
Support for exposing C++ operators and functions as the corresponding
Python special methods was added. Thinking that the Boost.Python
<a href="../special.html#numeric">v1 interface</a> was a little too
esoteric (especially the use of
v1 interface was a little too esoteric (especially the use of
<code>left_operand&lt;...&gt;/right_operand&lt;...&gt;</code> for
asymmetric operands), I introduced a simple form of <a
href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">expression
@@ -155,7 +154,7 @@ This forced the exposure of the <a
href="http://www.python.org/2.2/descrintro.html#property"><code>property</code></a>
interface used internally to implement the data member exposure
facility described in <a
href="Mar2002#data_members">March</a>. Properties are an
href="Mar2002.html#data_members">March</a>. Properties are an
incredibly useful idiom, so it's good to be able to provide them
at little new development cost.
@@ -212,7 +211,7 @@ Major updates were made to the following pages:
<blockquote>
<dl>
<dt><a href="call.html">call.html</a><dd> <dt><a href="updated">updated</a><dd>
<dt><a href="call.html">call.html</a><dd> <dt>updated<dd>
<dt><a href="class.html">class.html</a><dd>
<dt><a href="reference.html">reference.html</a><dd>
</dl>

View File

@@ -72,7 +72,7 @@
use the new preproccessor metaprogramming constructs and helping us to
work around buggy and slow C++ preprocessors.</p>
<p><a href="nicodemus-at-globalite.com.br">Bruno da Silva de
<p><a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de
Oliveira</a> contributed the ingenious <a
href="../../pyste/index.html">Pyste</a> (&quot;Pie-Steh&quot;)
code generator.

View File

@@ -281,6 +281,7 @@ namespace boost { namespace python
// pickle support
template &lt;typename PickleSuite&gt;
self&amp; def_pickle(PickleSuite const&amp;);
self&amp; enable_pickling();
};
}}
</pre>
@@ -709,6 +710,21 @@ class_&amp; def_pickle(PickleSuite const&amp;);
checks.</dt>
</dl>
<br>
<pre>
class_&amp; enable_pickling();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Defines the <code>__reduce__</code> method and
the <code>__safe_for_unpickling__</code> attribute.
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Light-weight alternative to
<code>def_pickle()</code>. Enables implementation of
<a href="pickle.html">pickle support</a> from Python.</dt>
</dl>
<br>
<h3><a name="bases-spec"></a>Class template

135
doc/v2/def_visitor.html Normal file
View File

@@ -0,0 +1,135 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="Microsoft FrontPage 5.0">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/def_visitor.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html"><font size="7">Boost.Python</font></a></h1>
<h2 align="center">Header &lt;boost/python/def_visitor.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#def_visitor-spec">Class <code>def_visitor</code></a>
<dd> <a href="#def_visitor-synopsis">Class <code>def_visitor</code>
synopsis</a></dd>
<dd> <a href="#def_visitor-requirements">Class <code>def_visitor</code>
requirements</a></dd>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/def_visitor.hpp&gt;</code> provides a generic visitation
interface through which the <a href="class.html">class_</a> <b>def</b> member
functionality can be extended non-intrusively to avoid cluttering the <a href="class.html">class_</a>
interface. It declares the <code>def_visitor&lt;T&gt; </code>class template,
which is parameterized on the derived type <tt>DerivedVisitor</tt>, which provides
the actual <b>def</b> functionality through its <b>visit</b> member functions.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="def_visitor-spec"></a>Class template <code>def_visitor&lt;DerivedVisitor&gt;</code></h3>
<p>The class def_visitor is a base class paramaterized by its derived class. The
def_visitor class is a protocol class. Its derived class, DerivedVisitor, is
expected to have a member function visit. The def_visitor class is never instantiated
directly. Instead, an instance of its subclass, DerivedVisitor,&nbsp; is passed
on as an argument to the <a href="class.html">class_</a> def member function.
<h4>
<a name="def_visitor-synopsis" id="def_visitor-synopsis"></a>Class <code>def_visitor </code>synopsis</h4>
<pre>namespace boost { namespace python {
template &lt;class DerivedVisitor&gt;
class def_visitor {};
}</pre>
<h3><a name="def_visitor-requirements"></a><code>def_visitor </code>requirements</h3>
<p>The <span class="pre">client supplied class </span><span class="pre"></span><tt class="literal"><span class="pre">DerivedVisitor</span></tt>
template parameter is expected to:
<ul>
<li>be privately derived from def_visitor</li>
<li>grant friend access to class def_visitor_access</li>
<li>define either or both visit member functions listed in the table below:</li>
</ul>
<table border class="table">
<tr>
<td width="181" nowrap><b>Expression</b></td>
<td width="85"><b>Return Type</b></td>
<td width="330"><b>Requirements</b></td>
<td width="259"><b>Effects</b></td>
</tr>
<tr>
<td nowrap>visitor.visit(cls)</td>
<td>void</td>
<td>cls is an instance of a <a href="class.html">class_</a>&nbsp; being wrapped
to Python. visitor is a def_visitor derived class.</td>
<td>A call to cls.def(visitor) forwards to this member function.</td>
</tr>
<tr>
<td nowrap>visitor.visit(cls, name, options)</td>
<td>void</td>
<td>cls is a class_ instance, name is a C string. visitor is a def_visitor
derived class. options is a context specific optional argument.</td>
<td>A call to cls.def(name, visitor) or cls.def(name, visitor, options) forwards
to this member function. </td>
</tr>
</table>
<h2><a name="examples"></a>Example</h2>
<pre>class X {/*...*/};<br>
class my_def_visitor : boost::python::def_visitor&lt;my_def_visitor&gt;
{
friend class def_visitor_access;
template &lt;class classT&gt;
void visit(classT&amp; c) const
{
c
.def(&quot;foo&quot;, &amp;my_def_visitor::foo)
.def(&quot;bar&quot;, &amp;my_def_visitor::bar)
;
}
static void foo(X&amp; self);
static void bar(X&amp; self);
};
BOOST_PYTHON_MODULE(my_ext)
{
class_&lt;X&gt;(&quot;X&quot;)
.def(my_def_visitor())
;
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->27 August, 2003<!--webbot bot="Timestamp" endspan i-checksum="34484" -->
</p>
<p><i>&copy; Copyright Joel de Guzman 2003. All Rights Reserved.</i>

View File

@@ -58,10 +58,25 @@
<dt><a href="#ownership">How can I wrap a function which needs to take
ownership of a raw pointer?</a></dt>
<dt><a href="#slow_compilation">Compilation takes too much time and eats too much memory!
<dt><a href="#slow_compilation">Compilation takes too much time and eats too much memory!
What can I do to make it faster?</a></dt>
<dt><a href="#packages">How do I create sub-packages using Boost.Python?</a></dt>
<dt><a href="#packages">How do I create sub-packages using Boost.Python?</a></dt>
<dt><a href="#msvcthrowbug"
>error C2064: term does not evaluate to a function taking 2 arguments</a>
</dt>
<dt><a href="#voidptr">How do I handle <tt>void *</tt> conversion?</a></dt>
<dt><a href="#custom_string"
>How can I automatically convert my custom string type to
and from a Python string?</a></dt>
<dt><a href="#topythonconversionfailed">Why is my automatic to-python conversion not being
found?</a></dt>
<dt><a href="#threadsupport">Is Boost.Python thread-aware/compatible with multiple interpreters?</a></dt>
</dl>
<hr>
@@ -87,7 +102,7 @@ And then:
<pre>
&gt;&gt;&gt; def hello(s):
... print s
... print s
...
&gt;&gt;&gt; foo(hello)
hello, world!
@@ -119,7 +134,7 @@ hello, world!
<h2><a name="dangling">I'm getting the "attempt to return dangling
reference" error. What am I doing wrong?</a></h2>
That exception is protecting you from causing a nasty crash. It usually
happens in response to some code like this:
happens in response to some code like this:
<pre>
period const&amp; get_floating_frequency() const
{
@@ -127,7 +142,7 @@ period const&amp; get_floating_frequency() const
m_self,"get_floating_frequency");
}
</pre>
And you get:
And you get:
<pre>
ReferenceError: Attempt to return dangling reference to object of type:
class period
@@ -158,7 +173,7 @@ class period
I have the choice of using copy_const_reference or
return_internal_reference. Are there considerations that would lead me
to prefer one over the other, such as size of generated code or memory
overhead?</i>
overhead?</i>
<p><b>A:</b> copy_const_reference will make an instance with storage
for one of your objects, size = base_size + 12 * sizeof(double).
@@ -180,7 +195,7 @@ class period
<ol>
<li>
Using the regular <code>class_&lt;&gt;</code> wrapper:
Using the regular <code>class_&lt;&gt;</code> wrapper:
<pre>
class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
.def(...)
@@ -189,13 +204,13 @@ class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
</pre>
This can be moved to a template so that several types (double, int,
long, etc.) can be wrapped with the same code. This technique is used
in the file
in the file
<blockquote>
scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h
</blockquote>
in the "scitbx" package. The file could easily be modified for
wrapping std::vector&lt;&gt; instantiations.
wrapping std::vector&lt;&gt; instantiations.
<p>This type of C++/Python binding is most suitable for containers
that may contain a large number of elements (&gt;10000).</p>
@@ -203,19 +218,19 @@ class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
<li>
Using custom rvalue converters. Boost.Python "rvalue converters"
match function signatures such as:
match function signatures such as:
<pre>
void foo(std::vector&lt;double&gt; const&amp; array); // pass by const-reference
void foo(std::vector&lt;double&gt; array); // pass by value
</pre>
Some custom rvalue converters are implemented in the file
Some custom rvalue converters are implemented in the file
<blockquote>
scitbx/include/scitbx/boost_python/container_conversions.h
</blockquote>
This code can be used to convert from C++ container types such as
std::vector&lt;&gt; or std::list&lt;&gt; to Python tuples and vice
versa. A few simple examples can be found in the file
versa. A few simple examples can be found in the file
<blockquote>
scitbx/array_family/boost_python/regression_test_module.cpp
@@ -230,7 +245,7 @@ void foo(std::vector&lt;double&gt; array); // pass by value
rvalue converters that convert to a "math_array" type instead of tuples.
This is currently not implemented but is possible within the framework of
Boost.Python V2 as it will be released in the next couple of weeks. [ed.:
this was posted on 2002/03/10]
this was posted on 2002/03/10]
<p>It would also be useful to also have "custom lvalue converters" such
as std::vector&lt;&gt; &lt;-&gt; Python list. These converters would
@@ -245,7 +260,7 @@ void foo(std::vector&lt;double&gt;&amp; array)
}
}
</pre>
Python:
Python:
<pre>
&gt;&gt;&gt; l = [1, 2, 3]
&gt;&gt;&gt; foo(l)
@@ -253,7 +268,7 @@ void foo(std::vector&lt;double&gt;&amp; array)
[2, 4, 6]
</pre>
Custom lvalue converters require changes to the Boost.Python core library
and are currently not available.
and are currently not available.
<p>P.S.:</p>
@@ -270,7 +285,7 @@ cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
<blockquote>
<b>Q:</b> <i>I get this error message when compiling a large source
file. What can I do?</i>
file. What can I do?</i>
<p><b>A:</b> You have two choices:</p>
@@ -278,7 +293,7 @@ cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
<li>Upgrade your compiler (preferred)</li>
<li>
Break your source file up into multiple translation units.
Break your source file up into multiple translation units.
<p><code><b>my_module.cpp</b></code>:</p>
<pre>
@@ -292,7 +307,7 @@ BOOST_PYTHON_MODULE(my_module)
more_of_my_module();
}
</pre>
<code><b>more_of_my_module.cpp</b></code>:
<code><b>more_of_my_module.cpp</b></code>:
<pre>
void more_of_my_module()
{
@@ -306,7 +321,7 @@ void more_of_my_module()
can always pass a reference to the <code>class_</code> object to a
function in another source file, and call some of its member
functions (e.g. <code>.def(...)</code>) in the auxilliary source
file:
file:
<p><code><b>more_of_my_class.cpp</b></code>:</p>
<pre>
@@ -337,7 +352,7 @@ void more_of_my_class(class&lt;my_class&gt;&amp; x)
library that is under test, given that python code is minimal and
boost::python either works or it doesn't. (ie. While errors can occur
when the wrapping method is invalid, most errors are caught by the
compiler ;-).
compiler ;-).
<p>The basic steps required to initiate a gdb session to debug a c++
library via python are shown here. Note, however that you should start
@@ -368,20 +383,69 @@ Current language: auto; currently c++
solid and "just works" without requiring any special tricks from the
user.</p>
<p>Unfortunately for Cygwin and MinGW users, as of this writing gdb on
Windows has a very hard time dealing with shared libraries, which could
make Greg's approach next to useless for you. My best advice for you is
to use Metrowerks C++ for compiler conformance and Microsoft Visual
Studio as a debugger when you need one.</p>
<p>Raoul Gough has provided the following for gdb on Windows:</p>
<blockquote>
<p>gdb support for Windows DLLs has improved lately, so it is
now possible to debug Python extensions using a few
tricks. Firstly, you will need an up-to-date gdb with support
for minimal symbol extraction from a DLL. Any gdb from version 6
onwards, or Cygwin gdb-20030214-1 and onwards should do. A
suitable release will have a section in the gdb.info file under
Configuration &ndash; Native &ndash; Cygwin Native &ndash;
Non-debug DLL symbols. Refer to that info section for more
details of the procedures outlined here.</p>
<p>Secondly, it seems necessary to set a breakpoint in the
Python interpreter, rather than using ^C to break execution. A
good place to set this breakpoint is PyOS_Readline, which will
stop execution immediately before reading each interactive
Python command. You have to let Python start once under the
debugger, so that it loads its own DLL, before you can set the
breakpoint:</p>
<p>
<pre>
$ gdb python
GNU gdb 2003-09-02-cvs (cygwin-special)
[...]
(gdb) run
Starting program: /cygdrive/c/Python22/python.exe
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; ^Z
Program exited normally.
(gdb) break *&amp;PyOS_Readline
Breakpoint 1 at 0x1e04eff0
(gdb) run
Starting program: /cygdrive/c/Python22/python.exe
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
from /cygdrive/c/WINNT/system32/python22.dll
(gdb) cont
Continuing.
&gt;&gt;&gt; from my_ext import *
Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
from /cygdrive/c/WINNT/system32/python22.dll
(gdb) # my_ext now loaded (with any debugging symbols it contains)
</pre>
</blockquote>
<h3>Debugging extensions through Boost.Build</h3>
If you are launching your extension module tests with <a href=
"../../../tools/build">Boost.Build</a> using the
"../../../../tools/build/v1/build_system.htm">Boost.Build</a> using the
<code>boost-python-runtest</code> rule, you can ask it to launch your
debugger for you by adding "-sPYTHON_LAUNCH=<i>debugger</i>" to your bjam
command-line:
debugger for you by adding "--debugger=<i>debugger</i>" to your bjam
command-line:
<pre>
bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
bjam -sTOOLS=vc7.1 "--debugger=devenv /debugexe" test
bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
</pre>
It can also be extremely useful to add the <code>-d+2</code> option when
@@ -389,7 +453,7 @@ bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
commands it uses to invoke it. This will invariably involve setting up
PYTHONPATH and other important environment variables such as
LD_LIBRARY_PATH which may be needed by your debugger in order to get
things to work right.
things to work right.
<hr>
<h2><a name="imul"></a>Why doesn't my <code>*=</code> operator work?</h2>
@@ -400,7 +464,7 @@ bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
<i>operator. It always tells me "can't multiply sequence with non int
type". If I use</i> <code>p1.__imul__(p2)</code> <i>instead of</i>
<code>p1 *= p2</code><i>, it successfully executes my code. What's
wrong with me?</i>
wrong with me?</i>
<p><b>A:</b> There's nothing wrong with you. This is a bug in Python
2.2. You can see the same effect in Pure Python (you can learn a lot
@@ -421,24 +485,54 @@ bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
<h2><a name="macosx"></a>Does Boost.Python work with Mac OS X?</h2>
<blockquote>
<p>The short answer: as of January 2003, unfortunately not.</p>
It is known to work under 10.2.8 and 10.3 using
Apple's gcc 3.3 compiler:
<pre>gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1493)</pre>
Under 10.2.8 get the August 2003 gcc update (free at
<a href="http://connect.apple.com/">http://connect.apple.com/</a>).
Under 10.3 get the Xcode Tools v1.0 (also free).
<p>
Python 2.3 is required. The Python that ships with 10.3 is
fine. Under 10.2.8 use these commands to install Python
as a framework:
<pre>./configure --enable-framework
make
make frameworkinstall</pre>
The last command requires root privileges because the target
directory is
<tt>/Library/Frameworks/Python.framework/Versions/2.3</tt>.
However, the installation does not interfere with the Python
version that ships with 10.2.8.
<p>
It is also crucial to increase the <tt>stacksize</tt> before
starting compilations, e.g.:
<pre>limit stacksize 8192k</pre>
If the <tt>stacksize</tt> is too small the build might crash with
internal compiler errors.
<p>
Sometimes Apple's compiler exhibits a bug by printing an error
like the following while compiling a
<tt>boost::python::class_&lt;your_type&gt;</tt>
template instantiation:
<pre>.../inheritance.hpp:44: error: cannot
dynamic_cast `p' (of type `struct cctbx::boost_python::&lt;unnamed&gt;::add_pair*
') to type `void*' (source type is not polymorphic)</pre>
<p>The longer answer: using Mac OS 10.2.3 with the December Developer's
Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles
fine, including the examples. However, there are problems at runtime
(see <a href=
"http://mail.python.org/pipermail/c++-sig/2003-January/003267.html">http://mail.python.org/pipermail/c++-sig/2003-January/003267.html</a>).
Solutions are currently unknown.</p>
We do not know a general workaround, but if the definition of
<tt>your_type</tt> can be modified the following was found
to work in all cases encountered so far:<pre>struct your_type
{
// before defining any member data
#if defined(__MACH__) &amp;&amp; defined(__APPLE_CC__) &amp;&amp; __APPLE_CC__ == 1493
bool dummy_;
#endif
// now your member data, e.g.
double x;
int j;
// etc.
};</pre>
<p>It is known that under certain circumstances objects are
double-destructed. See <a href=
"http://mail.python.org/pipermail/c++-sig/2003-January/003278.html">http://mail.python.org/pipermail/c++-sig/2003-January/003278.html</a>
for details. It is not clear however if this problem is related to the
Boost.Python runtime issues.</p>
</blockquote>
<hr>
<h2><a name="xref">How can I find the existing PyObject that holds a C++
object?</a></h2>
@@ -450,7 +544,7 @@ bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
with virtual functions. If you make a wrapper class with an initial
PyObject* constructor argument and store that PyObject* as "self", you
can get back to it by casting down to that wrapper type in a thin wrapper
function. For example:
function. For example:
<pre>
class X { X(int); virtual ~X(); ... };
X* f(); // known to return Xs that are managed by Python objects
@@ -483,7 +577,7 @@ class_&lt;X,X_wrap&gt;("X", init&lt;int&gt;())
runtime check that it's valid. This approach also only works if the
<code>X</code> object was constructed from Python, because
<code>X</code>s constructed from C++ are of course never
<code>X_wrap</code> objects.
<code>X_wrap</code> objects.
<p>Another approach to this requires you to change your C++ code a bit;
if that's an option for you it might be a better way to go. work we've
@@ -502,11 +596,13 @@ class_&lt;X,X_wrap&gt;("X", init&lt;int&gt;())
its containing Python object, and you could have your f_wrap function
look in that mapping to get the Python object out.</p>
<hr>
<h2><a name="ownership">How can I wrap a function which needs to take
ownership of a raw pointer?</a></h2>
<blockquote>
<i>Part of an API that I'm wrapping goes something like this:</i>
<i>Part of an API that I'm wrapping goes something like this:</i>
<pre>
struct A {}; struct B { void add( A* ); }
where B::add() takes ownership of the pointer passed to it.
@@ -517,9 +613,9 @@ where B::add() takes ownership of the pointer passed to it.
a = mod.A()
b = mod.B()
b.add( a )
del a
del a
del b
# python interpreter crashes
# python interpreter crashes
# later due to memory corruption.
</pre>
@@ -530,13 +626,13 @@ del b
<p><i>--Bruce Lowery</i></p>
</blockquote>
Yes: Make sure the C++ object is held by auto_ptr:
Yes: Make sure the C++ object is held by auto_ptr:
<pre>
class_&lt;A, std::auto_ptr&lt;A&gt; &gt;("A")
...
;
</pre>
Then make a thin wrapper function which takes an auto_ptr parameter:
Then make a thin wrapper function which takes an auto_ptr parameter:
<pre>
void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
{
@@ -547,26 +643,237 @@ void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
Wrap that as B.add. Note that pointers returned via <code><a href=
"manage_new_object.html#manage_new_object-spec">manage_new_object</a></code>
will also be held by <code>auto_ptr</code>, so this transfer-of-ownership
will also work correctly.
will also work correctly.
<hr>
<h2><a name="slow_compilation">Compilation takes too much time and eats too
much memory! What can I do to make it faster?</a></h2>
much memory! What can I do to make it faster?</a></h2>
<p>
Please refer to the <a href="../tutorial/doc/reducing_compiling_time.html">Techniques</a>
section in the tutorial.
Please refer to the <a href="../tutorial/doc/reducing_compiling_time.html"
>Reducing Compiling Time</a> section in the tutorial.
</p>
<h2><a name="packages">How do I create sub-packages using Boost.Python?</a></h2>
<hr>
<h2><a name="packages">How do I create sub-packages using Boost.Python?</a></h2>
<p>
In the <a href="../tutorial/doc/creating_packages.html">Techniques</a>
section of the tutorial this topic is explored.
Please refer to the <a href="../tutorial/doc/creating_packages.html"
>Creating Packages</a> section in the tutorial.
</p>
<hr>
<h2><a name="msvcthrowbug"></a>error C2064: term does
not evaluate to a function taking 2 arguments</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
If you see Microsoft Visual C++ 7.1 (MS Visual Studio .NET 2003) issue
an error message like the following it is most likely due to a bug
in the compiler:
<pre>boost\boost\python\detail\invoke.hpp(76):
error C2064: term does not evaluate to a function taking 2 arguments"</pre>
This message is triggered by code like the following:
<pre>#include &lt;boost/python.hpp&gt;
using namespace boost::python;
class FXThread
{
public:
bool setAutoDelete(bool doso) throw();
};
void Export_FXThread()
{
class_< FXThread >("FXThread")
.def("setAutoDelete", &amp;FXThread::setAutoDelete)
;
}
</pre>
The bug is related to the <code>throw()</code> modifier.
As a workaround cast off the modifier. E.g.:
<pre>
.def("setAutoDelete", (bool (FXThread::*)(bool)) &amp;FXThread::setAutoDelete)</pre>
<p>(The bug has been reported to Microsoft.)</p>
<hr>
<h2><a name="voidptr"></a>How do I handle <tt>void *</tt> conversion?</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
For several reasons Boost.Python does not support <tt>void *</tt> as
an argument or as a return value. However, it is possible to wrap
functions with <tt>void *</tt> arguments or return values using
thin wrappers and the <i>opaque pointer</i> facility. E.g.:
<pre>// Declare the following in each translation unit
struct void_; // Deliberately do not define
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_);
void *foo(int par1, void *par2);
void_ *foo_wrapper(int par1, void_ *par2)
{
return (void_ *) foo(par1, par2);
}
...
BOOST_PYTHON_MODULE(bar)
{
def("foo", &amp;foo_wrapper);
}</pre>
<hr>
<h2><a name="custom_string"></a>How can I automatically
convert my custom string type to and from a Python string?</h2>
<font size="-1"><i>Ralf W. Grosse-Kunstleve provides these
notes:</i></font><p>
Below is a small, self-contained demo extension module that shows
how to do this. Here is the corresponding trivial test:
<pre>import custom_string
assert custom_string.hello() == "Hello world."
assert custom_string.size("california") == 10</pre>
If you look at the code you will find:
<ul>
<li>A custom <tt>to_python</tt> converter (easy):
<tt>custom_string_to_python_str</tt>
<li>A custom lvalue converter (needs more code):
<tt>custom_string_from_python_str</tt>
</ul>
The custom converters are registered in the global Boost.Python
registry near the top of the module initialization function. Once
flow control has passed through the registration code the automatic
conversions from and to Python strings will work in any module
imported in the same process.
<pre>#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/to_python_converter.hpp&gt;
namespace sandbox { namespace {
class custom_string
{
public:
custom_string() {}
custom_string(std::string const&amp; value) : value_(value) {}
std::string const&amp; value() const { return value_; }
private:
std::string value_;
};
struct custom_string_to_python_str
{
static PyObject* convert(custom_string const&amp; s)
{
return boost::python::incref(boost::python::object(s.value()).ptr());
}
};
struct custom_string_from_python_str
{
custom_string_from_python_str()
{
boost::python::converter::registry::push_back(
&amp;convertible,
&amp;construct,
boost::python::type_id&lt;custom_string&gt;());
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyString_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
const char* value = PyString_AsString(obj_ptr);
if (value == 0) boost::python::throw_error_already_set();
void* storage = (
(boost::python::converter::rvalue_from_python_storage&lt;custom_string&gt;*)
data)-&gt;storage.bytes;
new (storage) custom_string(value);
data-&gt;convertible = storage;
}
};
custom_string hello() { return custom_string(&quot;Hello world.&quot;); }
std::size_t size(custom_string const&amp; s) { return s.value().size(); }
void init_module()
{
using namespace boost::python;
boost::python::to_python_converter&lt;
custom_string,
custom_string_to_python_str&gt;();
custom_string_from_python_str();
def(&quot;hello&quot;, hello);
def(&quot;size&quot;, size);
}
}} // namespace sandbox::&lt;anonymous&gt;
BOOST_PYTHON_MODULE(custom_string)
{
sandbox::init_module();
}</pre>
<hr>
<h2><a name="topythonconversionfailed"></a
>Why is my automatic to-python conversion not being found?</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
If you define custom converters similar to the ones
shown above the <tt>def_readonly()</tt> and <tt>def_readwrite()</tt>
member functions provided by <tt>boost::python::class_</tt> for
direct access to your member data will not work as expected.
This is because <tt>def_readonly("bar",&nbsp;&amp;foo::bar)</tt> is
equivalent to:
<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()))</pre>
Similarly, <tt>def_readwrite("bar",&nbsp;&amp;foo::bar)</tt> is
equivalent to:
<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()),
make_setter(&amp;foo::bar, return_internal_reference())</pre>
In order to define return value policies compatible with the
custom conversions replace <tt>def_readonly()</tt> and
<tt>def_readwrite()</tt> by <tt>add_property()</tt>. E.g.:
<pre>.add_property("bar", make_getter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()),
make_setter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()))</pre>
<hr>
<h2><a name="threadsupport"></a
>Is Boost.Python thread-aware/compatible with multiple interpreters?</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
The quick answer to this is: no.</p>
<p>
The longer answer is that it can be patched to be so, but it's
complex. You will need to add custom lock/unlock wrapping of every
time your code enters Boost.Python (particularly every virtual
function override) plus heavily modify
<tt>boost/python/detail/invoke.hpp</tt> with custom unlock/lock
wrapping of every time Boost.Python enters your code. You must
furthermore take care to <i>not</i> unlock/lock when Boost.Python
is invoking iterator changes via <tt>invoke.hpp</tt>.</p>
<p>
There is a patched <tt>invoke.hpp</tt> posted on the C++-SIG
mailing list archives and you can find a real implementation of all
the machinery necessary to fully implement this in the TnFOX
project at <a href="http://sourceforge.net/projects/tnfox/"> this
SourceForge project location</a>.</p>
<hr>
<p>Revised
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
18 March, 2003
28 January, 2004
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
@@ -575,4 +882,3 @@ void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
Rights Reserved.</i></p>
</body>
</html>

View File

@@ -71,9 +71,8 @@ namespace boost { namespace python
{
template &lt;class T&gt;
struct from_python : private <a href=
"../../../utility/utility.htm#Class noncopyable">boost::noncopyable</a> // Exposition only.
// from_python&lt;T&gt; meets the <a href=
"NonCopyable.html">NonCopyable</a> requirements
"../../../utility/utility.htm#Class_noncopyable">boost::noncopyable</a> // Exposition only.
// from_python&lt;T&gt; meets the NonCopyable requirements
{
from_python(PyObject*);
bool convertible() const;

View File

@@ -278,7 +278,7 @@
std::vector interface]) classes (currently, this is the only predefined
suite available). It provides all the policies required by the
<tt>indexing_suite</tt>.
</p>
</p>
<p>
Example usage:
</p>
@@ -300,16 +300,16 @@
<h2>
<a name="indexing_suite_class"></a>indexing_suite class
</h2>
<h3>
Class template<br>
<tt>indexing_suite&lt;<br>
class <font color="#007F00">Container</font><br>
, class <font color="#007F00">DerivedPolicies<br></font></tt> <tt>,
bool <font color="#007F00">NoProxy</font><br>
, bool <font color="#007F00">NoProxy</font>,<br>
, class <font color="#007F00">Element</font><br>
, class <font color="#007F00">Key</font><br>
, class <font color="#007F00">Index</font></tt>
<h3>
<br>
<tt>indexing_suite&lt;<br>
class Container<br>
, class DerivedPolicies<font color="#007F00"><br>
</font></tt> <tt>,
bool NoProxy<br>
, class Element<br>
, class Key<br>
, class Index</tt>
</h3>
<table width="100%" border="1">
<tr>

View File

@@ -97,7 +97,7 @@
<pre>
namespace boost { namespace python
{
class instance_holder : <a href="../../../utility/utility.htm#Class noncopyable">noncopyable</a>
class instance_holder : <a href="../../../utility/utility.htm#Class_noncopyable">noncopyable</a>
{
public:
// destructor

View File

@@ -66,9 +66,13 @@ template &lt;class F, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies)
template &lt;class F, class Policies, class Keywords&gt;
template &lt;class F, class Policies, class KeywordsOrSignature&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; keywords)
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, KeywordsOrSignature const&amp; ks)
template &lt;class F, class Policies, class Keywords, class Signature&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; kw, Signature const&amp; sig)
</pre>
<dl class="function-semantics">
@@ -82,19 +86,41 @@ template &lt;class F, class Policies, class Keywords&gt;
<dt><b>Effects:</b> Creates a Python callable object which, when called
from Python, converts its arguments to C++ and calls <code>f</code>. If
<code>F</code> is a pointer-to-member-function type, the target object
of the function call (<code>*this</code>) will be taken from the first
Python argument, and subsequent Python arguments will be used as the
arguments to <code>f</code>. If <code>policies</code> are supplied, it
<code>F</code> is a pointer-to-member-function type, the target
object of the function call (<code>*this</code>) will be taken
from the first Python argument, and subsequent Python arguments
will be used as the arguments
to <code>f</code>. <ul>
<li> If <code>policies</code> are supplied, it
will be applied to the function as described <a href=
"CallPolicies.html">here</a>. If <code>keywords</code> are
"CallPolicies.html">here</a>.
<li>If <code>keywords</code> are
supplied, the keywords will be applied in order to the final
arguments of the resulting function.</dt>
arguments of the resulting function.
<li>If <code>Signature</code>
is supplied, it should be an instance of an <a
href="../../../mpl/doc/ref/Sequence.html">MPL front-extensible
sequence</a> representing the function's return type followed by
its argument types. Pass a <code>Signature</code> when wrapping
function object types whose signatures can't be deduced, or when
you wish to override the types which will be passed to the
wrapped function.
</ul></dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
<dt><b>Caveats:</b> An argument of pointer type may
be <code>0</code> if <code>None</code> is passed from Python.
An argument type which is a constant reference may refer to a
temporary which was created from the Python object for just the
duration of the call to the wrapped function, for example
a <code>std::vector</code> conjured up by the conversion process
from a Python list. Use a non-<code>const</code> reference
argument when a persistent lvalue is required.
</dl>
<pre>
<a name=
"make_constructor-spec"></a>template &lt;class T, class ArgList, class Generator&gt;
@@ -109,7 +135,7 @@ template &lt;class ArgList, class Generator, class Policies&gt;
<dt><b>Requires:</b> <code>T</code> is a class type.
<code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>. <code>ArgList</code> is an <a
href="../../../mpl/doc/Sequences.html">MPL sequence</a> of C++ argument
href="../../../mpl/doc/ref/Sequences.html">MPL sequence</a> of C++ argument
types (<i>A1,&nbsp;A2,...&nbsp;AN</i>) such that if
<code>a1,&nbsp;a2</code>...&nbsp;<code>aN</code> are objects of type
<i>A1,&nbsp;A2,...&nbsp;AN</i> respectively, the expression <code>new

View File

@@ -208,16 +208,19 @@
<p><a name="slice_nil-spec"></a></p>
<pre>
enum slice_nil { _ };
class slice_nil;
static const _ = slice_nil();
</pre>
A type that can be used to get the effect of leaving out an index in a
Python slice expression:
<pre>
&gt;&gt;&gt; x[:-1]
&gt;&gt;&gt; x[::-1]
</pre>
C++ equivalent:
<pre>
x.slice(_,-1)
x[slice(_,_,-1)]
</pre>
<h2><a name="classes"></a>Classes</h2>

View File

@@ -196,6 +196,8 @@ namespace boost { namespace python { namespace self_ns {
"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator+(self_t);
<a href=
"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator~(self_t);
<a href=
"#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator!(self_t);
// value operations
<a href=
@@ -349,123 +351,123 @@ namespace boost { namespace python { namespace self_ns {
</tr>
<tr>
<td>self&nbsp;==&nbsp;r</td>
<td><code>self&nbsp;==&nbsp;r</code></td>
<td>__eq__</td>
<td><code>__eq__</code></td>
<td>x&nbsp;==&nbsp;y</td>
<td><code>x&nbsp;==&nbsp;y</code></td>
<td>x&nbsp;==&nbsp;y, y&nbsp;==&nbsp;x</td>
<td><code>x&nbsp;==&nbsp;y, y&nbsp;==&nbsp;x</code></td>
</tr>
<tr>
<td>l&nbsp;==&nbsp;self</td>
<td><code>l&nbsp;==&nbsp;self</code></td>
<td>__eq__</td>
<td><code>__eq__</code></td>
<td>y&nbsp;==&nbsp;x</td>
<td><code>y&nbsp;==&nbsp;x</code></td>
<td>y&nbsp;==&nbsp;x, x&nbsp;==&nbsp;y</td>
<td><code>y&nbsp;==&nbsp;x, x&nbsp;==&nbsp;y</code></td>
</tr>
<tr>
<td>self&nbsp;!=&nbsp;r</td>
<td><code>self&nbsp;!=&nbsp;r</code></td>
<td>__ne__</td>
<td><code>__ne__</code></td>
<td>x&nbsp;!=&nbsp;y</td>
<td><code>x&nbsp;!=&nbsp;y</code></td>
<td>x&nbsp;!=&nbsp;y, y&nbsp;!=&nbsp;x</td>
<td><code>x&nbsp;!=&nbsp;y, y&nbsp;!=&nbsp;x</code></td>
</tr>
<tr>
<td>l&nbsp;!=&nbsp;self</td>
<td><code>l&nbsp;!=&nbsp;self</code></td>
<td>__ne__</td>
<td><code>__ne__</code></td>
<td>y&nbsp;!=&nbsp;x</td>
<td><code>y&nbsp;!=&nbsp;x</code></td>
<td>y&nbsp;!=&nbsp;x, x&nbsp;!=&nbsp;y</td>
<td><code>y&nbsp;!=&nbsp;x, x&nbsp;!=&nbsp;y</code></td>
</tr>
<tr>
<td>self&nbsp;&lt;&nbsp;r</td>
<td><code>self&nbsp;&lt;&nbsp;r</code></td>
<td>__lt__</td>
<td><code>__lt__</code></td>
<td>x&nbsp;&lt;&nbsp;y</td>
<td><code>x&nbsp;&lt;&nbsp;y</code></td>
<td>x&nbsp;&lt;&nbsp;y, y&nbsp;&gt;&nbsp;x</td>
<td><code>x&nbsp;&lt;&nbsp;y, y&nbsp;&gt;&nbsp;x</code></td>
</tr>
<tr>
<td>l&nbsp;&lt;&nbsp;self</td>
<td><code>l&nbsp;&lt;&nbsp;self</code></td>
<td>__gt__</td>
<td><code>__gt__</code></td>
<td>y&nbsp;&lt;&nbsp;x</td>
<td><code>y&nbsp;&lt;&nbsp;x</code></td>
<td>y&nbsp;&gt;&nbsp;x, x&nbsp;&lt;&nbsp;y</td>
<td><code>y&nbsp;&gt;&nbsp;x, x&nbsp;&lt;&nbsp;y</code></td>
</tr>
<tr>
<td>self&nbsp;&gt;&nbsp;r</td>
<td><code>self&nbsp;&gt;&nbsp;r</code></td>
<td>__gt__</td>
<td><code>__gt__</code></td>
<td>x&nbsp;&gt;&nbsp;y</td>
<td><code>x&nbsp;&gt;&nbsp;y</code></td>
<td>x&nbsp;&gt;&nbsp;y, y&nbsp;&lt;&nbsp;x</td>
<td><code>x&nbsp;&gt;&nbsp;y, y&nbsp;&lt;&nbsp;x</code></td>
</tr>
<tr>
<td>l&nbsp;&gt;&nbsp;self</td>
<td><code>l&nbsp;&gt;&nbsp;self</code></td>
<td>__lt__</td>
<td><code>__lt__</code></td>
<td>y&nbsp;&gt;&nbsp;x</td>
<td><code>y&nbsp;&gt;&nbsp;x</code></td>
<td>y&nbsp;&lt;&nbsp;x, x&nbsp;&gt;&nbsp;y</td>
<td><code>y&nbsp;&lt;&nbsp;x, x&nbsp;&gt;&nbsp;y</code></td>
</tr>
<tr>
<td>self&nbsp;&lt;=&nbsp;r</td>
<td><code>self&nbsp;&lt;=&nbsp;r</code></td>
<td>__le__</td>
<td><code>__le__</code></td>
<td>x&nbsp;&lt;=&nbsp;y</td>
<td><code>x&nbsp;&lt;=&nbsp;y</code></td>
<td>x&nbsp;&lt;=&nbsp;y, y&nbsp;&gt;=&nbsp;x</td>
<td><code>x&nbsp;&lt;=&nbsp;y, y&nbsp;&gt;=&nbsp;x</code></td>
</tr>
<tr>
<td>l&nbsp;&lt;=&nbsp;self</td>
<td><code>l&nbsp;&lt;=&nbsp;self</code></td>
<td>__ge__</td>
<td><code>__ge__</code></td>
<td>y&nbsp;&lt;=&nbsp;x</td>
<td><code>y&nbsp;&lt;=&nbsp;x</code></td>
<td>y&nbsp;&gt;=&nbsp;x, x&nbsp;&lt;=&nbsp;y</td>
<td><code>y&nbsp;&gt;=&nbsp;x, x&nbsp;&lt;=&nbsp;y</code></td>
</tr>
<tr>
<td>self&nbsp;&gt;=&nbsp;r</td>
<td><code>self&nbsp;&gt;=&nbsp;r</code></td>
<td>__ge__</td>
<td><code>__ge__</code></td>
<td>x&nbsp;&gt;=&nbsp;y</td>
<td><code>x&nbsp;&gt;=&nbsp;y</code></td>
<td>x&nbsp;&gt;=&nbsp;y, y&nbsp;&lt;=&nbsp;x</td>
<td><code>x&nbsp;&gt;=&nbsp;y, y&nbsp;&lt;=&nbsp;x</code></td>
</tr>
<tr>
<td>l&nbsp;&gt;=&nbsp;self</td>
<td><code>l&nbsp;&gt;=&nbsp;self</code></td>
<td>__le__</td>
<td><code>__le__</code></td>
<td>y&nbsp;&gt;=&nbsp;x</td>
<td><code>y&nbsp;&gt;=&nbsp;x</code></td>
<td>y&nbsp;&lt;=&nbsp;x, x&nbsp;&gt;=&nbsp;y</td>
<td><code>y&nbsp;&lt;=&nbsp;x, x&nbsp;&gt;=&nbsp;y</code></td>
</tr>
</table>
@@ -487,183 +489,183 @@ namespace boost { namespace python { namespace self_ns {
</tr>
<tr>
<td>self&nbsp;+&nbsp;r</td>
<td><code>self&nbsp;+&nbsp;r</code></td>
<td>__add__</td>
<td><code>__add__</code></td>
<td>x&nbsp;+&nbsp;y</td>
<td><code>x&nbsp;+&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;+&nbsp;self</td>
<td><code>l&nbsp;+&nbsp;self</code></td>
<td>__radd__</td>
<td><code>__radd__</code></td>
<td>y&nbsp;+&nbsp;x</td>
<td><code>y&nbsp;+&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;-&nbsp;r</td>
<td><code>self&nbsp;-&nbsp;r</code></td>
<td>__sub__</td>
<td><code>__sub__</code></td>
<td>x&nbsp;-&nbsp;y</td>
<td><code>x&nbsp;-&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;-&nbsp;self</td>
<td><code>l&nbsp;-&nbsp;self</code></td>
<td>__rsub__</td>
<td><code>__rsub__</code></td>
<td>y&nbsp;-&nbsp;x</td>
<td><code>y&nbsp;-&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;*&nbsp;r</td>
<td><code>self&nbsp;*&nbsp;r</code></td>
<td>__mul__</td>
<td><code>__mul__</code></td>
<td>x&nbsp;*&nbsp;y</td>
<td><code>x&nbsp;*&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;*&nbsp;self</td>
<td><code>l&nbsp;*&nbsp;self</code></td>
<td>__rmul__</td>
<td><code>__rmul__</code></td>
<td>y&nbsp;*&nbsp;x</td>
<td><code>y&nbsp;*&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;/&nbsp;r</td>
<td><code>self&nbsp;/&nbsp;r</code></td>
<td>__div__</td>
<td><code>__div__</code></td>
<td>x&nbsp;/&nbsp;y</td>
<td><code>x&nbsp;/&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;/&nbsp;self</td>
<td><code>l&nbsp;/&nbsp;self</code></td>
<td>__rdiv__</td>
<td><code>__rdiv__</code></td>
<td>y&nbsp;/&nbsp;x</td>
<td><code>y&nbsp;/&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;%&nbsp;r</td>
<td><code>self&nbsp;%&nbsp;r</code></td>
<td>__mod__</td>
<td><code>__mod__</code></td>
<td>x&nbsp;%&nbsp;y</td>
<td><code>x&nbsp;%&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;%&nbsp;self</td>
<td><code>l&nbsp;%&nbsp;self</code></td>
<td>__rmod__</td>
<td><code>__rmod__</code></td>
<td>y&nbsp;%&nbsp;x</td>
<td><code>y&nbsp;%&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;&gt;&gt;&nbsp;r</td>
<td><code>self&nbsp;&gt;&gt;&nbsp;r</code></td>
<td>__rshift__</td>
<td><code>__rshift__</code></td>
<td>x&nbsp;&gt;&gt;&nbsp;y</td>
<td><code>x&nbsp;&gt;&gt;&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;&gt;&gt;&nbsp;self</td>
<td><code>l&nbsp;&gt;&gt;&nbsp;self</code></td>
<td>__rrshift__</td>
<td><code>__rrshift__</code></td>
<td>y&nbsp;&gt;&gt;&nbsp;x</td>
<td><code>y&nbsp;&gt;&gt;&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;&lt;&lt;&nbsp;r</td>
<td><code>self&nbsp;&lt;&lt;&nbsp;r</code></td>
<td>__lshift__</td>
<td><code>__lshift__</code></td>
<td>x&nbsp;&lt;&lt;&nbsp;y</td>
<td><code>x&nbsp;&lt;&lt;&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;&lt;&lt;&nbsp;self</td>
<td><code>l&nbsp;&lt;&lt;&nbsp;self</code></td>
<td>__rlshift__</td>
<td><code>__rlshift__</code></td>
<td>y&nbsp;&lt;&lt;&nbsp;x</td>
<td><code>y&nbsp;&lt;&lt;&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;&amp;&nbsp;r</td>
<td><code>self&nbsp;&amp;&nbsp;r</code></td>
<td>__and__</td>
<td><code>__and__</code></td>
<td>x&nbsp;&amp;&nbsp;y</td>
<td><code>x&nbsp;&amp;&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;&amp;&nbsp;self</td>
<td><code>l&nbsp;&amp;&nbsp;self</code></td>
<td>__rand__</td>
<td><code>__rand__</code></td>
<td>y&nbsp;&amp;&nbsp;x</td>
<td><code>y&nbsp;&amp;&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;^&nbsp;r</td>
<td><code>self&nbsp;^&nbsp;r</code></td>
<td>__xor__</td>
<td><code>__xor__</code></td>
<td>x&nbsp;^&nbsp;y</td>
<td><code>x&nbsp;^&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;^&nbsp;self</td>
<td><code>l&nbsp;^&nbsp;self</code></td>
<td>__rxor__</td>
<td><code>__rxor__</code></td>
<td>y&nbsp;^&nbsp;x</td>
<td><code>y&nbsp;^&nbsp;x</code></td>
</tr>
<tr>
<td>self&nbsp;|&nbsp;r</td>
<td><code>self&nbsp;|&nbsp;r</code></td>
<td>__or__</td>
<td><code>__or__</code></td>
<td>x&nbsp;|&nbsp;y</td>
<td><code>x&nbsp;|&nbsp;y</code></td>
</tr>
<tr>
<td>l&nbsp;|&nbsp;self</td>
<td><code>l&nbsp;|&nbsp;self</code></td>
<td>__ror__</td>
<td><code>__ror__</code></td>
<td>y&nbsp;|&nbsp;x</td>
<td><code>y&nbsp;|&nbsp;x</code></td>
</tr>
<tr>
<td>pow(self,&nbsp;r)</td>
<td><code>pow(self,&nbsp;r)</code></td>
<td>__pow__</td>
<td><code>__pow__</code></td>
<td>pow(x,&nbsp;y)</td>
<td><code>pow(x,&nbsp;y)</code></td>
</tr>
<tr>
<td>pow(l,&nbsp;self)</td>
<td><code>pow(l,&nbsp;self)</code></td>
<td>__rpow__</td>
<td><code>__rpow__</code></td>
<td>pow(y,&nbsp;x)</td>
<td><code>pow(y,&nbsp;x)</code></td>
</tr>
</table>
<h4><a name="self_t-spec-unary-ops"></a>Class <code>self_t</code> unary
<h4><a name="self_t-spec-value-unary-ops"></a>Class <code>self_t</code> unary
operations</h4>
<table border="1" summary="self_t unary operations">
@@ -676,27 +678,35 @@ namespace boost { namespace python { namespace self_ns {
</tr>
<tr>
<td>-self</td>
<td><code>-self</code></td>
<td>__neg__</td>
<td><code>__neg__</code></td>
<td>-x</td>
<td><code>-x</code></td>
</tr>
<tr>
<td>+self</td>
<td><code>+self</code></td>
<td>__pos__</td>
<td><code>__pos__</code></td>
<td>+x</td>
<td><code>+x</code></td>
</tr>
<tr>
<td>~self</td>
<td><code>~self</code></td>
<td>__invert__</td>
<td><code>__invert__</code></td>
<td>~x</td>
<td><code>~x</code></td>
</tr>
<tr>
<td><code>not self</code><br><i>or</i><br><code>!self</code></td>
<td><code>__nonzero__</code></td>
<td><code>!!x</code></td>
</tr>
</table>
@@ -713,44 +723,44 @@ namespace boost { namespace python { namespace self_ns {
</tr>
<tr>
<td>int_(self)</td>
<td><code>int_(self)</code></td>
<td>__int__</td>
<td><code>__int__</code></td>
<td>long(x)</td>
<td><code>long(x)</code></td>
</tr>
<tr>
<td>long_</td>
<td><code>long_</code></td>
<td>__long__</td>
<td><code>__long__</code></td>
<td>PyLong_FromLong(x)</td>
<td><code>PyLong_FromLong(x)</code></td>
</tr>
<tr>
<td>float_</td>
<td><code>float_</code></td>
<td>__float__</td>
<td><code>__float__</code></td>
<td>double(x)</td>
<td><code>double(x)</code></td>
</tr>
<tr>
<td>complex_</td>
<td><code>complex_</code></td>
<td>__complex__</td>
<td><code>__complex__</code></td>
<td>std::complex&lt;double&gt;(x)</td>
<td><code>std::complex&lt;double&gt;(x)</code></td>
</tr>
<tr>
<td>str</td>
<td><code>str</code></td>
<td>__str__</td>
<td><code>__str__</code></td>
<td><a href=
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</td>
<td><code><a href=
"../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)</code></td>
</tr>
</table>
@@ -876,7 +886,7 @@ BOOST_PYTHON_MODULE(demo)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
13 November, 2002
3 October, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

View File

@@ -281,13 +281,51 @@ is not empty.
</ul>
<hr>
<h2>Light-weight alternative: pickle support implemented in Python</h2>
&copy; Copyright Ralf W. Grosse-Kunstleve 20012-2002. Permission to copy,
<h3><a href="../../test/pickle4.cpp"><tt>pickle4.cpp</tt></a></h3>
The <tt>pickle4.cpp</tt> example demonstrates an alternative technique
for implementing pickle support. First we direct Boost.Python via
the <tt>class_::enable_pickling()</tt> member function to define only
the basic attributes required for pickling:
<pre>
class_&lt;world&gt;("world", args&lt;const std::string&amp;&gt;())
// ...
.enable_pickling()
// ...
</pre>
This enables the standard Python pickle interface as described
in the Python documentation. By &quot;injecting&quot; a
<tt>__getinitargs__</tt> method into the definition of the wrapped
class we make all instances pickleable:
<pre>
# import the wrapped world class
from pickle4_ext import world
# definition of __getinitargs__
def world_getinitargs(self):
return (self.get_country(),)
# now inject __getinitargs__ (Python is a dynamic language!)
world.__getinitargs__ = world_getinitargs
</pre>
See also the
<a href="../tutorial/doc/extending_wrapped_objects_in_python.html"
>tutorial section</a> on injecting additional methods from Python.
<hr>
&copy; Copyright Ralf W. Grosse-Kunstleve 2001-2004. Permission to copy,
use, modify, sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided "as
is" without express or implied warranty, and with no claim as to its
suitability for any purpose.
<p>
Updated: Aug 2002.
Updated: Feb 2004.
</div>

View File

@@ -27,8 +27,15 @@
</tr>
</table>
<hr>
<b>Boost.Python</b> has been successfully tested on the following
platforms and compilers:
Please see
our <a
href="http://boost.sourceforge.net/regression-logs">regression
logs</a> for up-to-date information. Note that logs not marked
otherwise reflect the CVS state, not the condition of the release.
<p>
Earlier versions of <b>Boost.Python</b> have been successfully
tested on the following platforms and compilers.
<dl class="page-index">
<dt>Unix Platforms:</dt>

View File

@@ -96,193 +96,158 @@
<h2><a name="high_level">High Level Components</a></h2>
<dl>
<dt><a href="class.html">class.hpp/class_fwd.hpp</a></dt>
<dd>
<dl>
<dt><a href="class.html">class.hpp/class_fwd.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="class.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="class.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="class.html#class_-spec">class_</a></dt>
<dt><a href="class.html#bases-spec">bases</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="def.html">def.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="def.html#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="def.html#def-spec">def</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="enum.html">enum.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="enum.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="enum.html#enum_-spec">enum_</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="errors.html">errors.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="errors.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"errors.html#error_already_set-spec">error_already_set</a></dt>
</dl>
</dd>
<dt><a href="errors.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href=
"errors.html#handle_exception-spec">handle_exception</a></dt>
<dt><a href=
"errors.html#expect_non_null-spec">expect_non_null</a></dt>
<dt><a href=
"errors.html#throw_error_already_set-spec">throw_error_already_set</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href=
"exception_translator.html">exception_translator.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"exception_translator.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href=
"exception_translator.html#register_exception_translator-spec">register_exception_translator</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="init.html">init.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="init.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="init.html#init-spec">init</a></dt>
<dt><a href="init.html#optional-spec">optional</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="iterator.html">iterator.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="iterator.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="iterator.html#iterator-spec">iterator</a></dt>
<dt><a href="iterator.html#iterators-spec">iterators</a></dt>
</dl>
</dd>
<dt><a href="iterator.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href="iterator.html#range-spec">range</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="module.html">module.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="module.html#macros">Macros</a></dt>
<dd>
<dl class="index">
<dt><a href=
"module.html#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="operators.html">operators.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="operators.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="operators.html#self_t-spec">self_t</a></dt>
<dt><a href="operators.html#other-spec">other</a></dt>
<dt><a href="operators.html#operator_-spec">operator_</a></dt>
</dl>
</dd>
<dt><a href="operators.html#objects">Objects</a></dt>
<dd>
<dl class="index">
<dt><a href="operators.html#self-spec">self</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="scope.html">scope.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="scope.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="scope.html#scope-spec">scope</a></dt>
</dl>
</dd>
<dt><a href="class.html#class_-spec">class_</a></dt>
<dt><a href="class.html#bases-spec">bases</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="def.html">def.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="def.html#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="def.html#def-spec">def</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="def_visitor.html">def_visitor.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="def_visitor.html#classes">Classes</a></dt>
</dl>
</dd>
<dt><a href="enum.html">enum.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="enum.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="enum.html#enum_-spec">enum_</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="errors.html">errors.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="errors.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"errors.html#error_already_set-spec">error_already_set</a></dt>
</dl>
</dd>
<dt><a href="errors.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href=
"errors.html#handle_exception-spec">handle_exception</a></dt>
<dt><a href=
"errors.html#expect_non_null-spec">expect_non_null</a></dt>
<dt><a href=
"errors.html#throw_error_already_set-spec">throw_error_already_set</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href=
"exception_translator.html">exception_translator.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"exception_translator.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href=
"exception_translator.html#register_exception_translator-spec">register_exception_translator</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="init.html">init.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="init.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="init.html#init-spec">init</a></dt>
<dt><a href="init.html#optional-spec">optional</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="iterator.html">iterator.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="iterator.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="iterator.html#iterator-spec">iterator</a></dt>
<dt><a href="iterator.html#iterators-spec">iterators</a></dt>
</dl>
</dd>
<dt><a href="iterator.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href="iterator.html#range-spec">range</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="module.html">module.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="module.html#macros">Macros</a></dt>
<dd>
<dl class="index">
<dt><a href=
"module.html#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="operators.html">operators.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="operators.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="operators.html#self_t-spec">self_t</a></dt>
<dt><a href="operators.html#other-spec">other</a></dt>
<dt><a href="operators.html#operator_-spec">operator_</a></dt>
</dl>
</dd>
<dt><a href="operators.html#objects">Objects</a></dt>
<dd>
<dl class="index">
<dt><a href="operators.html#self-spec">self</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="scope.html">scope.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="scope.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="scope.html#scope-spec">scope</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<h2><a name="object_wrappers">Object Wrappers</a></h2>
@@ -371,7 +336,7 @@
</dl>
</dd>
<dt><a href="str.html">tuple.hpp</a></dt>
<dt><a href="tuple.html">tuple.hpp</a></dt>
<dd>
<dl class="index">
@@ -392,6 +357,19 @@
</dd>
</dl>
</dd>
<dt><a href="slice.html">slice.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="slice.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href="slice.html#slice-spec">slice</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<h2><a name="invocation">Function Invocation and Creation</a></h2>

View File

@@ -58,10 +58,9 @@
void register_ptr_to_python()
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>P</code> is the type of the smart pointer,
for example <code>smart_ptr&lt;X&gt;</code>.
<dt><b>Requires:</b> <code>P</code> is <a href="Dereferenceable.html#Dereferenceable-concept">Dereferenceable</a>.
</dt>
<dt><b>Effects:</b> Allows conversions to-python of <code>smart_ptr&lt;X&gt;</code>
<dt><b>Effects:</b> Allows conversions to-python of <code>P</code>
instances.
</dt>
</dl>

View File

@@ -86,7 +86,7 @@
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a></td>
<td>A model of <a href=
"ResultConverterGenerator.html">ResultConverterGenerator</a>.</td>
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>.</td>
</tr>
<tr>

241
doc/v2/slice.html Normal file
View File

@@ -0,0 +1,241 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator"
content="HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/slice.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tbody>
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/slice.hpp&gt;</h2>
</td>
</tr>
</tbody>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#slice-spec">Class <code>slice</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#slice-spec-synopsis">Class <code>slice</code>
synopsis</a></dt>
<dt><a href="#slice-spec-ctors">Class <code>slice</code>
constructors</a></dt>
<dt><a href="#slice-spec-observers">Class <code>slice</code>
observer functions</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>Exposes a <a href="ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a>
for the Python <a
href="http://www.python.org/doc/2.3.3/api/slice-objects.html">slice</a>
type.</p>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class-spec"></a>Class <code>slice</code></h3>
<p>Exposes the extended slicing protocol by wrapping the built-in slice
type. The semantics of the constructors and member functions defined
below can be fully understood by reading the <a
href="ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
definition. Since <code>slice</code> is publicly derived from <code><a
href="object.html#object-spec">object</a></code>, the public object
interface applies to <code>slice</code> instances as well.<br>
</p>
<h4><a name="slice-spec-synopsis"></a>Class <code>slice</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
class slice : public object
{
public:
slice(); // create an empty slice, equivalent to [::]
template &lt;typename Int1, typename Int2&gt;
slice(Int1 start, Int2 stop);
template &lt;typename Int1, typename Int2, typename Int3&gt;
slice(Int1 start, Int2 stop, Int3 step);
// Access the parameters this slice was created with.
object start();
object stop();
object step();
// The return type of slice::get_indicies()
template &lt;typename RandomAccessIterator&gt;
struct range
{
RandomAccessIterator start;
RandomAccessIterator stop;
int step;
};
template &lt;typename RandomAccessIterator&gt;
range&lt;RandomAccessIterator&gt;
get_indicies(
RandomAccessIterator const&amp; begin,
RandomAccessIterator const&amp; end);
};
}}
</pre>
<h4><a name="slice-spec-ctors"></a>Class <code>slice</code>
constructors<br>
</h4>
<pre>slice();<br></pre>
<dl class="function-semantics">
<dt><b>Effects:</b> constructs a <code>slice</code> with default stop, start, and
step values.&nbsp; Equivalent to the slice object created by the Python
expression <code>base[::].</code></dt>
<dt><b>Throws:</b> nothing.</dt>
</dl>
<pre>
template &lt;typename Int1, typename Int2&gt;
slice(Int1 start, Int2 stop);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code>
are of type <code>slice_nil</code> or convertible to type <code>object</code>.</dt>
<dt><b>Effects:</b> constructs a new slice with default step value
and the provided start and stop values.&nbsp; Equivalent to the slice
object
created by the built-in Python function <code><a
href="http://www.python.org/doc/current/lib/built-in-funcs.html#12h-62">slice(start,stop)</a></code>,
or the Python expression <code>base[start:stop]</code>.</dt>
<dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
exception if no conversion is possible from the arguments to type <code>object</code>.</dt>
</dl>
<pre>
template &lt;typename Int1, typename Int2, typename Int3&gt;
slice(Int1 start, Int2 stop, Int3 step);
</pre>
<dt><b>Requires:</b> <code>start</code>, <code>stop</code>, and <code>step</code> are integers, <code>slice_nil</code>, or convertible to type <code>object</code>.</dt>
<dt><b>Effects:</b> constructs a new slice with start stop and step
values.&nbsp; Equivalent to the slice object created
by the built-in Python function <code><a
href="http://www.python.org/doc/current/lib/built-in-functions.html#12h-62">slice(start,stop,step)</a></code>,
or the Python expression <code>base[start:stop:step]</code>.</dt>
<dt><b>Throws:</b> <code>error_already_set</code> and sets a Python <code>TypeError</code>
exception if no conversion is possible from the arguments to type
object.</dt>
<h4><a name="slice-spec-observers"></a>Class <code>slice</code>
observer functions<br>
</h4>
<pre>
object slice::start();
object slice::stop();
object slice::step();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> None.</dt>
<dt><b>Throws:</b> nothing.</dt>
<dt><b>Returns:</b>the parameter that
the slice was created with.&nbsp;If the parameter was omitted or
slice_nil was used when the slice was created, than that parameter will
be a reference to PyNone and compare equal to a default-constructed
object.&nbsp;In principal, any object may be used when creating a
slice object, but in practice they are usually integers.</dt>
</dl>
<br>
<pre>
template &lt;typename RandomAccessIterator&gt;
slice::range&lt;RandomAccessIterator&gt;
slice::get_indicies(
RandomAccessIterator const&amp; begin, RandomAccessIterator const&amp; end);
</pre>
<dl class="function-semantics">
<dt><b>Arguments:</b> A pair of STL-conforming Random Access
Iterators that form a half-open range.</dt>
<dt><b>Effects:</b> Create a RandomAccessIterator pair that defines a
fully-closed range within the [begin,end) range of its arguments.&nbsp;
This function translates this slice's indicies while accounting for the
effects of any PyNone or negative indicies, and non-singular step sizes.</dt>
<dt><b>Returns:</b> a slice::range
that has been initialized with a non-zero value of step and a pair of
RandomAccessIterators that point within the range of this functions
arguments and define a closed interval.</dt>
<dt><b>Throws:</b> <a href="definitions.html#raise">Raises</a> a Python <code>TypeError</code> exception if any of this slice's arguments
are neither references to <code>PyNone</code> nor convertible to <code>int</code>.&nbsp; Throws
<code>std::invalid_argument</code> if the resulting range would be empty.&nbsp; You
should always wrap calls to <code>slice::get_indicies()</code>
within <code>try { ...; } catch (std::invalid_argument) {}</code> to
handle this case and take appropriate action.</dt>
<dt><b>Rationale</b>: closed-interval: If
an open interval were used, then for step
size other than 1, the required state for the end iterator would point
beyond the one-past-the-end position or before the beginning of the
specified range.<br>
exceptions on empty slice: It is impossible to define a closed interval
over an empty range, so some other form of error checking would have to
be used to prevent undefined behavior.&nbsp;In the case where the
exception is not caught, it will simply be translated to Python by the
default exception handling mechanisms. </dt>
</dl>
<h2><a name="examples"></a><b>Examples</b></h2>
<pre>
using namespace boost::python;
// Perform an extended slice of a Python list.
// Warning: extended slicing was not supported for built-in types prior
// to Python 2.3
list odd_elements(list l)
{
return l[slice(_,_,2)];
}
// Perform a multidimensional rich slice of a Numeric.array
numeric::array even_columns(numeric::array arr)
{
// select every other column, starting with the second, of a 2-D array.
// Equivalent to "return arr[:, 1::2]" in Python.
return arr[make_tuple( slice(), slice(1,_,2))];
}
// Perform a summation over a slice of a std::vector.
double partial_sum(std::vector&lt;double&gt; const&amp; Foo, slice index)
{
slice::range&lt;std::vector&lt;double&gt;::const_iterator&gt; bounds;
try {
bounds = index.get_indicies&lt;&gt;(Foo.begin(), Foo.end());
}
catch (std::invalid_argument) {
return 0.0;
}
double sum = 0.0;
while (bounds.start != bounds.end) {
sum += *bounds.start;
std::advance( bounds.start, bounds.step);
}
sum += *bounds.start;
return sum;
}
</pre>
<p>Revised 07 Febuary, 2004</p>
<p><i>&copy; Copyright <a
href="mailto:jbrandmeyer@users.sourceforge.net">Jonathan Brandmeyer</a>,
2004.&nbsp; Modification, copying and redistribution of this document
is permitted under the terms and conditions of the Boost Software
License, version 1.0.<br>
</i></p>
</body>
</html>

View File

@@ -67,8 +67,10 @@
<p>Exposes the <a href=
"http://www.python.org/dev/doc/devel/lib/string-methods.html">string
methods</a> of Python's built-in <code>str</code> type. The
semantics of the constructors and member functions defined below
can be fully understood by reading the <a href=
semantics of the constructors and member functions defined below,
except for the two-argument constructors which construct str
objects from a range of characters, can be fully understood by
reading the <a href=
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
definition. Since <code>str</code> is publicly derived from
<code><a href="object.html#object-spec">object</a></code>, the
@@ -85,7 +87,10 @@ namespace boost { namespace python
public:
str(); // new str
str(const char* s); // new str
str(char const* s); // new str
str(char const* start, char const* finish); // new str
str(char const* start, std::size_t length); // new str
template &lt;class T&gt;
explicit str(T const&amp; other);

View File

@@ -60,8 +60,8 @@ namespace boost { namespace python
template &lt;class T&gt;
struct to_python_value
{
typedef typename <a href="../../../type_traits/index.htm#transformations">add_reference</a>&lt;
typename <a href="../../../type_traits/index.htm#transformations">add_const</a>&lt;T&gt;::type
typedef typename <a href="../../../type_traits/index.html#transformations">add_reference</a>&lt;
typename <a href="../../../type_traits/index.html#transformations">add_const</a>&lt;T&gt;::type
&gt;::type argument_type;
static bool convertible();

View File

@@ -1,5 +1,8 @@
# Specify our location in the boost project hierarchy
subproject libs/python/example ;
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
# and conditions of use.
# This is the top of our own project tree
project-root ;
# Declares the following targets:
#
@@ -19,18 +22,17 @@ subproject libs/python/example ;
#
# Include definitions needed for Python modules
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
import python ;
# ----- getting_started1 -------
# Declare a Python extension called getting_started1
extension getting_started1
: # sources
getting_started1.cpp
: # sources
getting_started1.cpp
# dependencies
<dll>../build/boost_python
# requirements and dependencies for Boost.Python extensions
<template>@boost/libs/python/build/extension
;
# Declare a test for the extension module
@@ -49,8 +51,8 @@ extension getting_started2
: # sources
getting_started2.cpp
# dependencies
<dll>../build/boost_python
# requirements and dependencies for Boost.Python extensions
<template>@boost/libs/python/build/extension
;
# Declare a test for the extension module

7
example/Jamrules Executable file
View File

@@ -0,0 +1,7 @@
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
# and conditions of use.
# Edit this path to point at the root directory of your Boost
# installation. Absolute paths work, too.
path-global BOOST_ROOT : ../../.. ;
project boost : $(BOOST_ROOT) ;

6
example/boost-build.jam Executable file
View File

@@ -0,0 +1,6 @@
# Copyright David Abrahams 2003. See accompanying LICENSE for terms
# and conditions of use.
# Edit this path to point at the tools/build/v1 subdirectory of your
# Boost installation. Absolute paths work, too.
boost-build ../../../tools/build/v1 ;

View File

@@ -0,0 +1,18 @@
r'''>>> import getting_started1
>>> print getting_started1.greet()
hello, world
>>> number = 11
>>> print number, '*', number, '=', getting_started1.square(number)
11 * 11 = 121
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_getting_started1
return doctest.testmod(test_getting_started1)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -0,0 +1,31 @@
r'''>>> from getting_started2 import *
>>> hi = hello('California')
>>> hi.greet()
'Hello from California'
>>> invite(hi)
'Hello from California! Please come soon!'
>>> hi.invite()
'Hello from California! Please come soon!'
>>> class wordy(hello):
... def greet(self):
... return hello.greet(self) + ', where the weather is fine'
...
>>> hi2 = wordy('Florida')
>>> hi2.greet()
'Hello from Florida, where the weather is fine'
>>> invite(hi2)
'Hello from Florida! Please come soon!'
'''
def run(args = None):
if args is not None:
import sys
sys.argv = args
import doctest, test_getting_started2
return doctest.testmod(test_getting_started2)
if __name__ == '__main__':
import sys
sys.exit(run()[0])

View File

@@ -5,8 +5,7 @@
subproject libs/python/example/tutorial ;
# Include definitions needed for Python modules
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
import python ;
extension hello # Declare a Python extension called hello
: hello.cpp # source

View File

@@ -52,6 +52,7 @@
# include <boost/python/ptr.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/register_ptr_to_python.hpp>
# include <boost/python/return_arg.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/return_opaque_pointer.hpp>
# include <boost/python/return_value_policy.hpp>

View File

@@ -26,51 +26,25 @@ struct arg_from_python<PyObject*>
{
typedef PyObject* result_type;
arg_from_python(PyObject*) {}
arg_from_python(PyObject* p) : m_source(p) {}
bool convertible() const { return true; }
PyObject* operator()(PyObject* source) const { return source; }
PyObject* operator()() const { return m_source; }
private:
PyObject* m_source;
};
template <>
struct arg_from_python<PyObject* const&>
{
typedef PyObject* const& result_type;
arg_from_python(PyObject*) {}
arg_from_python(PyObject* p) : m_source(p) {}
bool convertible() const { return true; }
PyObject*const& operator()(PyObject*const& source) const { return source; }
PyObject*const& operator()() const { return m_source; }
private:
PyObject* m_source;
};
namespace detail
{
//
// Meta-iterators for use with caller<>
//
// temporary hack
template <class T> struct nullary : T
{
nullary(PyObject* x) : T(x), m_p(x) {}
typename T::result_type operator()() { return this->T::operator()(m_p); }
PyObject* m_p;
};
// An MPL metafunction class which returns arg_from_python<ArgType>
struct gen_arg_from_python
{
template <class ArgType> struct apply
{
typedef nullary<arg_from_python<ArgType> > type;
};
};
// An MPL iterator over an endless sequence of gen_arg_from_python
struct args_from_python
{
typedef gen_arg_from_python type;
typedef args_from_python next;
};
}
//
// implementations
//

View File

@@ -32,10 +32,12 @@
namespace boost { namespace python {
typedef detail::keywords<1> arg;
namespace detail
{
template <std::size_t nkeywords>
struct keywords
struct keywords_base
{
BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
@@ -44,18 +46,61 @@ namespace detail
return keyword_range(elements, elements + nkeywords);
}
keywords<nkeywords+1> operator,(const keywords<1> &k) const
{
python::detail::keywords<size+1> res;
std::copy(elements, elements+size, res.elements);
res.elements[size] = k.elements[0];
return res;
}
keywords<nkeywords+1> operator,(const char *name) const;
keyword elements[nkeywords];
keywords<nkeywords+1>
operator,(arg const &k) const;
keywords<nkeywords + 1>
operator,(char const *name) const;
};
template <std::size_t nkeywords>
struct keywords : keywords_base<nkeywords>
{
};
template <>
struct keywords<1> : keywords_base<1>
{
explicit keywords(char const *name)
{
elements[0].name = name;
}
template <class T>
arg& operator=(T const& value)
{
object z(value);
elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
return *this;
}
operator detail::keyword const&() const
{
return elements[0];
}
};
template <std::size_t nkeywords>
inline
keywords<nkeywords+1>
keywords_base<nkeywords>::operator,(arg const &k) const
{
keywords<nkeywords> const& l = *static_cast<keywords<nkeywords> const*>(this);
python::detail::keywords<nkeywords+1> res;
std::copy(l.elements, l.elements+nkeywords, res.elements);
res.elements[nkeywords] = k.elements[0];
return res;
}
template <std::size_t nkeywords>
inline
keywords<nkeywords + 1>
keywords_base<nkeywords>::operator,(char const *name) const
{
return this->operator,(python::arg(name));
}
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
@@ -108,39 +153,9 @@ namespace detail
# endif
}
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
class old_edg_workaround_for_arg { friend class arg; };
#endif
struct arg : detail::keywords<1>
{
explicit arg(char const *name)
{
elements[0].name = name;
}
template <class T>
arg& operator=(T const& value)
{
object z(value);
elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
return *this;
}
operator detail::keyword const&() const
{
return elements[0];
}
};
namespace detail
{
template <std::size_t nkeywords>
inline keywords<nkeywords + 1>
keywords<nkeywords>::operator,(const char *name) const
{
return this->operator,(arg(name));
}
inline detail::keywords<1> args(char const* name)
{
return detail::keywords<1>(name);
}
# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
@@ -151,7 +166,7 @@ inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name))
BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
return result; \
}
# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY)
# define BOOST_PP_LOCAL_LIMITS (2, BOOST_PYTHON_MAX_ARITY)
# include BOOST_PP_LOCAL_ITERATE()
}} // namespace boost::python

View File

@@ -40,7 +40,10 @@ namespace boost { namespace python {
# endif // CALL_DWA2002411_HPP
#elif BOOST_PP_ITERATION_DEPTH() == 1
# line BOOST_PP_LINE(__LINE__, call.hpp)
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, call.hpp)
# endif
# define N BOOST_PP_ITERATION()

View File

@@ -39,7 +39,10 @@ namespace boost { namespace python {
# endif // CALL_METHOD_DWA2002411_HPP
#elif BOOST_PP_ITERATION_DEPTH() == 1
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
# endif
# define N BOOST_PP_ITERATION()

View File

@@ -29,7 +29,6 @@
# include <boost/python/detail/overloads_fwd.hpp>
# include <boost/python/detail/operator_id.hpp>
# include <boost/python/detail/member_function_cast.hpp>
# include <boost/python/detail/def_helper.hpp>
# include <boost/python/detail/force_instantiate.hpp>
@@ -48,8 +47,14 @@
# include <boost/utility.hpp>
# include <boost/detail/workaround.hpp>
# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) || BOOST_WORKAROUND(__GNUC__, < 3)
# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004) \
/* pro9 reintroduced the bug */ \
|| (BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201))) \
|| BOOST_WORKAROUND(__GNUC__, < 3)
# define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1
# endif
# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
@@ -128,7 +133,6 @@ namespace detail
register_wrapper_class_impl((Held*)0, (T*)0, 0);
}
# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
template <class T>
struct is_data_member_pointer
: mpl::and_<
@@ -136,15 +140,17 @@ namespace detail
, mpl::not_<is_member_function_pointer<T> >
>
{};
# define BOOST_PYTHON_DATA_MEMBER_HELPER , detail::is_data_member_pointer<D>()
# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
# define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , detail::is_data_member_pointer<D>()
# define BOOST_PYTHON_YES_DATA_MEMBER , mpl::true_
# define BOOST_PYTHON_NO_DATA_MEMBER , mpl::false_
# elif defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
# define BOOST_PYTHON_DATA_MEMBER_HELPER , 0
# define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , 0
# define BOOST_PYTHON_YES_DATA_MEMBER , int
# define BOOST_PYTHON_NO_DATA_MEMBER , ...
# else
# define BOOST_PYTHON_DATA_MEMBER_HELPER
# define BOOST_PYTHON_DATA_MEMBER_HELPER(D)
# define BOOST_PYTHON_YES_DATA_MEMBER
# define BOOST_PYTHON_NO_DATA_MEMBER
# endif
@@ -338,81 +344,53 @@ class class_ : public objects::class_base
template <class D>
self& def_readonly(char const* name, D const& d)
{
return this->def_readonly_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER);
return this->def_readonly_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
template <class D>
self& def_readwrite(char const* name, D const& d)
{
return this->def_readwrite_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER);
return this->def_readwrite_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
template <class D>
self& def_readonly(char const* name, D& d)
{
return this->def_readonly_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER);
return this->def_readonly_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
template <class D>
self& def_readwrite(char const* name, D& d)
{
return this->def_readwrite_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER);
return this->def_readwrite_impl(name, d BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
// Property creation
template <class Get>
self& add_property(char const* name, Get fget)
{
base::add_property(
name
, object(
detail::member_function_cast<T,Get>::stage1(fget).stage2((T*)0).stage3(fget)
)
);
base::add_property(name, this->make_getter(fget));
return *this;
}
template <class Get, class Set>
self& add_property(char const* name, Get fget, Set fset)
{
base::add_property(
name
, object(
detail::member_function_cast<T,Get>::stage1(fget).stage2((T*)0).stage3(fget)
)
, object(
detail::member_function_cast<T,Set>::stage1(fset).stage2((T*)0).stage3(fset)
)
);
base::add_property(name, this->make_getter(fget), this->make_setter(fset));
return *this;
}
template <class Get>
self& add_static_property(char const* name, Get fget)
{
base::add_static_property(
name
, object(
detail::member_function_cast<T,Get>::stage1(fget).stage2((T*)0).stage3(fget)
)
);
base::add_static_property(name, object(fget));
return *this;
}
template <class Get, class Set>
self& add_static_property(char const* name, Get fget, Set fset)
{
base::add_static_property(
name
, object(
detail::member_function_cast<T,Get>::stage1(fget).stage2((T*)0).stage3(fget)
)
, object(
detail::member_function_cast<T,Set>::stage1(fset).stage2((T*)0).stage3(fset)
)
);
base::add_static_property(name, object(fget), object(fset));
return *this;
}
@@ -437,6 +415,12 @@ class class_ : public objects::class_base
return *this;
}
self& enable_pickling()
{
this->base::enable_pickling_(false);
return *this;
}
self& staticmethod(char const* name)
{
this->make_method_static(name);
@@ -444,34 +428,86 @@ class class_ : public objects::class_base
}
private: // helper functions
// Builds a method for this class around the given [member]
// function pointer or object, appropriately adjusting the type of
// the first signature argument so that if f is a member of a
// (possibly not wrapped) base class of T, an lvalue argument of
// type T will be required.
//
// @group PropertyHelpers {
template <class F>
object make_getter(F f)
{
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
return this->make_fn_impl(
f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
);
}
template <class F>
object make_setter(F f)
{
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
return this->make_fn_impl(
f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
);
}
template <class F>
object make_fn_impl(F const& f, mpl::false_, void*, mpl::false_)
{
return python::make_function(f, default_call_policies(), detail::get_signature(f, (T*)0));
}
template <class D, class B>
object make_fn_impl(D B::*pm_, mpl::false_, char*, mpl::true_)
{
D T::*pm = pm_;
return python::make_getter(pm);
}
template <class D, class B>
object make_fn_impl(D B::*pm_, mpl::false_, int*, mpl::true_)
{
D T::*pm = pm_;
return python::make_setter(pm);
}
template <class F>
object make_fn_impl(F const& x, mpl::true_, void*, mpl::false_)
{
return x;
}
// }
template <class D, class B>
self& def_readonly_impl(
char const* name, D B::*pm_ BOOST_PYTHON_YES_DATA_MEMBER)
{
D T::*pm = pm_;
return this->add_property(name, make_getter(pm));
return this->add_property(name, pm_);
}
template <class D, class B>
self& def_readwrite_impl(
char const* name, D B::*pm_ BOOST_PYTHON_YES_DATA_MEMBER)
{
D T::*pm = pm_;
return this->add_property(name, make_getter(pm), make_setter(pm));
return this->add_property(name, pm_, pm_);
}
template <class D>
self& def_readonly_impl(
char const* name, D& d BOOST_PYTHON_NO_DATA_MEMBER)
{
return this->add_static_property(name, make_getter(d));
return this->add_static_property(name, python::make_getter(d));
}
template <class D>
self& def_readwrite_impl(
char const* name, D& d BOOST_PYTHON_NO_DATA_MEMBER)
{
return this->add_static_property(name, make_getter(d), make_setter(d));
return this->add_static_property(name, python::make_getter(d), python::make_setter(d));
}
inline void register_() const;
@@ -481,6 +517,7 @@ class class_ : public objects::class_base
// These two overloads discriminate between def() as applied to a
// generic visitor and everything else.
//
// @group def_impl {
template <class Helper, class LeafVisitor, class Visitor>
inline void def_impl(
char const* name
@@ -501,21 +538,27 @@ class class_ : public objects::class_base
)
{
objects::add_to_namespace(
*this, name,
make_function(
// This bit of nastiness casts F to a member function of T if possible.
detail::member_function_cast<T,Fn>::stage1(fn).stage2((T*)0).stage3(fn)
, helper.policies(), helper.keywords())
, helper.doc());
*this
, name
, make_function(
fn
, helper.policies()
, helper.keywords()
, detail::get_signature(fn, (T*)0)
)
, helper.doc()
);
this->def_default(name, fn, helper, mpl::bool_<Helper::has_default_implementation>());
}
// }
//
// These two overloads handle the definition of default
// implementation overloads for virtual functions. The second one
// handles the case where no default implementation was specified.
//
// @group def_default {
template <class Fn, class Helper>
inline void def_default(
char const* name
@@ -536,6 +579,7 @@ class class_ : public objects::class_base
template <class Fn, class Helper>
inline void def_default(char const*, Fn, Helper const&, mpl::bool_<false>)
{ }
// }
//
// These two overloads discriminate between def() as applied to
@@ -543,6 +587,7 @@ class class_ : public objects::class_base
// BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
// discriminate.
//
// @group def_maybe_overloads {
template <class OverloadsT, class SigT>
void def_maybe_overloads(
char const* name
@@ -572,6 +617,7 @@ class class_ : public objects::class_base
);
}
// }
};

View File

@@ -44,7 +44,7 @@ struct pointer_cref_arg_from_python
typedef T result_type;
pointer_cref_arg_from_python(PyObject*);
T operator()(PyObject*) const;
T operator()() const;
bool convertible() const;
private: // storage for a U*
@@ -74,7 +74,7 @@ struct pointer_arg_from_python : arg_lvalue_from_python_base
typedef T result_type;
pointer_arg_from_python(PyObject*);
T operator()(PyObject*) const;
T operator()() const;
};
// Used when T == U& and (T != V const& or T == W volatile&)
@@ -84,7 +84,7 @@ struct reference_arg_from_python : arg_lvalue_from_python_base
typedef T result_type;
reference_arg_from_python(PyObject*);
T operator()(PyObject*) const;
T operator()() const;
};
// ===================
@@ -114,10 +114,11 @@ struct arg_rvalue_from_python
# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
typename arg_rvalue_from_python<T>::
# endif
result_type operator()(PyObject*);
result_type operator()();
private:
rvalue_from_python_data<result_type> m_data;
PyObject* m_source;
};
@@ -132,9 +133,10 @@ struct back_reference_arg_from_python
typedef T result_type;
back_reference_arg_from_python(PyObject*);
T operator()(PyObject*);
T operator()();
private:
typedef boost::python::arg_from_python<typename T::type> base;
PyObject* m_source;
};
@@ -259,9 +261,9 @@ inline bool pointer_cref_arg_from_python<T>::convertible() const
return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0;
}
template <class T>
inline T pointer_cref_arg_from_python<T>::operator()(PyObject* p) const
inline T pointer_cref_arg_from_python<T>::operator()() const
{
return (p == Py_None) // None ==> 0
return (*(void**)m_result.bytes == Py_None) // None ==> 0
? detail::null_ptr_reference((T(*)())0)
// Otherwise, return a U*const& to the m_result storage.
: python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
@@ -277,9 +279,9 @@ inline pointer_arg_from_python<T>::pointer_arg_from_python(PyObject* p)
}
template <class T>
inline T pointer_arg_from_python<T>::operator()(PyObject* p) const
inline T pointer_arg_from_python<T>::operator()() const
{
return (p == Py_None) ? 0 : T(result());
return (result() == Py_None) ? 0 : T(result());
}
// reference_arg_from_python
@@ -291,7 +293,7 @@ inline reference_arg_from_python<T>::reference_arg_from_python(PyObject* p)
}
template <class T>
inline T reference_arg_from_python<T>::operator()(PyObject*) const
inline T reference_arg_from_python<T>::operator()() const
{
return python::detail::void_ptr_to_reference(result(), (T(*)())0);
}
@@ -302,6 +304,7 @@ inline T reference_arg_from_python<T>::operator()(PyObject*) const
template <class T>
inline arg_rvalue_from_python<T>::arg_rvalue_from_python(PyObject* obj)
: m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters))
, m_source(obj)
{
}
@@ -313,10 +316,10 @@ inline bool arg_rvalue_from_python<T>::convertible() const
template <class T>
inline typename arg_rvalue_from_python<T>::result_type
arg_rvalue_from_python<T>::operator()(PyObject* p)
arg_rvalue_from_python<T>::operator()()
{
if (m_data.stage1.construct != 0)
m_data.stage1.construct(p, &m_data.stage1);
m_data.stage1.construct(m_source, &m_data.stage1);
return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
}
@@ -325,15 +328,15 @@ arg_rvalue_from_python<T>::operator()(PyObject* p)
//
template <class T>
back_reference_arg_from_python<T>::back_reference_arg_from_python(PyObject* x)
: base(x)
: base(x), m_source(x)
{
}
template <class T>
inline T
back_reference_arg_from_python<T>::operator()(PyObject* x)
back_reference_arg_from_python<T>::operator()()
{
return T(x, base::operator()(x));
return T(m_source, base::operator()());
}
}}} // namespace boost::python::converter

View File

@@ -8,6 +8,7 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/python/handle.hpp>
# include <boost/implicit_cast.hpp>
# include <string>
# include <complex>
# include <boost/limits.hpp>
@@ -82,16 +83,16 @@ namespace detail
// Specialize converters for signed and unsigned T to Python Int
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x)) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
unsigned T \
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
std::numeric_limits<long>::max()) \
? PyLong_FromUnsignedLong(x) \
: PyInt_FromLong(x))
? ::PyLong_FromUnsignedLong(x) \
: ::PyInt_FromLong(x))
// Bool is not signed.
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, ::PyInt_FromLong(x))
// note: handles signed char and unsigned char, but not char (see below)
BOOST_PYTHON_TO_INT(char)
@@ -103,23 +104,31 @@ BOOST_PYTHON_TO_INT(long)
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
# ifdef HAVE_LONG_LONG
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, PyLong_FromLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, PyLong_FromUnsignedLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x))
# endif
# undef BOOST_TO_PYTHON_INT
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromStringAndSize(x.c_str(),x.size()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<int>(x.size())))
# ifndef BOOST_NO_STD_WSTRING
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<int>(x.size())))
# endif
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, ::PyFloat_FromDouble(x))
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<float>, ::PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<long double>, ::PyComplex_FromDoubles(x.real(), x.imag()))
# undef BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE
# undef BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE
# undef BOOST_PYTHON_TO_PYTHON_BY_VALUE
# undef BOOST_PYTHON_TO_INT
namespace converter
{

View File

@@ -0,0 +1,18 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
# define CONTEXT_RESULT_CONVERTER_DWA2003917_HPP
namespace boost { namespace python { namespace converter {
// A ResultConverter base class used to indicate that this result
// converter should be constructed with the original Python argument
// list.
struct context_result_converter {};
}}} // namespace boost::python::converter
#endif // CONTEXT_RESULT_CONVERTER_DWA2003917_HPP

View File

@@ -27,7 +27,7 @@ struct object_manager_value_arg_from_python
object_manager_value_arg_from_python(PyObject*);
bool convertible() const;
T operator()(PyObject*) const;
T operator()() const;
private:
PyObject* m_source;
};
@@ -48,7 +48,7 @@ struct object_manager_ref_arg_from_python
object_manager_ref_arg_from_python(PyObject*);
bool convertible() const;
Ref operator()(PyObject*) const;
Ref operator()() const;
~object_manager_ref_arg_from_python();
private:
typename python::detail::referent_storage<Ref>::type m_result;
@@ -71,9 +71,9 @@ inline bool object_manager_value_arg_from_python<T>::convertible() const
}
template <class T>
inline T object_manager_value_arg_from_python<T>::operator()(PyObject* x) const
inline T object_manager_value_arg_from_python<T>::operator()() const
{
return T(python::detail::borrowed_reference(x));
return T(python::detail::borrowed_reference(m_source));
}
template <class Ref>
@@ -111,7 +111,7 @@ inline bool object_manager_ref_arg_from_python<Ref>::convertible() const
}
template <class Ref>
inline Ref object_manager_ref_arg_from_python<Ref>::operator()(PyObject*) const
inline Ref object_manager_ref_arg_from_python<Ref>::operator()() const
{
return python::detail::void_ptr_to_reference(
this->m_result.bytes, (Ref(*)())0);

View File

@@ -1,99 +0,0 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
# define PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP
# include <boost/python/detail/prefix.hpp>
//
// arg_from_python converters for Python type wrappers, to be used as
// base classes for specializations.
//
namespace boost { namespace python { namespace converter {
template <PyTypeObject* python_type>
struct pytype_arg_from_python
{
pytype_arg_from_python(PyObject*);
bool convertible() const;
private:
PyObject* m_src;
};
// rvalue converter base
template <class Wrapper, PyTypeObject* python_type>
struct pytype_wrapper_value_arg_from_python
: pytype_arg_from_python<python_type>
{
typedef Wrapper result_type;
pytype_wrapper_value_arg_from_python(PyObject*);
Wrapper operator()(PyObject*) const;
};
// Special case for Wrapper& - must store an lvalue internally. This
// OK because the entire state of the object is actually in the Python
// object.
template <class Wrapper, PyTypeObject* python_type>
struct pytype_wrapper_ref_arg_from_python
: pytype_arg_from_python<python_type>
{
typedef Wrapper& result_type;
pytype_wrapper_ref_arg_from_python(PyObject*);
Wrapper& operator()(PyObject*) const;
private:
mutable Wrapper m_result;
};
//
// implementations
//
template <PyTypeObject* python_type>
inline pytype_arg_from_python<python_type>::pytype_arg_from_python(PyObject* x)
: m_src(x)
{
}
template <PyTypeObject* python_type>
inline bool pytype_arg_from_python<python_type>::convertible() const
{
return PyObject_IsInstance(m_src, (PyObject*)python_type);
}
template <class Wrapper, PyTypeObject* python_type>
pytype_wrapper_value_arg_from_python<Wrapper,python_type>::pytype_wrapper_value_arg_from_python(
PyObject* p)
: pytype_arg_from_python<python_type>(p)
{
}
template <class Wrapper, PyTypeObject* python_type>
Wrapper pytype_wrapper_value_arg_from_python<Wrapper,python_type>::operator()(
PyObject* x) const
{
return Wrapper(python::detail::borrowed_reference(x));
}
template <class Wrapper, PyTypeObject* python_type>
pytype_wrapper_ref_arg_from_python<Wrapper,python_type>::pytype_wrapper_ref_arg_from_python(
PyObject* p)
: pytype_arg_from_python<python_type>(p)
, m_result(python::detail::borrowed_reference(p))
{
}
template <class Wrapper, PyTypeObject* python_type>
Wrapper& pytype_wrapper_ref_arg_from_python<Wrapper,python_type>::operator()(
PyObject* x) const
{
return m_result;
}
}}} // namespace boost::python::converter
#endif // PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP

View File

@@ -19,14 +19,13 @@ struct shared_ptr_from_python
converter::registry::insert(&convertible, &construct, type_id<shared_ptr<T> >());
}
static shared_ptr_from_python const registration;
private:
static void* convertible(PyObject* p)
{
return p == Py_None
? p
: converter::get_lvalue_from_python(p, registered<T>::converters)
;
if (p == Py_None)
return p;
return converter::get_lvalue_from_python(p, registered<T>::converters);
}
static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
@@ -45,9 +44,6 @@ struct shared_ptr_from_python
}
};
template <class T>
shared_ptr_from_python<T> const shared_ptr_from_python<T>::registration;
}}} // namespace boost::python::converter
#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP

View File

@@ -9,6 +9,7 @@
# include <boost/python/refcount.hpp>
# include <boost/python/converter/shared_ptr_deleter.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/get_pointer.hpp>
namespace boost { namespace python { namespace converter {
@@ -18,7 +19,7 @@ PyObject* shared_ptr_to_python(shared_ptr<T> const& x)
if (!x)
return python::detail::none();
else if (shared_ptr_deleter* d = boost::get_deleter<shared_ptr_deleter>(x))
return incref(d->owner.get());
return incref( get_pointer( d->owner ) );
else
return converter::registered<shared_ptr<T> const&>::converters.to_python(&x);
}

View File

@@ -8,12 +8,12 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/return_by_value.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/converter/builtin_converters.hpp>
@@ -24,12 +24,14 @@
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/is_member_pointer.hpp>
# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
# include <boost/type_traits/remove_cv.hpp>
# endif
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/vector/vector10.hpp>
# include <boost/bind.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python {
@@ -43,97 +45,57 @@ namespace boost { namespace python {
namespace detail
{
//
// Raw Getter and Setter function generators. These class templates
// generate static functions which can be bound together with
// policies and wrapped to generate the python callable objects
// mentioned above.
//
//
// Generates get and set functions for access through
// pointers-to-data-members
//
template <class Data, class Class, class Policies>
// A small function object which handles the getting and setting of
// data members.
template <class Data, class Class>
struct member
{
static PyObject* get(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies)
{
arg_from_python<Class*> c0(PyTuple_GET_ITEM(args_, 0));
if (!c0.convertible()) return 0;
// find the result converter
typedef typename Policies::result_converter result_converter;
typedef typename boost::add_reference<Data>::type source;
typename mpl::apply1<result_converter,source>::type cr;
if (!policies.precall(args_)) return 0;
PyObject* result = cr( (c0(PyTuple_GET_ITEM(args_, 0)))->*pm );
return policies.postcall(args_, result);
}
static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies)
{
// check that each of the arguments is convertible
arg_from_python<Class&> c0(PyTuple_GET_ITEM(args_, 0));
if (!c0.convertible()) return 0;
typedef typename add_const<Data>::type target1;
typedef typename add_reference<target1>::type target;
arg_from_python<target> c1(PyTuple_GET_ITEM(args_, 1));
private:
typedef typename add_const<Data>::type data_const;
typedef typename add_reference<data_const>::type data_cref;
if (!c1.convertible()) return 0;
if (!policies.precall(args_)) return 0;
(c0(PyTuple_GET_ITEM(args_, 0))).*pm = c1(PyTuple_GET_ITEM(args_, 1));
return policies.postcall(args_, detail::none());
public:
member(Data Class::*which) : m_which(which) {}
Data& operator()(Class& c) const
{
return c.*m_which;
}
void operator()(Class& c, data_cref d) const
{
c.*m_which = d;
}
private:
Data Class::*m_which;
};
//
// Generates get and set functions for access through ordinary
// pointers. These are generally used to wrap static data members,
// but can also be used to expose namespace-scope data as class
// attributes.
//
template <class Data, class Policies>
// A small function object which handles the getting and setting of
// non-member objects.
template <class Data>
struct datum
{
static PyObject* get(Data *p, PyObject* args_, PyObject*, Policies const& policies)
{
// find the result converter
typedef typename Policies::result_converter result_converter;
typedef typename boost::add_reference<Data>::type source;
typename mpl::apply1<result_converter,source>::type cr;
if (!policies.precall(args_)) return 0;
PyObject* result = cr( *p );
return policies.postcall(args_, result);
}
static PyObject* set(Data* p, PyObject* args_, PyObject*, Policies const& policies)
{
// check that each of the arguments is convertible
typedef typename add_const<Data>::type target1;
typedef typename add_reference<target1>::type target;
arg_from_python<target> c0(PyTuple_GET_ITEM(args_, 0));
private:
typedef typename add_const<Data>::type data_const;
typedef typename add_reference<data_const>::type data_cref;
if (!c0.convertible()) return 0;
if (!policies.precall(args_)) return 0;
*p = c0(PyTuple_GET_ITEM(args_, 0));
return policies.postcall(args_, detail::none());
public:
datum(Data *which) : m_which(which) {}
Data& operator()() const
{
return *m_which;
}
};
void operator()(data_cref d) const
{
*m_which = d;
}
private:
Data *m_which;
};
//
// Helper metafunction for determining the default CallPolicy to use
// for attribute access. If T is a [reference to a] class type X
@@ -208,13 +170,8 @@ namespace detail
template <class D, class Policies>
inline object make_getter(D* d, Policies const& policies, mpl::false_, int)
{
return objects::function_object(
objects::py_function(
::boost::bind(
&detail::datum<D,Policies>::get, d, _1, _2
, policies)
, mpl::vector1<D>()
)
return python::make_function(
detail::datum<D>(d), policies, mpl::vector1<D&>()
);
}
@@ -230,14 +187,16 @@ namespace detail
template <class C, class D, class Policies>
inline object make_getter(D C::*pm, Policies const& policies, mpl::true_, int)
{
return objects::function_object(
objects::py_function(
::boost::bind(
&detail::member<D,C,Policies>::get, pm, _1, _2
, policies)
, mpl::vector2<D, C const*>()
)
);
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
typedef typename remove_cv<C>::type Class;
#else
typedef C Class;
#endif
return python::make_function(
detail::member<D,Class>(pm)
, policies
, mpl::vector2<D&,Class&>()
);
}
// Handle pointers-to-members without policies
@@ -268,13 +227,8 @@ namespace detail
template <class D, class Policies>
inline object make_setter(D* p, Policies const& policies, mpl::false_, int)
{
return objects::function_object(
objects::py_function(
::boost::bind(
&detail::datum<D,Policies>::set, p, _1, _2
, policies)
, mpl::vector2<void, D const&>()
)
return python::make_function(
detail::datum<D>(p), policies, mpl::vector2<void,D const&>()
);
}
@@ -282,13 +236,10 @@ namespace detail
template <class C, class D, class Policies>
inline object make_setter(D C::*pm, Policies const& policies, mpl::true_, int)
{
return objects::function_object(
objects::py_function(
::boost::bind(
&detail::member<D,C,Policies>::set, pm, _1, _2
, policies)
, mpl::vector3<void, C*, D const&>()
)
return python::make_function(
detail::member<D,C>(pm)
, policies
, mpl::vector3<void, C&, D const&>()
);
}

View File

@@ -29,19 +29,23 @@ struct default_result_converter;
struct default_call_policies
{
// Nothing to do
static bool precall(PyObject*)
// Ownership of this argument tuple will ultimately be adopted by
// the caller.
template <class ArgumentPackage>
static bool precall(ArgumentPackage const&)
{
return true;
}
// Pass the result through
static PyObject* postcall(PyObject*, PyObject* result)
template <class ArgumentPackage>
static PyObject* postcall(ArgumentPackage const&, PyObject* result)
{
return result;
}
typedef default_result_converter result_converter;
typedef PyObject* argument_package;
};
struct default_result_converter

View File

@@ -9,70 +9,100 @@
# ifndef CALLER_DWA20021121_HPP
# define CALLER_DWA20021121_HPP
# include <boost/compressed_pair.hpp>
# include <boost/mpl/apply.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/at.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/detail/invoke.hpp>
# include <boost/python/detail/signature.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/python/converter/context_result_converter.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/iteration/local.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/preprocessor/repetition/repeat.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/dec.hpp>
# include <boost/preprocessor/if.hpp>
# include <boost/preprocessor/iteration/local.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/preprocessor/repetition/repeat.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/detail/invoke.hpp>
# include <boost/python/detail/signature.hpp>
# include <boost/compressed_pair.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/mpl/apply.hpp>
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/at.hpp>
# include <boost/mpl/int.hpp>
namespace boost { namespace python { namespace detail {
template <int N>
inline PyObject* get(mpl::int_<N>, PyObject* const& args_)
{
return PyTuple_GET_ITEM(args_,N);
}
inline unsigned arity(PyObject* const& args_)
{
return PyTuple_GET_SIZE(args_);
}
// This "result converter" is really just used as
// a dispatch tag to invoke(...), selecting the appropriate
// implementation
typedef int void_result_to_python;
// A metafunction taking an iterator FunctionIter to a metafunction
// class and an iterator ArgIter to an argument, which applies the
// result of dereferencing FunctionIter to the result of dereferencing
// ArgIter
template <class FunctionIter, class ArgIter>
struct apply_iter1
: mpl::apply1<typename FunctionIter::type, typename ArgIter::type> {};
// Given a model of CallPolicies and a C++ result type, this
// metafunction selects the appropriate converter to use for
// converting the result to python.
template <class Policies, class Result>
struct select_result_converter
: mpl::if_<
: mpl::apply_if<
is_same<Result,void>
, void_result_to_python
, typename mpl::apply1<typename Policies::result_converter,Result>::type*
, mpl::identity<void_result_to_python>
, mpl::apply1<typename Policies::result_converter,Result>
>
{
};
template <class ArgPackage, class ResultConverter>
inline ResultConverter create_result_converter(
ArgPackage const& args_
, ResultConverter*
, converter::context_result_converter*
)
{
return ResultConverter(args_);
}
template <class ArgPackage, class ResultConverter>
inline ResultConverter create_result_converter(
ArgPackage const& args_
, ResultConverter*
, ...
)
{
return ResultConverter();
}
template <unsigned> struct caller_arity;
template <class F, class ConverterGenerators, class CallPolicies, class Sig>
template <class F, class CallPolicies, class Sig>
struct caller;
# define BOOST_PYTHON_NEXT(init,name,n) \
typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n;
# define BOOST_PYTHON_ARG_CONVERTER(n) \
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \
typedef typename apply_iter1<conv_iter##n,arg_iter##n>::type c_t##n; \
c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \
if (!c##n.convertible()) \
# define BOOST_PYTHON_ARG_CONVERTER(n) \
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \
c_t##n c##n(get(mpl::int_<n>(), inner_args)); \
if (!c##n.convertible()) \
return 0;
# define BOOST_PP_ITERATION_PARAMS_1 \
@@ -84,11 +114,11 @@ struct caller;
// A metafunction returning the base class used for caller<class F,
// class ConverterGenerators, class CallPolicies, class Sig>.
template <class F, class ConverterGenerators, class CallPolicies, class Sig>
template <class F, class CallPolicies, class Sig>
struct caller_base_select
{
enum { arity = mpl::size<Sig>::value - 1 };
typedef typename caller_arity<arity>::template impl<F,ConverterGenerators,CallPolicies,Sig> type;
typedef typename caller_arity<arity>::template impl<F,CallPolicies,Sig> type;
};
// A function object type which wraps C++ objects as Python callable
@@ -101,11 +131,6 @@ struct caller_base_select
// actually be any data for which an appropriate invoke_tag() can
// be generated. invoke(...) takes care of the actual invocation syntax.
//
// ConverterGenerators -
// An MPL iterator type over a sequence of metafunction classes
// that can be applied to element 1...N of Sig to produce
// argument from_python converters for the arguments
//
// CallPolicies -
// The precall, postcall, and what kind of resultconverter to
// generate for mpl::front<Sig>::type
@@ -114,12 +139,12 @@ struct caller_base_select
// The `intended signature' of the function. An MPL sequence
// beginning with a result type and continuing with a list of
// argument types.
template <class F, class ConverterGenerators, class CallPolicies, class Sig>
template <class F, class CallPolicies, class Sig>
struct caller
: caller_base_select<F,ConverterGenerators,CallPolicies,Sig>::type
: caller_base_select<F,CallPolicies,Sig>::type
{
typedef typename caller_base_select<
F,ConverterGenerators,CallPolicies,Sig
F,CallPolicies,Sig
>::type base;
typedef PyObject* result_type;
@@ -139,7 +164,7 @@ struct caller
template <>
struct caller_arity<N>
{
template <class F, class ConverterGenerators, class Policies, class Sig>
template <class F, class Policies, class Sig>
struct impl
{
impl(F f, Policies p) : m_data(f,p) {}
@@ -152,6 +177,10 @@ struct caller_arity<N>
typedef typename mpl::begin<Sig>::type first;
typedef typename first::type result_t;
typedef typename select_result_converter<Policies, result_t>::type result_converter;
typedef typename Policies::argument_package argument_package;
argument_package inner_args(args_);
# if N
# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
# define BOOST_PP_LOCAL_LIMITS (0, N-1)
@@ -159,15 +188,17 @@ struct caller_arity<N>
# endif
// all converters have been checked. Now we can do the
// precall part of the policy
if (!m_data.second().precall(args_))
if (!m_data.second().precall(inner_args))
return 0;
typedef typename detail::invoke_tag<F>::type tag;
PyObject* result = detail::invoke(
tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c));
detail::invoke_tag<result_t,F>()
, create_result_converter(args_, (result_converter*)0, (result_converter*)0)
, m_data.first()
BOOST_PP_ENUM_TRAILING_PARAMS(N, c)
);
return m_data.second().postcall(args_, result);
return m_data.second().postcall(inner_args, result);
}
static unsigned min_arity() { return N; }

View File

@@ -15,4 +15,4 @@ namespace boost { namespace python { namespace detail {
}
}
}}} // namespace boost::python::detail
# endif // BOOST_PYTHON_DETAIL_DEALLOC_HPP_
# endif // BOOST_PYTHON_DETAIL_DEALLOC_HPP_

View File

@@ -37,8 +37,13 @@ namespace objects
namespace detail
{
template <class T, class F> struct member_function_cast;
// Called as::
//
// name_space_def(ns, "func", func, kw, policies, docstring, &ns)
//
// Dispatch to properly add f to namespace ns.
//
// @group define_stub_function helpers {
template <class Func, class CallPolicies, class NameSpaceT>
static void name_space_def(
NameSpaceT& name_space
@@ -55,10 +60,9 @@ namespace detail
objects::add_to_namespace(
name_space, name,
detail::make_keyword_range_function(
// This bit of nastiness casts F to a member function of T if possible.
member_function_cast<wrapped_type,Func>::stage1(f).stage2((wrapped_type*)0).stage3(f)
, policies, kw)
, doc);
f, policies, kw, get_signature(f, (wrapped_type*)0))
, doc
);
}
template <class Func, class CallPolicies>
@@ -80,7 +84,7 @@ namespace detail
, doc);
}
// For backward compatibility
// For backward compatibility -- is this obsolete?
template <class Func, class CallPolicies, class NameSpaceT>
static void name_space_def(
NameSpaceT& name_space
@@ -94,10 +98,10 @@ namespace detail
{
name_space.def(name, f, policies, doc);
}
// }
///////////////////////////////////////////////////////////////////////////////
//
// This Boost PP code generates expansions for
// Expansions of ::
//
// template <typename OverloadsT, typename NameSpaceT>
// inline void
@@ -107,7 +111,7 @@ namespace detail
// name_space.def(name, &OverloadsT::func_N);
// }
//
// where N runs from 0 to BOOST_PYTHON_MAX_ARITY
// where N runs from 0 to BOOST_PYTHON_MAX_ARITY.
//
// The set of overloaded functions (define_stub_function) expects:
//
@@ -118,7 +122,7 @@ namespace detail
// (see defaults_gen.hpp)
// 5. char const* name: doc string
//
///////////////////////////////////////////////////////////////////////////////
// @group define_stub_function<N> {
template <int N>
struct define_stub_function {};
@@ -126,129 +130,137 @@ namespace detail
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>))
#include BOOST_PP_ITERATE()
// }
// This helper template struct does the actual recursive
// definition. There's a generic version
// define_with_defaults_helper<N> and a terminal case
// define_with_defaults_helper<0>. The struct and its
// specialization has a sole static member function def that
// expects:
//
// 1. char const* name: function name that will be
// visible to python
//
// 2. OverloadsT: a function overloads struct
// (see defaults_gen.hpp)
//
// 3. NameSpaceT& name_space: a python::class_ or
// python::module instance
//
// 4. char const* name: doc string
//
// The def static member function calls a corresponding
// define_stub_function<N>. The general case recursively calls
// define_with_defaults_helper<N-1>::def until it reaches the
// terminal case case define_with_defaults_helper<0>.
template <int N>
struct define_with_defaults_helper {
///////////////////////////////////////////////////////////////////////////////
//
// define_with_defaults_helper<N>
//
// This helper template struct does the actual recursive definition.
// There's a generic version define_with_defaults_helper<N> and a
// terminal case define_with_defaults_helper<0>. The struct and its
// specialization has a sole static member function def that expects:
//
// 1. char const* name: function name that will be visible to python
// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp)
// 3. NameSpaceT& name_space: a python::class_ or python::module instance
// 4. char const* name: doc string
//
// The def static member function calls a corresponding
// define_stub_function<N>. The general case recursively calls
// define_with_defaults_helper<N-1>::def until it reaches the
// terminal case case define_with_defaults_helper<0>.
//
///////////////////////////////////////////////////////////////////////////////
template <int N>
struct define_with_defaults_helper {
template <class StubsT, class CallPolicies, class NameSpaceT>
static void
def(
char const* name,
StubsT stubs,
keyword_range kw,
CallPolicies const& policies,
NameSpaceT& name_space,
char const* doc)
{
// define the NTH stub function of stubs
define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
template <class StubsT, class CallPolicies, class NameSpaceT>
static void
def(
char const* name,
StubsT stubs,
keyword_range kw,
CallPolicies const& policies,
NameSpaceT& name_space,
char const* doc)
{
// define the NTH stub function of stubs
define_stub_function<N>::define(name, stubs, kw, policies, name_space, doc);
if (kw.second > kw.first)
--kw.second;
// call the next define_with_defaults_helper
define_with_defaults_helper<N-1>::def(name, stubs, kw, policies, name_space, doc);
}
};
if (kw.second > kw.first)
--kw.second;
///////////////////////////////////////
template <>
struct define_with_defaults_helper<0> {
// call the next define_with_defaults_helper
define_with_defaults_helper<N-1>::def(name, stubs, kw, policies, name_space, doc);
}
};
template <class StubsT, class CallPolicies, class NameSpaceT>
static void
def(
char const* name,
StubsT stubs,
keyword_range const& kw,
CallPolicies const& policies,
NameSpaceT& name_space,
char const* doc)
{
// define the Oth stub function of stubs
define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc);
// return
}
};
template <>
struct define_with_defaults_helper<0> {
///////////////////////////////////////////////////////////////////////////////
//
// define_with_defaults
//
// 1. char const* name: function name that will be visible to python
// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp)
// 3. CallPolicies& policies: Call policies
// 4. NameSpaceT& name_space: a python::class_ or python::module instance
// 5. SigT sig: Function signature typelist (see defaults_gen.hpp)
// 6. char const* name: doc string
//
// This is the main entry point. This function recursively defines all
// stub functions of StubT (see defaults_gen.hpp) in NameSpaceT name_space which
// can be either a python::class_ or a python::module. The sig argument
// is a typelist that specifies the return type, the class (for member
// functions, and the arguments. Here are some SigT examples:
//
// int foo(int) mpl::list<int, int>
// void bar(int, int) mpl::list<void, int, int>
// void C::foo(int) mpl::list<void, C, int>
//
///////////////////////////////////////////////////////////////////////////////
template <class OverloadsT, class NameSpaceT, class SigT>
inline void
define_with_defaults(
char const* name,
OverloadsT const& overloads,
NameSpaceT& name_space,
SigT const&)
{
typedef typename mpl::front<SigT>::type return_type;
typedef typename OverloadsT::void_return_type void_return_type;
typedef typename OverloadsT::non_void_return_type non_void_return_type;
template <class StubsT, class CallPolicies, class NameSpaceT>
static void
def(
char const* name,
StubsT stubs,
keyword_range const& kw,
CallPolicies const& policies,
NameSpaceT& name_space,
char const* doc)
{
// define the Oth stub function of stubs
define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc);
// return
}
};
typedef typename mpl::if_c<
boost::is_same<void, return_type>::value
, void_return_type
, non_void_return_type
>::type stubs_type;
// define_with_defaults
//
// 1. char const* name: function name that will be
// visible to python
//
// 2. OverloadsT: a function overloads struct
// (see defaults_gen.hpp)
//
// 3. CallPolicies& policies: Call policies
// 4. NameSpaceT& name_space: a python::class_ or
// python::module instance
//
// 5. SigT sig: Function signature typelist
// (see defaults_gen.hpp)
//
// 6. char const* name: doc string
//
// This is the main entry point. This function recursively
// defines all stub functions of StubT (see defaults_gen.hpp) in
// NameSpaceT name_space which can be either a python::class_ or
// a python::module. The sig argument is a typelist that
// specifies the return type, the class (for member functions,
// and the arguments. Here are some SigT examples:
//
// int foo(int) mpl::vector<int, int>
// void bar(int, int) mpl::vector<void, int, int>
// void C::foo(int) mpl::vector<void, C, int>
//
template <class OverloadsT, class NameSpaceT, class SigT>
inline void
define_with_defaults(
char const* name,
OverloadsT const& overloads,
NameSpaceT& name_space,
SigT const&)
{
typedef typename mpl::front<SigT>::type return_type;
typedef typename OverloadsT::void_return_type void_return_type;
typedef typename OverloadsT::non_void_return_type non_void_return_type;
BOOST_STATIC_ASSERT(
(stubs_type::max_args) <= mpl::size<SigT>::value);
typedef typename mpl::if_c<
boost::is_same<void, return_type>::value
, void_return_type
, non_void_return_type
>::type stubs_type;
typedef typename stubs_type::template gen<SigT> gen_type;
define_with_defaults_helper<stubs_type::n_funcs-1>::def(
name
, gen_type()
, overloads.keywords()
, overloads.call_policies()
, name_space
, overloads.doc_string());
}
BOOST_STATIC_ASSERT(
(stubs_type::max_args) <= mpl::size<SigT>::value);
typedef typename stubs_type::template gen<SigT> gen_type;
define_with_defaults_helper<stubs_type::n_funcs-1>::def(
name
, gen_type()
, overloads.keywords()
, overloads.call_policies()
, name_space
, overloads.doc_string());
}
} // namespace detail
}} // namespace boost::python
///////////////////////////////////////////////////////////////////////////////
#endif // DEFAULTS_DEF_JDG20020811_HPP
#else // defined(BOOST_PP_IS_ITERATING)

View File

@@ -45,23 +45,19 @@ namespace boost { namespace python { namespace detail {
// invoke(...), selecting the appropriate implementation
typedef int void_result_to_python;
// Trait forward declaration.
template <class T> struct is_defaulted_virtual_fn;
// Tag types describing invocation methods
struct fn_tag {};
struct mem_fn_tag {};
template <bool void_return, bool member>
struct invoke_tag_ {};
// A metafunction returning the appropriate tag type for invoking an
// object of type T.
template <class T>
// object of type F with return type R.
template <class R, class F>
struct invoke_tag
: mpl::if_<
is_member_function_pointer<T>
, mem_fn_tag
, fn_tag
: invoke_tag_<
is_same<R,void>::value
, is_member_function_pointer<F>::value
>
{};
{
};
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/invoke.hpp>))
@@ -75,26 +71,26 @@ struct invoke_tag
# define N BOOST_PP_ITERATION()
template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
inline PyObject* invoke(fn_tag, RC*, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
inline PyObject* invoke(invoke_tag_<false,false>, RC const& rc, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
{
return RC()(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ));
return rc(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ));
}
template <class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
inline PyObject* invoke(fn_tag, void_result_to_python, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
template <class RC, class F BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
inline PyObject* invoke(invoke_tag_<true,false>, RC const&, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
{
f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) );
return none();
}
template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
inline PyObject* invoke(mem_fn_tag, RC*, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
inline PyObject* invoke(invoke_tag_<false,true>, RC const& rc, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
{
return RC()( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) );
return rc( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) );
}
template <class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
inline PyObject* invoke(mem_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
template <class RC, class F, class TC BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class AC)>
inline PyObject* invoke(invoke_tag_<true,true>, RC const&, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) )
{
(tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT));
return none();

View File

@@ -14,36 +14,39 @@
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/add_reference.hpp>
# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \
template <class X_> \
struct is_##name \
{ \
typedef char yes; \
typedef char (&no)[2]; \
\
static typename add_reference<X_>::type dummy; \
\
template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \
static yes test( \
qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) >&, int \
); \
\
template <class U> \
static no test(U&, ...); \
\
BOOST_STATIC_CONSTANT( \
bool, value \
= !is_reference<X_>::value \
& (sizeof(test(dummy, 0)) == sizeof(yes))); \
\
typedef mpl::bool_<value> type; \
# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \
template <class X_> \
struct is_##name \
{ \
typedef char yes; \
typedef char (&no)[2]; \
\
static typename add_reference<X_>::type dummy; \
\
struct helpers \
{ \
template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \
static yes test( \
qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) >&, int \
); \
\
template <class U> \
static no test(U&, ...); \
}; \
\
BOOST_STATIC_CONSTANT( \
bool, value \
= !is_reference<X_>::value \
& (sizeof(helpers::test(dummy, 0)) == sizeof(yes))); \
\
typedef mpl::bool_<value> type; \
};
# else
# define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \
template <class T> \
struct is_##name : mpl::false_ \
struct is_##name : mpl::false_ \
{ \
}; \
\
@@ -51,7 +54,7 @@ template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) > \
struct is_##name< \
qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) > \
> \
: mpl::true_ \
: mpl::true_ \
{ \
};

View File

@@ -21,13 +21,30 @@ namespace boost { namespace python { namespace detail {
// F. This version is needed when defining functions with default
// arguments, because compile-time information about the number of
// keywords is missing for all but the initial function definition.
//
// @group make_keyword_range_function {
template <class F, class Policies>
object make_keyword_range_function(F f, Policies const& policies, keyword_range const& kw)
object make_keyword_range_function(
F f
, Policies const& policies
, keyword_range const& kw)
{
return detail::make_function_aux(
f, policies, args_from_python(), detail::get_signature(f), kw, mpl::int_<0>());
f, policies, detail::get_signature(f), kw, mpl::int_<0>());
}
template <class F, class Policies, class Signature>
object make_keyword_range_function(
F f
, Policies const& policies
, keyword_range const& kw
, Signature const& sig)
{
return detail::make_function_aux(
f, policies, sig, kw, mpl::int_<0>());
}
// }
// Builds an '__init__' function which inserts the given Holder type
// in a wrapped C++ class instance. ArgList is an MPL type sequence
// describing the C++ argument types to be passed to Holder's

View File

@@ -1,118 +0,0 @@
#if !defined(BOOST_PP_IS_ITERATING)
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# ifndef MEMBER_FUNCTION_CAST_DWA2002311_HPP
# define MEMBER_FUNCTION_CAST_DWA2002311_HPP
# include <boost/python/detail/preprocessor.hpp>
# include <boost/mpl/if.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/preprocessor/comma_if.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/debug/line.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
namespace boost { namespace python { namespace detail {
template <class S, class FT>
struct cast_helper
{
struct yes_helper
{
static FT stage3(FT x) { return x; }
};
struct no_helper
{
template <class T>
static T stage3(T x) { return x; }
};
static yes_helper stage2(S*) { return yes_helper(); }
static no_helper stage2(void*) { return no_helper(); }
};
struct non_member_function_cast_impl
{
template <class T>
static non_member_function_cast_impl stage1(T) { return non_member_function_cast_impl(); }
template <class T>
static non_member_function_cast_impl stage2(T) { return non_member_function_cast_impl(); }
template <class T>
T stage3(T x) { return x; }
};
template <class T>
struct member_function_cast_impl
{
# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
template <class U>
static non_member_function_cast_impl stage1(U)
{
return non_member_function_cast_impl();
}
# endif
// Member functions
# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, <boost/python/detail/member_function_cast.hpp>))
# include BOOST_PP_ITERATE()
};
template <class T, class SF>
struct member_function_cast
# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
: member_function_cast_impl<T>
# else
: mpl::if_c<
is_member_function_pointer<SF>::value
, member_function_cast_impl<T>
, non_member_function_cast_impl
>::type
# endif
{
};
}}} // namespace boost::python::detail
# endif // MEMBER_FUNCTION_CAST_DWA2002311_HPP
#elif BOOST_PP_ITERATION_DEPTH() == 1
// outer over cv-qualifiers
# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/member_function_cast.hpp>))
# include BOOST_PP_ITERATE()
#elif BOOST_PP_ITERATION_DEPTH() == 2
# line BOOST_PP_LINE(__LINE__, member_function_cast.hpp)
// inner over arities
# define N BOOST_PP_ITERATION()
# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1))
# define P BOOST_PP_ENUM_PARAMS_Z(1, N, A)
template <
class S, class R
BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)
>
static cast_helper<S, R (T::*)( P ) Q>
stage1(R (S::*)( P ) Q)
{
return cast_helper<S, R (T::*)( P ) Q>();
}
# undef P
# undef N
# undef Q
#endif

View File

@@ -47,7 +47,8 @@ enum operator_id
op_iand,
op_ixor,
op_ior,
op_complex
op_complex,
op_nonzero
};
}}} // namespace boost::python::detail

View File

@@ -18,7 +18,7 @@
/* Enable compiler features; switching on C lib defines doesn't work
here, because the symbols haven't necessarily been defined yet. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# define _GNU_SOURCE 1
#endif
/* Forcing SUSv2 compatibility still produces problems on some
@@ -26,7 +26,7 @@
define is switched off. */
#if 0
#ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 500
# define _XOPEN_SOURCE 500
#endif
#endif
@@ -40,10 +40,10 @@
#endif
/* pyconfig.h may or may not define DL_IMPORT */
#ifndef DL_IMPORT /* declarations for DLL import/export */
#ifndef DL_IMPORT /* declarations for DLL import/export */
#define DL_IMPORT(RTYPE) RTYPE
#endif
#ifndef DL_EXPORT /* declarations for DLL import/export */
#ifndef DL_EXPORT /* declarations for DLL import/export */
#define DL_EXPORT(RTYPE) RTYPE
#endif
@@ -124,15 +124,15 @@ extern "C" { // Boost.Python modification: provide missing extern "C"
#include "abstract.h"
#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a))
#define PyArg_NoArgs(v) PyArg_Parse(v, "")
#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a))
#define PyArg_NoArgs(v) PyArg_Parse(v, "")
/* Convert a possibly signed character to a nonnegative int */
/* XXX This assumes characters are 8 bits wide */
#ifdef __CHAR_UNSIGNED__
#define Py_CHARMASK(c) (c)
#define Py_CHARMASK(c) (c)
#else
#define Py_CHARMASK(c) ((c) & 0xff)
#define Py_CHARMASK(c) ((c) & 0xff)
#endif
#include "pyfpe.h"

View File

@@ -88,7 +88,10 @@ result(X const&, short = 0) { return 0; }
/* --------------- function pointers --------------- */
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers))
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers))
# endif
# define N BOOST_PP_ITERATION()
@@ -108,7 +111,10 @@ boost::type<R>* result(R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)), int = 0)
# include BOOST_PP_ITERATE()
#elif BOOST_PP_ITERATION_DEPTH() == 2
# line BOOST_PP_LINE(__LINE__, result.hpp(pointers-to-members))
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, result.hpp(pointers-to-members))
# endif
// Inner over arities
# define N BOOST_PP_ITERATION()

View File

@@ -9,15 +9,16 @@
# ifndef SIGNATURE_DWA20021121_HPP
# define SIGNATURE_DWA20021121_HPP
# include <boost/mpl/at.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/iteration/local.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/at.hpp>
# include <boost/mpl/size.hpp>
namespace boost { namespace python { namespace detail {
@@ -33,8 +34,10 @@ template <unsigned> struct signature_arity;
(3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/signature.hpp>))
# include BOOST_PP_ITERATE()
// A metafunction returning the base class used for signature<class F,
// class ConverterGenerators, class CallPolicies, class Sig>.
// A metafunction returning the base class used for
//
// signature<class F, class CallPolicies, class Sig>.
//
template <class Sig>
struct signature_base_select
{

View File

@@ -31,7 +31,7 @@ namespace boost { namespace python { namespace detail {
# include BOOST_PP_ITERATE()
template <class R, class T>
boost::type<T*>* target(R (T::*)) { return 0; }
T& (* target(R (T::*)) )() { return 0; }
}}} // namespace boost::python::detail
@@ -39,12 +39,15 @@ boost::type<T*>* target(R (T::*)) { return 0; }
/* --------------- function pointers --------------- */
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER
# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers))
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers))
# endif
# define N BOOST_PP_ITERATION()
template <class R BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)>
boost::type<BOOST_PP_IF(N, A0, void)>* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)))
BOOST_PP_IF(N, A0, void)(* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))) )()
{
return 0;
}
@@ -59,14 +62,17 @@ boost::type<BOOST_PP_IF(N, A0, void)>* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N,
# include BOOST_PP_ITERATE()
#elif BOOST_PP_ITERATION_DEPTH() == 2
# line BOOST_PP_LINE(__LINE__, target.hpp(pointers-to-members))
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, target.hpp(pointers-to-members))
# endif
// Inner over arities
# define N BOOST_PP_ITERATION()
# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1))
template <class R, class T BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)>
boost::type<T Q*>* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q)
T& (* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) )()
{
return 0;
}

View File

@@ -13,7 +13,7 @@
# if BOOST_PYTHON_MAX_ARITY + 2 > BOOST_PYTHON_MAX_BASES
# define BOOST_PYTHON_LIST_SIZE BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY))
# else
# define BOOST_PYTHON_BASE_LIST_SIZE BOOST_PYTHON_MAX_BASES
# define BOOST_PYTHON_LIST_SIZE BOOST_PYTHON_MAX_BASES
# endif
// Compute the MPL vector header to use for lists up to BOOST_PYTHON_LIST_SIZE in length

View File

@@ -137,6 +137,24 @@ class handle
T* m_p;
};
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
} // namespace python
#endif
template<class T> inline T * get_pointer(python::handle<T> const & p)
{
return p.get();
}
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace python {
#else
// We don't want get_pointer above to hide the others
using boost::get_pointer;
#endif
typedef handle<PyTypeObject> type_handle;
//

View File

@@ -393,13 +393,13 @@ namespace detail
template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
static void apply(
ClassT& cl
, CallPoliciesT const& policies
, Signature const& args
, NArgs
, char const* doc
, detail::keyword_range const& keywords)
, CallPoliciesT const& policies
, Signature const& args
, NArgs
, char const* doc
, detail::keyword_range const& keywords)
{
def_init_aux(cl, args, NArgs(), policies, doc, keywords);
detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
}
};
}

View File

@@ -11,9 +11,13 @@
# include <boost/python/detail/target.hpp>
# include <boost/python/object/iterator.hpp>
# include <boost/python/object_core.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/bind.hpp>
# include <boost/bind/protect.hpp>
namespace boost { namespace python {
namespace detail
@@ -21,14 +25,19 @@ namespace detail
// Adds an additional layer of binding to
// objects::make_iterator(...), which allows us to pass member
// function and member data pointers.
template <class NextPolicies, class Target, class Accessor1, class Accessor2>
template <class Target, class Accessor1, class Accessor2, class NextPolicies>
inline object make_iterator(
Accessor1 get_start, Accessor2 get_finish, boost::type<Target>* target = 0, NextPolicies* = 0)
Accessor1 get_start
, Accessor2 get_finish
, NextPolicies next_policies
, Target&(*)()
)
{
return objects::make_iterator_function<NextPolicies,Target>(
return objects::make_iterator_function<Target>(
boost::protect(boost::bind(get_start, _1))
, boost::protect(boost::bind(get_finish, _1))
);
, boost::protect(boost::bind(get_finish, _1))
, next_policies
);
}
// Guts of template class iterators<>, below.
@@ -73,9 +82,11 @@ struct iterators
template <class Accessor1, class Accessor2>
object range(Accessor1 start, Accessor2 finish)
{
return detail::make_iterator<objects::default_iterator_call_policies>(
start, finish
, detail::target(start));
return detail::make_iterator(
start, finish
, objects::default_iterator_call_policies()
, detail::target(start)
);
}
// Create an iterator-building function which uses the given accessors
@@ -83,7 +94,7 @@ object range(Accessor1 start, Accessor2 finish)
template <class NextPolicies, class Accessor1, class Accessor2>
object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0)
{
return detail::make_iterator<NextPolicies>(start, finish, detail::target(start));
return detail::make_iterator(start, finish, NextPolicies(), detail::target(start));
}
// Create an iterator-building function which uses the given accessors
@@ -91,8 +102,8 @@ object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0)
template <class NextPolicies, class Target, class Accessor1, class Accessor2>
object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type<Target>* = 0)
{
typedef typename add_reference<Target>::type target;
return detail::make_iterator<NextPolicies, target>(start, finish);
// typedef typename add_reference<Target>::type target;
return detail::make_iterator(start, finish, NextPolicies(), (Target&(*)())0);
}
// A Python callable object which produces an iterator traversing

View File

@@ -38,13 +38,13 @@ class long_ : public detail::long_base
template <class T>
explicit long_(T const& rhs)
: base(object(rhs))
: detail::long_base(object(rhs))
{
}
template <class T, class U>
explicit long_(T const& rhs, U const& base)
: base(object(rhs), object(base))
: detail::long_base(object(rhs), object(base))
{
}

View File

@@ -0,0 +1,279 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef MAKE_CONSTRUCTOR_DWA20011221_HPP
# define MAKE_CONSTRUCTOR_DWA20011221_HPP
# include <boost/python/detail/prefix.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/args.hpp>
# include <boost/python/object_fwd.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/python/object/make_holder.hpp>
# include <boost/python/object/pointer_holder.hpp>
# include <boost/python/converter/context_result_converter.hpp>
# include <boost/python/detail/caller.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/int.hpp>
# include <boost/mpl/push_front.hpp>
# include <boost/mpl/pop_front.hpp>
namespace boost { namespace python {
namespace detail
{
template <class T>
struct install_holder : converter::context_result_converter
{
install_holder(PyObject* args_)
: m_self(PyTuple_GetItem(args_, 0)) {}
PyObject* operator()(T x) const
{
dispatch(x, is_pointer<T>());
return none();
}
private:
template <class U>
void dispatch(U* x, mpl::true_) const
{
std::auto_ptr<U> owner(x);
dispatch(owner, mpl::false_());
}
template <class Ptr>
void dispatch(Ptr x, mpl::false_) const
{
typedef typename pointee<Ptr>::type value_type;
typedef objects::pointer_holder<Ptr,value_type> holder;
typedef objects::instance<holder> instance_t;
void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder));
try {
(new (memory) holder(x))->install(this->m_self);
}
catch(...) {
holder::deallocate(this->m_self, memory);
throw;
}
}
PyObject* m_self;
};
struct constructor_result_converter
{
template <class T>
struct apply
{
typedef install_holder<T> type;
};
};
template <class BaseArgs, class Offset>
struct offset_args
{
offset_args(BaseArgs base_) : base(base_) {}
BaseArgs base;
};
template <int N, class BaseArgs, class Offset>
inline PyObject* get(mpl::int_<N>, offset_args<BaseArgs,Offset> const& args_)
{
return get(mpl::int_<(N+Offset::value)>(), args_.base);
}
template <class BaseArgs, class Offset>
inline unsigned arity(offset_args<BaseArgs,Offset> const& args_)
{
return arity(args_.base) - Offset::value;
}
template <class BasePolicy_ = default_call_policies>
struct constructor_policy : BasePolicy_
{
constructor_policy(BasePolicy_ base) : BasePolicy_(base) {}
// If the BasePolicy_ supplied a result converter it would be
// ignored; issue an error if it's not the default.
BOOST_STATIC_ASSERT((
is_same<
typename BasePolicy_::result_converter
, default_result_converter
>::value
));
typedef constructor_result_converter result_converter;
typedef offset_args<typename BasePolicy_::argument_package, mpl::int_<1> > argument_package;
};
template <class InnerSignature>
struct outer_constructor_signature
{
typedef typename mpl::pop_front<InnerSignature>::type inner_args;
typedef typename mpl::push_front<inner_args,object>::type outer_args;
typedef typename mpl::push_front<outer_args,void>::type type;
};
// ETI workaround
template <>
struct outer_constructor_signature<int>
{
typedef int type;
};
//
// These helper functions for make_constructor (below) do the raw work
// of constructing a Python object from some invokable entity. See
// <boost/python/detail/caller.hpp> for more information about how
// the Sig arguments is used.
//
// @group make_constructor_aux {
template <class F, class CallPolicies, class Sig>
object make_constructor_aux(
F f // An object that can be invoked by detail::invoke()
, CallPolicies const& p // CallPolicies to use in the invocation
, Sig const& // An MPL sequence of argument types expected by F
)
{
typedef typename outer_constructor_signature<Sig>::type outer_signature;
typedef constructor_policy<CallPolicies> inner_policy;
return objects::function_object(
objects::py_function(
detail::caller<F,inner_policy,Sig>(f, inner_policy(p))
, outer_signature()
)
);
}
// As above, except that it accepts argument keywords. NumKeywords
// is used only for a compile-time assertion to make sure the user
// doesn't pass more keywords than the function can accept. To
// disable all checking, pass mpl::int_<0> for NumKeywords.
template <class F, class CallPolicies, class Sig, class NumKeywords>
object make_constructor_aux(
F f
, CallPolicies const& p
, Sig const&
, detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names
, NumKeywords // An MPL integral type wrapper: the size of kw
)
{
enum { arity = mpl::size<Sig>::value - 1 };
typedef typename detail::error::more_keywords_than_function_arguments<
NumKeywords::value, arity
>::too_many_keywords assertion;
typedef typename outer_constructor_signature<Sig>::type outer_signature;
typedef constructor_policy<CallPolicies> inner_policy;
return objects::function_object(
objects::py_function(
detail::caller<F,inner_policy,Sig>(f, inner_policy(p))
, outer_signature()
)
);
}
// }
//
// These dispatch functions are used to discriminate between the
// cases when the 3rd argument is keywords or when it is a
// signature.
//
// @group Helpers for make_constructor when called with 3 arguments. {
//
template <class F, class CallPolicies, class Keywords>
object make_constructor_dispatch(F f, CallPolicies const& policies, Keywords const& kw, mpl::true_)
{
return detail::make_constructor_aux(
f
, policies
, detail::get_signature(f)
, kw.range()
, mpl::int_<Keywords::size>()
);
}
template <class F, class CallPolicies, class Signature>
object make_constructor_dispatch(F f, CallPolicies const& policies, Signature const& sig, mpl::false_)
{
return detail::make_constructor_aux(
f
, policies
, sig
);
}
// }
}
// These overloaded functions wrap a function or member function
// pointer as a Python object, using optional CallPolicies,
// Keywords, and/or Signature. @group {
//
template <class F>
object make_constructor(F f)
{
return detail::make_constructor_aux(
f,default_call_policies(), detail::get_signature(f));
}
template <class F, class CallPolicies>
object make_constructor(F f, CallPolicies const& policies)
{
return detail::make_constructor_aux(
f, policies, detail::get_signature(f));
}
template <class F, class CallPolicies, class KeywordsOrSignature>
object make_constructor(
F f
, CallPolicies const& policies
, KeywordsOrSignature const& keywords_or_signature)
{
typedef typename
detail::is_reference_to_keywords<KeywordsOrSignature&>::type
is_kw;
return detail::make_constructor_dispatch(
f
, policies
, keywords_or_signature
, is_kw()
);
}
template <class F, class CallPolicies, class Keywords, class Signature>
object make_constructor(
F f
, CallPolicies const& policies
, Keywords const& kw
, Signature const& sig
)
{
return detail::make_constructor_aux(
f
, policies
, sig
, kw.range()
, mpl::int_<Keywords::size>()
);
}
// }
}}
#endif // MAKE_CONSTRUCTOR_DWA20011221_HPP

View File

@@ -9,7 +9,7 @@
# include <boost/python/detail/prefix.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/args_fwd.hpp>
# include <boost/python/args.hpp>
# include <boost/python/detail/caller.hpp>
# include <boost/python/object/function_object.hpp>
@@ -26,17 +26,16 @@ namespace detail
// These helper functions for make_function (below) do the raw work
// of constructing a Python object from some invokable entity. See
// <boost/python/detail/caller.hpp> for more information about how
// the ConverterGenerators and Sig arguments are used.
template <class F, class CallPolicies, class ConverterGenerators, class Sig>
// the Sig arguments is used.
template <class F, class CallPolicies, class Sig>
object make_function_aux(
F f // An object that can be invoked by detail::invoke()
, CallPolicies const& p // CallPolicies to use in the invocation
, ConverterGenerators const& // An MPL iterator over a sequence of arg_from_python generators
, Sig const& // An MPL sequence of argument types expected by F
)
{
return objects::function_object(
detail::caller<F,ConverterGenerators,CallPolicies,Sig>(f, p)
detail::caller<F,CallPolicies,Sig>(f, p)
);
}
@@ -44,11 +43,10 @@ namespace detail
// is used only for a compile-time assertion to make sure the user
// doesn't pass more keywords than the function can accept. To
// disable all checking, pass mpl::int_<0> for NumKeywords.
template <class F, class CallPolicies, class ConverterGenerators, class Sig, class NumKeywords>
template <class F, class CallPolicies, class Sig, class NumKeywords>
object make_function_aux(
F f
, CallPolicies const& p
, ConverterGenerators const&
, Sig const&
, detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names
, NumKeywords // An MPL integral type wrapper: the size of kw
@@ -61,42 +59,94 @@ namespace detail
>::too_many_keywords assertion;
return objects::function_object(
detail::caller<F,ConverterGenerators,CallPolicies,Sig>(f, p)
detail::caller<F,CallPolicies,Sig>(f, p)
, kw);
}
}
// make_function --
// Helpers for make_function when called with 3 arguments. These
// dispatch functions are used to discriminate between the cases
// when the 3rd argument is keywords or when it is a signature.
//
// @group {
template <class F, class CallPolicies, class Keywords>
object make_function_dispatch(F f, CallPolicies const& policies, Keywords const& kw, mpl::true_)
{
return detail::make_function_aux(
f
, policies
, detail::get_signature(f)
, kw.range()
, mpl::int_<Keywords::size>()
);
}
template <class F, class CallPolicies, class Signature>
object make_function_dispatch(F f, CallPolicies const& policies, Signature const& sig, mpl::false_)
{
return detail::make_function_aux(
f
, policies
, sig
);
}
// }
}
// These overloaded functions wrap a function or member function
// pointer as a Python object, using optional CallPolicies,
// Keywords, and/or Signature.
//
// These overloaded functions wrap a function or member function
// pointer as a Python object, using optional CallPolicies and
// Keywords.
// @group {
template <class F>
object make_function(F f)
{
return detail::make_function_aux(
f,default_call_policies(),detail::args_from_python(), detail::get_signature(f));
f,default_call_policies(), detail::get_signature(f));
}
template <class F, class CallPolicies>
object make_function(F f, CallPolicies const& policies)
{
return detail::make_function_aux(
f,policies,detail::args_from_python(), detail::get_signature(f));
f, policies, detail::get_signature(f));
}
template <class F, class CallPolicies, class Keywords>
object make_function(F f, CallPolicies const& policies, Keywords const& keywords)
template <class F, class CallPolicies, class KeywordsOrSignature>
object make_function(
F f
, CallPolicies const& policies
, KeywordsOrSignature const& keywords_or_signature)
{
typedef typename
detail::is_reference_to_keywords<KeywordsOrSignature&>::type
is_kw;
return detail::make_function_dispatch(
f
, policies
, keywords_or_signature
, is_kw()
);
}
template <class F, class CallPolicies, class Keywords, class Signature>
object make_function(
F f
, CallPolicies const& policies
, Keywords const& kw
, Signature const& sig
)
{
return detail::make_function_aux(
f
f
, policies
, detail::args_from_python()
, detail::get_signature(f)
, keywords.range()
, sig
, kw.range()
, mpl::int_<Keywords::size>()
);
);
}
// }
}}

View File

@@ -32,7 +32,7 @@ struct BOOST_PYTHON_DECL class_base : python::api::object
// Implementation detail. Hiding this in the private section would
// require use of template friend declarations.
void enable_pickling(bool getstate_manages_dict);
void enable_pickling_(bool getstate_manages_dict);
protected:
void add_property(char const* name, object const& fget);

View File

@@ -18,6 +18,8 @@
# include <boost/mpl/for_each.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python { namespace objects {
//////////////////////////////////////////////////////////////////////
@@ -76,8 +78,9 @@ struct register_base_of
template <class Derived, class Bases>
inline void register_class_from_python(Derived* = 0, Bases* = 0)
{
python::detail::force_instantiate(converter::shared_ptr_from_python<Derived>::registration);
// Static object constructor performs registration
static converter::shared_ptr_from_python<Derived> shared_ptr_registration;
// register all up/downcasts here
register_dynamic_id<Derived>();

View File

@@ -10,7 +10,6 @@
# include <boost/python/default_call_policies.hpp>
# include <boost/python/object/py_function.hpp>
# include <boost/python/signature.hpp>
# include <boost/python/arg_from_python.hpp>
namespace boost { namespace python { namespace objects {
@@ -26,7 +25,7 @@ inline handle<> function_handle(F const& f, Signature)
return objects::function_handle_impl(
python::detail::caller<
F,python::detail::args_from_python,default_call_policies,Signature
F,default_call_policies,Signature
>(
f, default_call_policies()
)

View File

@@ -6,20 +6,26 @@
#ifndef ITERATOR_DWA2002510_HPP
# define ITERATOR_DWA2002510_HPP
# include <boost/python/object/iterator_core.hpp>
# include <boost/python/detail/prefix.hpp>
# include <boost/python/class.hpp>
# include <boost/python/object/class_detail.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/return_by_value.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/python/handle.hpp>
# include <boost/type.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/mpl/apply.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/object/iterator_core.hpp>
# include <boost/python/object/class_detail.hpp>
# include <boost/python/object/function_object.hpp>
# include <boost/mpl/vector/vector10.hpp>
# include <boost/bind.hpp>
# include <boost/bind/protect.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/detail/raw_pyobject.hpp>
# include <boost/type.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>
@@ -40,6 +46,62 @@ struct iterator_range
{
iterator_range(object sequence, Iterator start, Iterator finish);
typedef boost::detail::iterator_traits<Iterator> traits_t;
struct next
{
typedef typename mpl::if_<
is_reference<
typename traits_t::reference
>
, typename traits_t::reference
, typename traits_t::value_type
>::type result_type;
result_type
operator()(iterator_range<NextPolicies,Iterator>& self)
{
if (self.m_start == self.m_finish)
stop_iteration_error();
return *self.m_start++;
}
# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
// CWPro8 has a codegen problem when this is an empty class
int garbage;
# endif
};
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// for compilers which can't deduce the value_type of pointers, we
// have a special implementation of next. This takes advantage of
// the fact that T* results are treated like T& results by
// Boost.Python's function wrappers.
struct next_ptr
{
typedef Iterator result_type;
result_type
operator()(iterator_range<NextPolicies,Iterator>& self)
{
if (self.m_start == self.m_finish)
stop_iteration_error();
return self.m_start++;
}
};
typedef mpl::if_<
is_same<
boost::detail::please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<Iterator>
, typename traits_t::value_type
>
, next_ptr
, next
>::type next_fn;
# else
typedef next next_fn;
# endif
object m_sequence; // Keeps the sequence alive while iterating.
Iterator m_start;
Iterator m_finish;
@@ -47,62 +109,6 @@ struct iterator_range
namespace detail
{
// Guts of the iterator's next() function. We can't just wrap an
// ordinary function because we don't neccessarily know the result
// type of dereferencing the iterator. This also saves us from
// throwing C++ exceptions to indicate end-of-sequence.
template <class Iterator, class Policies>
struct iterator_next
{
static PyObject* execute(PyObject* args_, PyObject* kw, Policies const& policies)
{
typedef iterator_range<Policies,Iterator> range_;
PyObject* py_self = PyTuple_GET_ITEM(args_, 0);
arg_from_python<range_*> c0(py_self);
range_* self = c0(py_self);
// Done iterating?
if (self->m_start == self->m_finish)
{
objects::set_stop_iteration_error();
return 0;
}
// note: precall happens before we can check for the result
// converter in this case, to ensure it happens before the
// iterator is dereferenced. However, the arity is 1 so
// there's not much risk that this will amount to anything.
if (!policies.precall(args_)) return 0;
PyObject* result = iterator_next::convert_result(*self->m_start);
++self->m_start;
return policies.postcall(args_, result);
}
private:
// Convert the result of dereferencing the iterator. Dispatched
// here because we can't neccessarily get the value_type of the
// iterator without PTS. This way, we deduce the value type by
// dereferencing.
template <class ValueType>
static PyObject* convert_result(ValueType& x)
{
typedef typename Policies::result_converter result_converter;
typename mpl::apply1<result_converter,ValueType&>::type cr;
return cr(x);
}
template <class ValueType>
static PyObject* convert_result(ValueType const& x)
{
typedef typename Policies::result_converter result_converter;
typename mpl::apply1<result_converter,ValueType const&>::type cr;
return cr(x);
}
};
// Get a Python class which contains the given iterator and
// policies, creating it if neccessary. Requires: NextPolicies is
// default-constructible.
@@ -118,93 +124,90 @@ namespace detail
if (class_obj.get() != 0)
return object(class_obj);
// Make a callable object which can be used as the iterator's next() function.
object next_function =
objects::function_object(
py_function(
bind(&detail::iterator_next<Iterator,NextPolicies>::execute, _1, _2, policies)
, mpl::vector2<
# if defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
object
# else
typename boost::detail::iterator_traits<Iterator>::value_type
# endif
, Iterator
>()
)
);
typedef typename range_::next_fn next_fn;
typedef typename next_fn::result_type result_type;
return class_<range_>(name, no_init)
.def("__iter__", identity_function())
.setattr("next", next_function)
;
.def(
"next"
, make_function(
next_fn()
, policies
, mpl::vector2<result_type,range_&>()
));
}
// This class template acts as a generator for an ordinary function
// which builds a Python iterator.
template <class Target, class Iterator
, class Accessor1, class Accessor2
, class NextPolicies
>
struct make_iterator_help
// A function object which builds an iterator_range.
template <
class Target
, class Iterator
, class Accessor1
, class Accessor2
, class NextPolicies
>
struct py_iter_
{
py_iter_(Accessor1 const& get_start, Accessor2 const& get_finish)
: m_get_start(get_start)
, m_get_finish(get_finish)
{}
// Extract an object x of the Target type from the first Python
// argument, and invoke get_start(x)/get_finish(x) to produce
// iterators, which are used to construct a new iterator_range<>
// object that gets wrapped into a Python iterator.
static PyObject* create(
Accessor1 const& get_start, Accessor2 const& get_finish
, PyObject* args_, PyObject* /*kw*/)
iterator_range<NextPolicies,Iterator>
operator()(back_reference<Target&> x) const
{
// Make sure the Python class is instantiated.
detail::demand_iterator_class("iterator", (Iterator*)0, NextPolicies());
to_python_value<iterator_range<NextPolicies,Iterator> > cr;
// Extract x from the first argument
PyObject* arg0 = PyTuple_GET_ITEM(args_, 0);
arg_from_python<Target> c0(arg0);
if (!c0.convertible()) return 0;
typename arg_from_python<Target>::result_type x = c0(arg0);
// Build and convert the iterator_range<>.
return cr(
iterator_range<NextPolicies,Iterator>(
object((python::detail::borrowed_reference)arg0)
, get_start(x), get_finish(x)));
return iterator_range<NextPolicies,Iterator>(
x.source()
, m_get_start(x.get())
, m_get_finish(x.get())
);
}
private:
Accessor1 m_get_start;
Accessor2 m_get_finish;
};
template <class NextPolicies, class Target, class Iterator, class Accessor1, class Accessor2>
template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
inline object make_iterator_function(
Accessor1 const& get_start
, Accessor2 const& get_finish
, NextPolicies const& next_policies
, Iterator const& (*)()
, boost::type<Target>*
, NextPolicies*
, int
)
{
return
objects::function_object(
py_function(
boost::bind(
&make_iterator_help<
Target,Iterator,Accessor1,Accessor2,NextPolicies
>::create
, get_start, get_finish, _1, _2)
, mpl::vector2<object, Target>()
)
);
return make_function(
py_iter_<Target,Iterator,Accessor1,Accessor2,NextPolicies>(get_start, get_finish)
, default_call_policies()
, mpl::vector2<iterator_range<NextPolicies,Iterator>, back_reference<Target&> >()
);
}
template <class NextPolicies, class Target, class Iterator, class Accessor1, class Accessor2>
template <class Target, class Iterator, class NextPolicies, class Accessor1, class Accessor2>
inline object make_iterator_function(
Accessor1 const& get_start, Accessor2 const& get_finish, Iterator& (*)(), boost::type<Target>*, NextPolicies*, ...)
Accessor1 const& get_start
, Accessor2 const& get_finish
, NextPolicies const& next_policies
, Iterator& (*)()
, boost::type<Target>*
, ...)
{
return make_iterator_function(
get_start, get_finish, (Iterator const&(*)())0
, (boost::type<Target>*)0, (NextPolicies*)0, 0);
get_start
, get_finish
, next_policies
, (Iterator const&(*)())0
, (boost::type<Target>*)0
, 0
);
}
}
@@ -215,22 +218,26 @@ namespace detail
// (where x is an instance of Target) to produce begin and end
// iterators for the range, and an instance of NextPolicies is used as
// CallPolicies for the Python iterator's next() function.
template <class NextPolicies, class Target, class Accessor1, class Accessor2>
template <class Target, class NextPolicies, class Accessor1, class Accessor2>
inline object make_iterator_function(
Accessor1 const& get_start, Accessor2 const& get_finish
, boost::type<Target>* = 0, NextPolicies* = 0)
Accessor1 const& get_start
, Accessor2 const& get_finish
, NextPolicies const& next_policies
, boost::type<Target>* = 0
)
{
typedef typename Accessor1::result_type iterator;
typedef typename add_const<iterator>::type iterator_const;
typedef typename add_reference<iterator_const>::type iterator_cref;
return detail::make_iterator_function(
get_start, get_finish
, (iterator_cref(*)())0
, (boost::type<Target>*)0
, (NextPolicies*)0
, 0
);
get_start
, get_finish
, next_policies
, (iterator_cref(*)())0
, (boost::type<Target>*)0
, 0
);
}
//

View File

@@ -11,7 +11,7 @@
namespace boost { namespace python { namespace objects {
BOOST_PYTHON_DECL object const& identity_function();
BOOST_PYTHON_DECL void set_stop_iteration_error();
BOOST_PYTHON_DECL void stop_iteration_error();
}}} // namespace boost::python::object

View File

@@ -45,7 +45,10 @@ template <int nargs> struct make_holder;
# endif // MAKE_HOLDER_DWA20011215_HPP
#elif BOOST_PP_ITERATION_DEPTH() == 1
# line BOOST_PP_LINE(__LINE__, make_holder.hpp)
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, make_holder.hpp)
# endif
# define N BOOST_PP_ITERATION()

View File

@@ -26,8 +26,8 @@ struct make_instance_impl
PyTypeObject* type = Derived::get_class_object(x);
if (type == 0)
return python::detail::none();
if (type == 0)
return python::detail::none();
PyObject* raw_result = type->tp_alloc(
type, objects::additional_instance_size<Holder>::value);

View File

@@ -10,6 +10,7 @@
# include <boost/python/converter/registry.hpp>
# include <boost/type_traits/is_polymorphic.hpp>
# include <boost/get_pointer.hpp>
# include <boost/detail/workaround.hpp>
# include <typeinfo>
namespace boost { namespace python { namespace objects {
@@ -34,8 +35,8 @@ struct make_ptr_instance
template <class U>
static inline PyTypeObject* get_class_object_impl(U const volatile* p)
{
if (p == 0)
return 0; // means "return None".
if (p == 0)
return 0; // means "return None".
PyTypeObject* derived = get_derived_class_object(
BOOST_DEDUCED_TYPENAME is_polymorphic<U>::type(), p);
@@ -48,19 +49,15 @@ struct make_ptr_instance
template <class U>
static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x)
{
converter::registration const* r = converter::registry::query(type_info(typeid(*x)));
converter::registration const* r = converter::registry::query(
type_info(typeid(*get_pointer(x)))
);
return r ? r->m_class_object : 0;
}
template <class U>
static inline PyTypeObject* get_derived_class_object(mpl::false_, U* x)
static inline PyTypeObject* get_derived_class_object(mpl::false_, U*)
{
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
if (typeid(*x) != typeid(U))
return get_derived_class_object(mpl::true_(), x);
# else
(void)x;
# endif
return 0;
}
};

View File

@@ -59,7 +59,7 @@ namespace detail {
inaccessible* (*setstate_fn)(),
bool)
{
cl.enable_pickling(false);
cl.enable_pickling_(false);
cl.def("__getinitargs__", getinitargs_fn);
}
@@ -75,7 +75,7 @@ namespace detail {
void (*setstate_fn)(Tsetstate, Ttuple),
bool getstate_manages_dict)
{
cl.enable_pickling(getstate_manages_dict);
cl.enable_pickling_(getstate_manages_dict);
cl.def("__getstate__", getstate_fn);
cl.def("__setstate__", setstate_fn);
}
@@ -93,7 +93,7 @@ namespace detail {
void (*setstate_fn)(Tsetstate, Ttuple),
bool getstate_manages_dict)
{
cl.enable_pickling(getstate_manages_dict);
cl.enable_pickling_(getstate_manages_dict);
cl.def("__getinitargs__", getinitargs_fn);
cl.def("__getstate__", getstate_fn);
cl.def("__setstate__", setstate_fn);

View File

@@ -9,6 +9,7 @@
# ifndef POINTER_HOLDER_DWA20011215_HPP
# define POINTER_HOLDER_DWA20011215_HPP
# include <boost/get_pointer.hpp>
# include <boost/type.hpp>
# include <boost/python/instance_holder.hpp>
@@ -29,20 +30,10 @@
# include <boost/preprocessor/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python { namespace objects {
template <class T>
bool is_null(T const& p, ...)
{
return p.get() == 0;
}
template <class T>
bool is_null(T* p, int)
{
return p == 0;
}
# if BOOST_WORKAROUND(__GNUC__, == 2)
# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward<A##n>::type)objects::do_unforward(a##n,0)
# else
@@ -113,11 +104,11 @@ void* pointer_holder<Pointer, Value>::holds(type_info dst_t)
if (dst_t == python::type_id<Pointer>())
return &this->m_p;
if (objects::is_null(this->m_p, 0))
Value* p = get_pointer(this->m_p);
if (p == 0)
return 0;
type_info src_t = python::type_id<Value>();
Value* p = &*this->m_p;
return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
}
@@ -127,14 +118,15 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t)
if (dst_t == python::type_id<Pointer>())
return &this->m_p;
if (objects::is_null(this->m_p, 0))
if (!get_pointer(this->m_p))
return 0;
Value* p = get_pointer(m_p);
if (dst_t == python::type_id<held_type>())
return &*this->m_p;
return p;
type_info src_t = python::type_id<Value>();
Value* p = &*this->m_p;
return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t);
}
@@ -144,7 +136,10 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t)
/* --------------- pointer_holder --------------- */
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp)
# endif
# define N BOOST_PP_ITERATION()
@@ -161,7 +156,10 @@ void* pointer_holder_back_reference<Pointer, Value>::holds(type_info dst_t)
/* --------------- pointer_holder_back_reference --------------- */
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp(pointer_holder_back_reference))
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp(pointer_holder_back_reference))
# endif
# define N BOOST_PP_ITERATION()

View File

@@ -103,7 +103,10 @@ void* value_holder_back_reference<Value,Held>::holds(
// --------------- value_holder ---------------
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1
# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder))
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder))
# endif
# define N BOOST_PP_ITERATION()
@@ -122,7 +125,10 @@ void* value_holder_back_reference<Value,Held>::holds(
// --------------- value_holder_back_reference ---------------
#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2
# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder_back_reference))
# if !(BOOST_WORKAROUND(__MWERKS__, > 0x3100) \
&& BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))
# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder_back_reference))
# endif
# define N BOOST_PP_ITERATION()

View File

@@ -13,7 +13,6 @@
# include <boost/python/call.hpp>
# include <boost/python/handle_fwd.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/slice_nil.hpp>
# include <boost/python/refcount.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/tag.hpp>
@@ -63,6 +62,7 @@ namespace api
struct item_policies;
struct const_slice_policies;
struct slice_policies;
class slice_nil;
typedef proxy<const_attribute_policies> const_object_attribute;
typedef proxy<attribute_policies> object_attribute;
@@ -146,6 +146,9 @@ namespace api
const_object_slice slice(object_cref, slice_nil) const;
object_slice slice(object_cref, slice_nil);
const_object_slice slice(slice_nil, slice_nil) const;
object_slice slice(slice_nil, slice_nil);
template <class T, class V>
const_object_slice
slice(T const& start, V const& end) const
@@ -280,7 +283,7 @@ namespace api
return object_initializer<
BOOST_DEDUCED_TYPENAME unwrap_reference<T>::type
>::get(
api::do_unforward_cref(x)
x
, is_obj()
);
}
@@ -468,4 +471,6 @@ inline PyObject* get_managed_object(object const& x, tag_t)
}} // namespace boost::python
# include <boost/python/slice_nil.hpp>
#endif // OBJECT_CORE_DWA2002615_HPP

View File

@@ -17,29 +17,28 @@
namespace boost { namespace python { namespace api {
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
template <class X> char
is_object_operators_helper(object_operators<X> const&);
template <class X>
char is_object_operators_helper(object_operators<X> const*);
typedef char (&no_type)[2];
no_type is_object_operators_helper(...);
template <class X> X& make();
template <class X> X* make_ptr();
template <class L, class R>
template <class L, class R = L>
struct is_object_operators
{
enum {
value
= (sizeof(api::is_object_operators_helper(api::make<L>()))
+ sizeof(api::is_object_operators_helper(api::make<R>()))
= (sizeof(api::is_object_operators_helper(api::make_ptr<L>()))
+ sizeof(api::is_object_operators_helper(api::make_ptr<R>()))
< 4
)
};
typedef mpl::bool_<value> type;
};
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
template <class L, class R, class T>
struct enable_binary
: boost::iterators::enable_if<is_object_operators<L,R>, T>

View File

@@ -63,6 +63,22 @@ object_operators<U>::slice(slice_nil, object_cref finish) const
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr())));
}
template <class U>
object_slice
object_operators<U>::slice(slice_nil, slice_nil)
{
object_cref2 x = *static_cast<U*>(this);
return object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
}
template <class U>
const_object_slice
object_operators<U>::slice(slice_nil, slice_nil) const
{
object_cref2 x = *static_cast<U const*>(this);
return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), allow_null((PyObject*)0)));
}
template <class U>
object_slice
object_operators<U>::slice(object_cref start, slice_nil)

View File

@@ -133,4 +133,4 @@ PyTypeObject opaque_pointer_converter<Pointer>::type_object =
} \
}}
# endif
# endif // OPAQUE_POINTER_CONVERTER_HPP_
# endif // OPAQUE_POINTER_CONVERTER_HPP_

View File

@@ -334,6 +334,7 @@ BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)

View File

@@ -8,7 +8,6 @@
# include <boost/python/def_visitor.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/arg_from_python.hpp>
# include <boost/mpl/push_front.hpp>
# include <boost/mpl/pop_front.hpp>
@@ -19,7 +18,7 @@ namespace boost { namespace python {
namespace detail
{
//
// { Helpers for pure_virtual_visitor, below.
// @group Helpers for pure_virtual_visitor. {
//
// Raises a Python RuntimeError reporting that a pure virtual
@@ -44,9 +43,9 @@ namespace detail
>::type type;
};
// Given an MPL sequence representing a signature, returns a new MPL
// sequence whose return type is replaced by void, and whose first
// argument is replaced by C&.
// Given an MPL sequence representing a member function [object]
// signature, returns a new MPL sequence whose return type is
// replaced by void, and whose first argument is replaced by C&.
template <class C, class S>
typename replace_front2<S,void,C&>::type
error_signature(S BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(C))
@@ -56,7 +55,7 @@ namespace detail
}
//
// } Helpers for pure_virtual_visitor
// }
//
//
@@ -97,10 +96,9 @@ namespace detail
// Add the default implementation which raises the exception
c.def(
name
, detail::make_function_aux(
, make_function(
detail::nullary_function_adaptor<void(*)()>(pure_virtual_called)
, default_call_policies()
, args_from_python()
, detail::error_signature<held_t>(detail::get_signature(m_pmf))
)
);

View File

@@ -7,10 +7,15 @@
# define RETURN_ARG_DWA2003719_HPP
# include <boost/python/default_call_policies.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/mpl/int.hpp>
# include <boost/static_assert.hpp>
# include <boost/python/refcount.hpp>
# include <cstddef>
namespace boost { namespace python {
@@ -67,8 +72,20 @@ struct return_arg : Base
// think it is better to issue an error instead, cause it can
// lead to confusions
>::type result_converter;
static PyObject* postcall(PyObject *args, PyObject* result);
template <class ArgumentPackage>
static PyObject* postcall(ArgumentPackage const& args, PyObject* result)
{
// In case of arg_pos == 0 we could simply return Base::postcall,
// but this is redundant
BOOST_STATIC_ASSERT(arg_pos > 0);
result = Base::postcall(args,result);
if (!result)
return 0;
Py_DECREF(result);
return incref( detail::get(mpl::int_<arg_pos-1>(),args) );
}
};
template <
@@ -78,23 +95,6 @@ struct return_self
: return_arg<1,Base>
{};
template <size_t arg_pos, class Base>
inline PyObject*
return_arg<arg_pos, Base>::postcall(PyObject *args, PyObject* result)
{
// In case of arg_pos == 0 we could simply return Base::postcall,
// but this is redundant
BOOST_STATIC_ASSERT(arg_pos > 0);
handle<> base_result(Base::postcall(args,result));
if(!base_result)
return 0;
return incref(PyTuple_GetItem(args,arg_pos-1));
}
}} // namespace boost::python
#endif // RETURN_ARG_DWA2003719_HPP

Some files were not shown because too many files have changed in this diff Show More