2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 17:32:55 +00:00

Compare commits

..

47 Commits

Author SHA1 Message Date
nobody
6a08750b23 This commit was manufactured by cvs2svn to create tag
'Version_1_30_2'.

[SVN r19685]
2003-08-18 18:40:31 +00:00
Dave Abrahams
ec0d1a6abc Updates for Boost 1.30.1
[SVN r19440]
2003-08-04 17:38:10 +00:00
Dave Abrahams
66f0c80336 Added Python 2.3 note.
[SVN r19438]
2003-08-04 17:01:29 +00:00
Dave Abrahams
9fa3d5c892 Backport bugfix from trunk
[SVN r19362]
2003-07-30 12:20:30 +00:00
nobody
97c0167660 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r19146]
2003-07-16 10:53:07 +00:00
Dave Abrahams
f249fc9919 unused variable warning patch
[SVN r19130]
2003-07-15 19:35:14 +00:00
Dave Abrahams
8678283629 merged from trunk
[SVN r18264]
2003-04-16 14:32:58 +00:00
Dave Abrahams
88e7049a5b merged from trunk
[SVN r18054]
2003-03-22 17:29:34 +00:00
Dave Abrahams
955f716108 fix typo
[SVN r18025]
2003-03-20 02:53:47 +00:00
Ralf W. Grosse-Kunstleve
9178b9e6cc pyconfig.h included first only under Tru64/cxx
[SVN r18022]
2003-03-20 00:27:16 +00:00
Ralf W. Grosse-Kunstleve
6f0b083a51 restore Codewarrior builds
[SVN r17998]
2003-03-19 07:04:07 +00:00
Bruno da Silva de Oliveira
574e6b9e2c - Updated to reflect changes in declarations.py
[SVN r17997]
2003-03-19 05:55:28 +00:00
nobody
5bfc1e080d This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17996]
2003-03-19 05:54:27 +00:00
Bruno da Silva de Oliveira
d475fcaf7d - Fixed bug where the PointerDeclaration of functions and methods didn't have the & operator
[SVN r17994]
2003-03-19 05:03:49 +00:00
Bruno da Silva de Oliveira
85f324efb6 - Unit tests for the examples
[SVN r17992]
2003-03-19 03:08:53 +00:00
Bruno da Silva de Oliveira
08254b1fe7 - Fixed bug where an union that was a class member crashed pyste (unions are still not exported)
- Added support for int, double, float and long operators


[SVN r17991]
2003-03-19 02:57:31 +00:00
Bruno da Silva de Oliveira
d4b1b46e63 - Unit tests for the examples
[SVN r17990]
2003-03-19 02:55:30 +00:00
nobody
08f07b0cc6 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17988]
2003-03-19 02:47:30 +00:00
Ralf W. Grosse-Kunstleve
2d0e0759c7 special code only for gcc <= 2.96
[SVN r17986]
2003-03-19 02:40:15 +00:00
Ralf W. Grosse-Kunstleve
130de54f23 fix for Visual C++ >= 7.1 as per David Abrahams
[SVN r17978]
2003-03-18 22:31:12 +00:00
Ralf W. Grosse-Kunstleve
3068b4ae13 gcc 2.96 compatibility
[SVN r17977]
2003-03-18 20:57:46 +00:00
Dave Abrahams
5867b87b60 Add funcptr FAQ
[SVN r17974]
2003-03-18 14:40:09 +00:00
Bruno da Silva de Oliveira
87953ae423 - Fixed bugs in Linux
[SVN r17969]
2003-03-18 05:16:01 +00:00
Bruno da Silva de Oliveira
eb252c0395 - Fixed bug where the permission bits were being copied to the tmp file
[SVN r17934]
2003-03-15 02:51:51 +00:00
nobody
2c0ec733ca This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17932]
2003-03-14 23:39:05 +00:00
Bruno da Silva de Oliveira
13df532aca - Fixed definition of private default implementations
[SVN r17930]
2003-03-14 23:36:44 +00:00
Bruno da Silva de Oliveira
c8747f6893 - Now generating wrappers for protected and private virtual methods
[SVN r17927]
2003-03-14 21:43:33 +00:00
nobody
69b9094dfc This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17902]
2003-03-14 02:49:25 +00:00
Bruno da Silva de Oliveira
5788cc83f3 no message
[SVN r17874]
2003-03-13 00:58:17 +00:00
Ralf W. Grosse-Kunstleve
0262c3bba9 adjustment for MIPSpro
[SVN r17864]
2003-03-12 22:59:46 +00:00
nobody
d6dd4e48e2 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17843]
2003-03-12 13:51:19 +00:00
Dave Abrahams
b58503707f opaque pointer conversions from Gottfried.Ganssauge@haufe.de
Acknowledgements for all


[SVN r17839]
2003-03-12 13:38:18 +00:00
nobody
8c1a826ce8 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17837]
2003-03-12 13:29:13 +00:00
Bruno da Silva de Oliveira
cc76f068ee - first RC version
[SVN r17827]
2003-03-12 03:40:44 +00:00
nobody
4efab432ab This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17826]
2003-03-12 01:39:29 +00:00
Ralf W. Grosse-Kunstleve
13b1f434ad pyconfig.h must be included before any system header (as per Python docs; essential for Python 2.3 under Tru64 Unix)
[SVN r17799]
2003-03-10 17:25:52 +00:00
Ralf W. Grosse-Kunstleve
c29241d859 non-template function make_function1 must be inline
[SVN r17791]
2003-03-09 17:26:06 +00:00
Dave Abrahams
fbe3d080e8 Fix for older EDGs
[SVN r17786]
2003-03-08 12:36:18 +00:00
Dave Abrahams
be96a3c4d6 Remove flotsam
[SVN r17783]
2003-03-08 08:53:19 +00:00
Dave Abrahams
70a967bac5 Remove flotsam
[SVN r17782]
2003-03-08 08:51:45 +00:00
Ralf W. Grosse-Kunstleve
a7ce37effa missing raw_function.hpp added; struct is_reference_to_class definition moved up
[SVN r17781]
2003-03-08 08:44:38 +00:00
Dave Abrahams
87c92775c9 Fix for Python 2.3 long->int conversion behavior change
[SVN r17779]
2003-03-08 05:28:54 +00:00
nobody
a15f7d5bf3 This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17778]
2003-03-08 03:53:20 +00:00
Dave Abrahams
a870ce20fc Added dangling_reference FAQ
Various idiomatic MPL cleanups in indirect_traits.hpp
raw_function support
Patches for CWPro7.2
Patches to pass tests under Python 2.3 with the new bool type.
Tests for member operators returning const objects
Fixes for testing Boost.Python under Cygwin


[SVN r17777]
2003-03-08 03:53:19 +00:00
Ralf W. Grosse-Kunstleve
e042228f45 MIPSpro compatibility
[SVN r17776]
2003-03-08 01:47:40 +00:00
Dave Abrahams
7c4cfe0589 Workaround for vc7 bug
[SVN r17709]
2003-03-03 17:24:07 +00:00
nobody
e24497a6cd This commit was manufactured by cvs2svn to create branch 'RC_1_30_0'.
[SVN r17693]
2003-03-01 19:43:06 +00:00
507 changed files with 18848 additions and 20605 deletions

View File

@@ -10,7 +10,8 @@
subproject libs/python/build ;
# bring in the rules for python
import python ;
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
if [ check-python-config ]
{
@@ -52,8 +53,6 @@ if [ check-python-config ]
object/iterator.cpp
object_protocol.cpp
object_operators.cpp
indexing/slice.cpp
indexing/python_iterator.cpp
;
dll boost_python
@@ -64,11 +63,6 @@ if [ check-python-config ]
<msvc-stlport><release>$(msvc-stlport-workarounds)
;
template extension
: <dll>boost_python
: <sysinclude>../../..
;
lib boost_python
: # sources
../src/$(sources)

View File

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

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
"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">
@@ -39,22 +39,25 @@
<dl class="index">
<dt><a href="#configuration">Configuration</a></dt>
<dt><a href="#cygwin_configuration">Configuration for Cygwin GCC
from a Windows prompt</a></dt>
<dt><a href="#results">Results</a></dt>
<dt><a href="#cygwin">Notes for Cygwin GCC Users</a></dt>
<dt><a href="#mingw">Notes for MinGW (and Cygwin with -mno-cygwin)
GCC Users</a></dt>
<dt><a href="#testing">Testing</a></dt>
</dl>
</dd>
<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
@@ -74,7 +77,7 @@
<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.Python extension modules are used
library, but if multiple Boost.Pythone extension modules are used
together, it will prevent sharing of types across extension modules, and
consume extra code space. To build <code>boost_python</code>, use <a
href="../../../tools/build/index.html">Boost.Build</a> in the usual way
@@ -82,7 +85,7 @@
installation (if you have already built boost from the top level this may
have no effect, since the work is already done).</p>
<h3><a name="configuration">Basic Configuration</a></h3>
<h3><a name="configuration">Configuration</a></h3>
You may need to configure the following variables to point Boost.Build at
your Python installation:
@@ -125,8 +128,7 @@
<td>path to Python <code>#include</code> directories</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code>. Try the default
before attempting to set it yourself.</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
@@ -134,50 +136,37 @@
<td>path to Python library object.</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code>. Try the default
before attempting to set it yourself.</td>
</tr>
</table>
<h3><a name="cygwin_configuration">Configuration for Cygwin GCC from a
Windows prompt</a></h3>
The following settings may be useful when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC (not MinGW) from a Windows command
shell using a Windows build of <code>bjam</code>. <b>If
"<code>bjam&nbsp;-v</code>" does not report "<code>OS=NT</code>", these
settings do not apply to you</b>; you should use the <a href=
"#configuration">normal configuration</a> variables instead. They are
only useful when building and testing with multiple toolsets on Windows
using a single build command, since Cygwin GCC requires a different build
of Python.
<table border="1" summary=
"Cygwin GCC under NT build configuration variables">
<tr>
<th>Variable Name</th>
<th>Semantics</th>
<th>Default</th>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]VERSION</code></td>
<td>The version of python being used under Cygwin.</td>
<td>The version of python being used under Cygwin. </td>
<td>$(PYTHON_VERSION)</td>
</tr>
<td>$(PYTHON_VERSION)
</td>
<td>Use only when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC. This and the following
settings are useful when building with multiple toolsets on
Windows, since Cygwin GCC requires a different build of
Python.</td> </tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]ROOT</code></td>
<td>unix-style path containing the <code>include/</code> directory
containing
<code>python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h</code>.</td>
<td>unix-style path containing the <code>include/</code>
directory containing
<code>python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h</code>. </td>
<td>$(PYTHON_ROOT)</td>
</tr>
<td>$(PYTHON_ROOT)
</td>
<td>Use only when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC.</td> </tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]LIB_PATH</code></td>
@@ -186,7 +175,9 @@
<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.a</code></td>
<td>Autoconfigured from <code>CYGWIN_PYTHON_ROOT</code></td>
</tr>
<td>Use only when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC.</td> </tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]DLL_PATH</code></td>
@@ -195,6 +186,10 @@
(<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll</code>)</td>
<td><code>/bin</code></td>
<td>Use only when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC.</td> </tr>
</tr>
</table>
@@ -211,23 +206,10 @@
"http://www.python.org/download/download_source.html">Unix installation
process</a> to build Python from source.</p>
<p>The special build configuration variables listed <a href=
"#cygwin_configuration">above</a> make it possible to use a regular Win32
build of bjam to build and test Boost.Python and Boost.Python extensions
using Cygwin GCC and targeting a Cygwin build of Python.</p>
<h3><a name="mingw">Notes for MinGW (and Cygwin with -mno-cygwin) GCC
Users</a></h3>
<p>You will need to create a MinGW-compatible version of the Python
library; the one shipped with Python will only work with a
Microsoft-compatible linker. Follow the instructions in the
"Non-Microsoft" section of the "Building Extensions: Tips And Tricks"
chapter in <a href=
"http://www.python.org/doc/current/inst/index.html">Installing Python
Modules</a> to create <code>libpythonXX.a</code>, where <code>XX</code>
corresponds to the major and minor version numbers of your Python
installation.</p>
<p>The special build configuration variables listed above as "Cygwin
only" make it possible to use a regular Win32 build of bjam to build and
test Boost.Python and Boost.Python extensions using Cygwin GCC and
targeting a Cygwin build of Python.</p>
<h3><a name="results">Results</a></h3>
@@ -266,49 +248,45 @@ bjam -sTOOLS=<i><a href=
passes.
<h2><a name="building_ext">Building your Extension Module</a></h2>
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
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
"<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.
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:
<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:
<ol>
<li><code><a
href="../example/boost-build.jam"><b>boost-build.jam</b></a></code> -
edit the line which reads
<ol>
<li>Create a new subdirectory in, <code>libs/python</code>, say
<code>libs/python/my_project</code>.</li>
<blockquote>
<pre>
boost-build ../../../tools/build ;
</pre>
</blockquote>
<li>Copy <code><a href=
"../example/Jamfile">libs/python/example/Jamfile</a></code> to your new
directory.</li>
so that the path refers to the <code>tools/build</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>
<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>
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>

View File

@@ -61,9 +61,25 @@
href="http://www.llnl.gov/">Lawrence Livermore National Laboratories</a>
and by the <a href="http://cci.lbl.gov/">Computational Crystallography
Initiative</a> at Lawrence Berkeley National Laboratories.
<hr>
<h2>Note for Python 2.3 users</h2>
This is a bugfix release only, and is <b>not</b> compatible with
Python 2.3. Boost 1.31.0, which will be compatible with Python
2.3, is due out shortly. In the meantime, if you need Python 2.3
compatibility, we suggest you get a CVS snapshot, either from the
<a href="../../../more/download.html#CVS">SourceForge anonymous
CVS</a> or from our mirror, updated nightly:
<pre>
cvs -d :pserver:anonymous@boost-consulting.com:/boost login
<i>no password; just hit return</i>
cvs -d :pserver:anonymous@boost-consulting.com:/boost co boost
</pre>
<hr>
<h2>Contents</h2>
<dl class="index">
@@ -88,34 +104,22 @@
<dt><a href="../pyste/index.html">Pyste (Boost.Python code generator)</a></dt>
<dt><a href="internals.html">Internals Documentation</a></dt>
<dt><a href="news.html">News/Change Log</a></dt>
<dt><a href="../todo.html">TODO list</a></dt>
<dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
<dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
<dt><a href="v2/acknowledgments.html">Acknowledgments</a></dt>
</dl>
<hr>
<h2>Articles</h2>
&quot;<a href="PyConDC_2003/bpl.html">Building Hybrid
Systems With Boost Python</a>&quot;, by Dave Abrahams and Ralf
W. Grosse-Kunstleve (<a href="PyConDC_2003/bpl.pdf">PDF</a>)
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
26 August, 2003
4 August, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
Abrahams</a> 2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,186 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
<title>Boost.Python Internals Boost</title>
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="boost-python-internals-logo">
<h1 class="title"><a class="reference" href="index.html">Boost.Python</a> Internals <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../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 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">license</a> for terms of use.</td>
</tr>
</tbody>
</table>
<p>In both of these cases, I'm quite capable of reading code - but the
thing I don't get from scanning the source is a sense of the
architecture, both structurally, and temporally (er, I mean in what
order things go on).</p>
<ol class="arabic">
<li><p class="first">What happens when you do the following:</p>
<pre class="literal-block">
struct boring {};
...etc...
class_&lt;boring&gt;(&quot;boring&quot;)
;
</pre>
</li>
</ol>
<p>There seems to be a fair bit going on.</p>
<blockquote>
<ul class="simple">
<li>Python needs a new ClassType to be registered.</li>
<li>We need to construct a new type that can hold our boring struct.</li>
<li>Inward and outward converters need to be registered for the type.</li>
</ul>
</blockquote>
<p>Can you gesture in the general direction where these things are done?</p>
<blockquote>
<p>I only have time for a &quot;off-the-top-of-my-head&quot; answer at the moment;
I suggest you step through the code with a debugger after reading this
to see how it works, fill in details, and make sure I didn't forget
anything.</p>
<blockquote>
<p>A new (Python) subclass of Boost.Python.Instance (see
libs/python/src/object/class.cpp) is created by invoking
Boost.Python.class, the metatype:</p>
<pre class="literal-block">
&gt;&gt;&gt; boring = Boost.Python.class(
... 'boring'
... , bases_tuple # in this case, just ()
... , {
... '__module__' : module_name
... , '__doc__' : doc_string # optional
... }
... )
</pre>
<p>A handle to this object is stuck in the m_class_object field
of the registration associated with <tt class="literal"><span class="pre">typeid(boring)</span></tt>. The
registry will keep that object alive forever, even if you
wipe out the 'boring' attribute of the extension module
(probably not a good thing).</p>
<p>Because you didn't specify <tt class="literal"><span class="pre">class&lt;boring,</span> <span class="pre">non_copyable,</span>
<span class="pre">...&gt;</span></tt>, a to-python converter for boring is registered which
copies its argument into a value_holder held by the the
Python boring object.</p>
<p>Because you didn't specify <tt class="literal"><span class="pre">class&lt;boring</span> <span class="pre">...&gt;(no_init)</span></tt>,
an <tt class="literal"><span class="pre">__init__</span></tt> function object is added to the class
dictionary which default-constructs a boring in a
value_holder (because you didn't specify some smart pointer
or derived wrapper class as a holder) held by the Python
boring object.</p>
<p><tt class="literal"><span class="pre">register_class_from_python</span></tt> is used to register a
from-python converter for <tt class="literal"><span class="pre">shared_ptr&lt;boring&gt;</span></tt>.
<tt class="literal"><span class="pre">boost::shared_ptr</span></tt>s are special among smart pointers
because their Deleter argument can be made to manage the
whole Python object, not just the C++ object it contains, no
matter how the C++ object is held.</p>
<p>If there were any <tt class="literal"><span class="pre">bases&lt;&gt;</span></tt>, we'd also be registering the
relationship between these base classes and boring in the
up/down cast graph (<tt class="literal"><span class="pre">inheritance.[hpp/cpp]</span></tt>).</p>
<p>In earlier versions of the code, we'd be registering lvalue
from-python converters for the class here, but now
from-python conversion for wrapped classes is handled as a
special case, before consulting the registry, if the source
Python object's metaclass is the Boost.Python metaclass.</p>
<p>Hmm, that from-python converter probably ought to be handled
the way class converters are, with no explicit conversions
registered.</p>
</blockquote>
</blockquote>
<ol class="arabic" start="2">
<li><p class="first">Can you give a brief overview of the data structures that are
present in the registry</p>
<blockquote>
<p>The registry is simple: it's just a map from typeid -&gt;
registration (see boost/python/converter/registrations.hpp).
<tt class="literal"><span class="pre">lvalue_chain</span></tt> and <tt class="literal"><span class="pre">rvalue_chain</span></tt> are simple endogenous
linked lists.</p>
<p>If you want to know more, just ask.</p>
<p>If you want to know about the cast graph, ask me something specific in
a separate message.</p>
</blockquote>
<p>and an overview of the process that happens as a type makes its
way from c++ to python and back again.</p>
</li>
</ol>
<blockquote>
<p>Big subject. I suggest some background reading: look for relevant
info in the LLNL progress reports and the messages they link to.
Also,</p>
<blockquote>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a></p>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-December/003115.html">http://mail.python.org/pipermail/c++-sig/2002-December/003115.html</a></p>
<p><a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1280898">http://aspn.activestate.com/ASPN/Mail/Message/1280898</a></p>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-July/001755.html">http://mail.python.org/pipermail/c++-sig/2002-July/001755.html</a></p>
</blockquote>
<p>from c++ to python:</p>
<blockquote>
<p>It depends on the type and the call policies in use or, for
<tt class="literal"><span class="pre">call&lt;&gt;(...)</span></tt>, <tt class="literal"><span class="pre">call_method&lt;&gt;(...)</span></tt>, or <tt class="literal"><span class="pre">object(...)</span></tt>, if
<tt class="literal"><span class="pre">ref</span></tt> or <tt class="literal"><span class="pre">ptr</span></tt> is used. There are also two basic
categories to to-python conversion, &quot;return value&quot; conversion
(for Python-&gt;C++ calls) and &quot;argument&quot; conversion (for
C++-&gt;Python calls and explicit <tt class="literal"><span class="pre">object()</span></tt> conversions). The
behavior of these two categories differs subtly in various ways
whose details I forget at the moment. You can probably find
the answers in the above references, and certainly in the code.</p>
<p>The &quot;default&quot; case is by-value (copying) conversion, which uses
to_python_value as a to-python converter.</p>
<blockquote>
<p>Since there can sensibly be only one way to convert any type
to python (disregarding the idea of scoped registries for the
moment), it makes sense that to-python conversions can be
handled by specializing a template. If the type is one of
the types handled by a built-in conversion
(builtin_converters.hpp), the corresponding template
specialization of to_python_value gets used.</p>
<p>Otherwise, to_python_value uses the <tt class="literal"><span class="pre">m_to_python</span></tt>
function in the registration for the C++ type.</p>
</blockquote>
<p>Other conversions, like by-reference conversions, are only
available for wrapped classes, and are requested explicitly by
using <tt class="literal"><span class="pre">ref(...)</span></tt>, <tt class="literal"><span class="pre">ptr(...)</span></tt>, or by specifying different
CallPolicies for a call, which can cause a different to-python
converter to be used. These conversions are never registered
anywhere, though they do need to use the registration to find
the Python class corresponding to the C++ type being referred
to. They just build a new Python instance and stick the
appropriate Holder instance in it.</p>
</blockquote>
<p>from python to C++:</p>
<blockquote>
<p>Once again I think there is a distinction between &quot;return value&quot;
and &quot;argument&quot; conversions, and I forget exactly what that is.</p>
<p>What happens depends on whether an lvalue conversion is needed
(see <a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a>)
All lvalue conversions are also registered in a type's rvalue
conversion chain, since when an rvalue will do, an lvalue is
certainly good enough.</p>
<p>An lvalue conversion can be done in one step (just get me the
pointer to the object - it can be <tt class="literal"><span class="pre">NULL</span></tt> if no conversion is
possible) while an rvalue conversion requires two steps to
support wrapped function overloading and multiple converters for
a given C++ target type: first tell me if a conversion is
possible, then construct the converted object as a second step.</p>
</blockquote>
</blockquote>
</div>
</div>
<hr class="footer"/>
<div class="footer">
<a class="reference" href="internals.rst">View document source</a>.
Generated on: 2003-09-12 14:51 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

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

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
"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">
@@ -29,100 +29,18 @@
<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
href="mailto:romany-at-actimize.com">Roman Yakovenko</a> and documented
<code>add_static_property</code> at his urging.</dd>
<dt>1 August 2003</dt>
<dd>
Added the new <code>arg</code> class contributed by <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a> which supplies the
ability to wrap functions that can be called with ommitted arguments
in the middle:
<pre>
void f(int x = 0, double y = 3.14, std::string z = std::string("foo"));
BOOST_PYTHON_MODULE(test)
{
def("f", f
, (arg("x", 0), arg("y", 3.14), arg("z", "foo")));
}
</pre>
And in Python:
<pre>
&gt;&gt;&gt; import test
&gt;&gt;&gt; f(0, z = "bar")
&gt;&gt;&gt; f(z = "bar", y = 0.0)
</pre>
Thanks, Nikolay!
</dd>
<dt>22 July 2003</dt>
<dd>Killed the dreaded "bad argument type for builtin operation" error.
Argument errors now show the actual and expected argument types!</dd>
<dt>19 July 2003</dt>
<dd>Added the new <code><a href=
"v2/return_arg.html">return_arg</a></code> policy from <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks,
Nikolay!</dd>
<dt>18 March, 2003</dt>
<dd><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
Gan&szlig;auge</a> has contributed <a href=
"v2/opaque_pointer_converter.html">opaque pointer support</a>.<br>
<a href="nicodemus-at-globalite.com.br">Bruno da Silva de Oliveira</a>
has contributed the exciting <a href="../pyste/index.html">Pyste</a>
("Pie-steh") package.</dd>
<dt>24 February 2003</dt>
<dd>Finished improved support for <code>boost::shared_ptr</code>. Now
any wrapped object of C++ class <code>X</code> can be converted
automatically to <code>shared_ptr&lt;X&gt;</code>, regardless of how it
was wrapped. The <code>shared_ptr</code> will manage the lifetime of
the Python object which supplied the <code>X</code>, rather than just
the <code>X</code> object itself, and when such a
<code>shared_ptr</code> is converted back to Python, the original
Python object will be returned.</dd>
<dd>Finished improved support
for <code>boost::shared_ptr</code>. Now any wrapped object of
C++ class <code>X</code> can be converted automatically
to <code>shared_ptr&lt;X&gt;</code>, regardless of how it was
wrapped. The <code>shared_ptr</code> will manage the lifetime
of the Python object which supplied the <code>X</code>, rather
than just the <code>X</code> object itself, and when such
a <code>shared_ptr</code> is converted back to Python, the
original Python object will be returned.</dd>
<dt>19 January 2003</dt>
<dd>Integrated <code>staticmethod</code> support from <a href=
@@ -180,12 +98,12 @@ BOOST_PYTHON_MODULE(test)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
11 September 2003
20 December, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
Abrahams</a> 2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -38,23 +38,28 @@
page .</p>
<hr>
<h3>Data Analysis</h3>
<h3>Enterprise Software</h3>
<dl class="page-index">
<dt><b><a href=
"http://www.neuralynx.com/neuralab/index.htm">NeuraLab</a></b></dt>
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
<dd>Neuralab is a data analysis environment specifically tailored for
neural data from <a href="http://www.neuralynx.com">Neuralynx</a>
acquisition systems. Neuralab combines presentation quality graphics, a
numerical analysis library, and the <a href=
"http://www.python.org">Python</a> scripting engine in a single
application. With Neuralab, Neuralynx users can perform common analysis
tasks with just a few mouse clicks. More advanced users can create
custom Python scripts, which can optionally be assigned to menus and
mouse clicks.</dd>
<dd>
The OpenWBEM project is an effort to develop an open-source
implementation of Web Based Enterprise Management suitable for
commercial and non-commercial application
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
<blockquote>
I'm using Boost.Python to wrap the client API of OpenWBEM.This will
make it easier to do rapid prototyping, testing, and scripting when
developing management solutions that use WBEM.
</blockquote>
</dd>
</dl>
<h3>Financial Analysis</h3>
<dl class="page-index">
<dt><b>TSLib</b> - <a href="http://www.fortressinv.com">Fortress
Investment Group LLC</a></dt>
@@ -82,81 +87,26 @@
</dd>
</dl>
<h3>Educational</h3>
<dl class="page-index">
<dt><a href="http://edu.kde.org/kig"><b>Kig</b></a></dt>
<dd>
<p>KDE Interactive Geometry is a high-school level educational tool,
built for the KDE desktop. It is a nice tool to let students work
with geometrical constructions. It is meant to be the most intuitive,
yet featureful application of its kind.</p>
<p>Versions after 0.6.x (will) support objects built by the user
himself in the Python language. The exporting of the relevant
internal API's were done using Boost.Python, which made the process
very easy.</p>
</dd>
</dl>
<h3>Enterprise Software</h3>
<dl class="page-index">
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
<dd>
The OpenWBEM project is an effort to develop an open-source
implementation of Web Based Enterprise Management suitable for
commercial and non-commercial application
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
<blockquote>
I'm using Boost.Python to wrap the client API of OpenWBEM.This will
make it easier to do rapid prototyping, testing, and scripting when
developing management solutions that use WBEM.
</blockquote>
</dd>
<dt><b><a href="http://www.transversal.com">Metafaq</a></b></dt>
<dd>
Metafaq, from <a href="http://www.transversal.com">Transversal,
Inc.</a>, is an enterprise level online knowledge base management
system.
<p><a href="mailto:ben.young-at-transversal.com">Ben Young</a>
writes:</p>
<blockquote>
Boost.Python is used in an automated process to generate python
bindings to our api which is exposed though multiple backends and
frontends. This allows us to write quick tests and bespoke scripts
to perform one off tasks without having to go through the full
compilation cycle.
</blockquote>
</dd>
</dl>
<h3>Graphics</h3>
<dl class="page-index">
<dt><b><a href="http://sourceforge.net/projects/pyosg">OpenSceneGraph
Bindings</a></b></dt>
<dt><b><a href=
"http://www.openscenegraph.org">OpenSceneGraph</a></b></dt>
<dd><a href="mailto:gideon@computer.org">Gideon May</a> has created a
set of bindings for <a href=
"http://www.openscenegraph.org">OpenSceneGraph</a>, a cross-platform
C++/OpenGL library for the real-time visualization.<br>
set of bindings for OpenSceneGraph, a cross-platform C++/OpenGL library
for the real-time visualization. You can read the release announcement
at <a href="http://www.hypereyes.com">www.hypereyes.com</a>. <a href=
"mailto:gideon@computer.org">Contact Gideon</a> for more
information.<br>
&nbsp;</dd>
<dt><a href=
"http://www.procoders.net/pythonmagick"><b>PythonMagick</b></a></dt>
"http://pythonmagick.procoders.net/"><b>PythonMagick</b></a></dt>
<dd>PythonMagick binds the <a href=
"http://www.graphicsmagick.org">GraphicsMagick</a> image manipulation
library to Python.<br>
"http://www.imagemagick.org">ImageMagick</a> image manipulation library
to Python.<br>
&nbsp;</dd>
<dt><b><a href=
@@ -170,8 +120,9 @@
so that all the manipulation can be done from either Python or the
GUI.
<p>Before the web page came online, <a href=
"mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a> wrote:</p>
<p>Before the web page came online, <a
href="mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a>
wrote:</p>
<blockquote>
Don't have a web page for the project, but the organization's is <a
@@ -257,85 +208,14 @@
Boost.Python plays and essential role.</p>
</blockquote>
</dd>
<dt><b><a href="http://www.esss.com.br">ESSS</a></b></dt>
<dd>
ESSS (Engineering Simulation and Scientific Software) is a company
that provides engineering solutions and acts in the brazilian and
south-american market providing products and services related to
Computational Fluid Dynamics and Image Analysis.
<p><a href="mailto:bruno@esss.com.br">Bruno da Silva de Oliveira</a>
writes:</p>
<blockquote>
Recently we moved our work from working exclusively with C++ to an
hybrid-language approach, using Python and C++, with Boost.Python
providing the layer between the two. The results are great so far!
</blockquote>
<p>Two projects have been developed so far with this technology:</p>
<p><b><a href="http://www.esss.com.br/dev_simba.phtml">Simba</a></b>
provides 3D visualization of geological formations gattered from the
simulation of the evolution of oil systems, allowing the user to
analyse various aspects of the simulation, like deformation, pressure
and fluids, along the time of the simulation.</p>
<p><b><a href="http://www.esss.com.br/dev_aero.phtml">Aero</a></b>
aims to construct a CFD with brazilian technology, which involves
various companies and universities. ESSS is responsible for various
of the application modules, including GUI and post-processing of
results.</p>
</dd>
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
LLC</a></b></dt>
<dd>
Rational Discovery provides computational modeling, combinatorial
library design and custom software development services to the
pharmaceutical, biotech and chemical industries. We do a substantial
amount of internal research to develop new approaches for applying
machine-learning techniques to solve chemical problems. Because we're
a small organization and chemistry is a large and complex field, it
is essential that we be able to quickly and easily prototype and test
new algorithms.
<p>For our internal software, we implement core data structures in C
and expose them to Python using Boost.Python. Algorithm development
is done in Python and then translated to C if required (often it's
not). This hybrid development approach not only greatly increases our
productivity, but it also allows "non-developers" (people without C
experience) to take part in method development. Learning C is a
daunting task, but "Python fits your brain." (Thanks to Bruce Eckel
for the quote.)</p>
</dd>
</dl>
<h3>Tools</h3>
<dl>
<dt><a href="http://www.jayacard.org"><b>Jayacard</b></a></dt>
<dd>
Jayacard aims at developing a secure portable open source operating
system for contactless smart cards and a complete suite of high
quality development tools to ease smart card OS and application
development.
<p>The core of the smart card reader management is written in C++ but
all the development tools are written in the friendly Python
language. Boost plays the fundamental role of binding the tools to
our core smart card reader library.</p>
</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
15 July, 2003</p>
22 March, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
"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">
@@ -31,9 +31,7 @@
<h2>Synopsis</h2>
<p>This is a list of available resources for support with Boost.Python
problems and feature requests. <b>Please try to resist emailing the
Boost.Python developers directly for support.</b> Use the following
resources instead; the developers are listening!</p>
problems and feature requests.</p>
<hr>
<dl class="page-index">
@@ -43,11 +41,9 @@
you Boost.Python.<br>
&nbsp;</dt>
<dt><b><a href=
"http://www.boost.org/more/mailing_lists.htm#cplussig">The Python
<dt><b><a href="http://www.python.org/sigs/c++-sig/">The Python
C++-sig</a></b> mailing list is a forum for discussing Python/C++
interoperability, and Boost.Python in particular. Post your
Boost.Python questions here.<br>
interoperability, and Boost.Python in particular.<br>
&nbsp;</dt>
<dt>The <b>Boost.Python <a href=
@@ -55,17 +51,18 @@
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 -->
12 Sept, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
17 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2003.</i></p>
Abrahams</a> 2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -32,15 +32,12 @@ with every boost distribution: <b>bjam</b>.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<p><img src="theme/lens.gif"></img> <b>Building without bjam</b><br>
<br>
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>. </p>
<p>Take note however that the preferred build tool for Boost.Python is <tt>bjam</tt>.
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<tt></tt>.</p></td>
<img src="theme/lens.gif"></img> <b>Building without bjam</b><br><br>
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>.
</td>
</tr>
</table>
<p>

View File

@@ -83,7 +83,7 @@ respectively. In our <tt>foo</tt> function the minimum number of arguments is 1
and the maximum number of arguments is 4. The <tt>def(...)</tt> function will
automatically add all the foo variants for us:</p>
<code><pre>
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
</span></pre></code>
<a name="boost_python_member_function_overloads"></a><h2>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</h2><p>
Objects here, objects there, objects here there everywhere. More frequently

View File

@@ -62,11 +62,6 @@ 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
@@ -999,7 +994,7 @@ respectively. In our [^foo] function the minimum number of arguments is 1
and the maximum number of arguments is 4. The [^def(...)] function will
automatically add all the foo variants for us:
def("foo", foo, foo_overloads());
.def("foo", foo, foo_overloads());
[h2 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
@@ -1335,258 +1330,6 @@ create a new scope around a class:
.value("blue", blue)
;
[def Py_Initialize [@http://www.python.org/doc/current/api/initialization.html#l2h-652 Py_Initialize]]
[def Py_Finalize [@http://www.python.org/doc/current/api/initialization.html#l2h-656 Py_Finalize]]
[def PyRun_String [@http://www.python.org/doc/current/api/veryhigh.html#l2h-55 PyRun_String]]
[def PyRun_File [@http://www.python.org/doc/current/api/veryhigh.html#l2h-56 PyRun_File]]
[def Py_eval_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-58 Py_eval_input]]
[def Py_file_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-59 Py_file_input]]
[def Py_single_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-60 Py_single_input]]
[def Py_XINCREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-65 Py_XINCREF]]
[def Py_XDECREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-67 Py_XDECREF]]
[def PyImport_AppendInittab [@http://www.python.org/doc/current/api/importing.html#l2h-137 PyImport_AppendInittab]]
[def PyImport_AddModule [@http://www.python.org/doc/current/api/importing.html#l2h-125 PyImport_AddModule]]
[def PyModule_New [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-591 PyModule_New]]
[def PyModule_GetDict [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-594 PyModule_GetDict]]
[page:0 Embedding]
By now you should know how to use Boost.Python to call your C++ code from
Python. However, sometimes you may need to do the reverse: call Python code
from the C++-side. This requires you to ['embed] the Python interpreter
into your C++ program.
Currently, Boost.Python does not directly support everything you'll need
when embedding. Therefore you'll need to use the
[@http://www.python.org/doc/current/api/api.html Python/C API] to fill in
the gaps. However, Boost.Python already makes embedding a lot easier and,
in a future version, it may become unnecessary to touch the Python/C API at
all. So stay tuned... :-)
[h2 Building embedded programs]
To be able to use embedding in your programs, they have to be linked to
both Boost.Python's and Python's static link library.
Boost.Python's static link library comes in two variants. Both are located
in Boost's [^/libs/python/build/bin-stage] subdirectory. On Windows, the
variants are called [^boost_python.lib] (for release builds) and
[^boost_python_debug.lib] (for debugging). If you can't find the libraries,
you probably haven't built Boost.Python yet. See [@../../building.html
Building and Testing] on how to do this.
Python's static link library can be found in the [^/libs] subdirectory of
your Python directory. On Windows it is called pythonXY.lib where X.Y is
your major Python version number.
Additionally, Python's [^/include] subdirectory has to be added to your
include path.
In a Jamfile, all the above boils down to:
[pre
projectroot c:\projects\embedded_program ; # location of the program
# bring in the rules for python
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
exe embedded_program # name of the executable
: #sources
embedded_program.cpp
: # requirements
<find-library>boost_python <library-path>c:\boost\libs\python
$(PYTHON_PROPERTIES)
<library-path>$(PYTHON_LIB_PATH)
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
]
[h2 Getting started]
Being able to build is nice, but there is nothing to build yet. Embedding
the Python interpreter into one of your C++ programs requires these 4
steps:
# '''#include''' [^<boost/python.hpp>][br][br]
# Call Py_Initialize() to start the interpreter and create the [^__main__] module.[br][br]
# Call other Python C API routines to use the interpreter.[br][br]
# Call Py_Finalize() to stop the interpreter and release its resources.
(Of course, there can be other C++ code between all of these steps.)
[:['[*Now that we can embed the interpreter in our programs, lets see how to put it to use...]]]
[page:1 Using the interpreter]
As you probably already know, objects in Python are reference-counted.
Naturally, the [^PyObject]s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully
automatic in Python, the Python/C API requires you to do it
[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
messy and especially hard to get right in the presence of C++ exceptions.
Fortunately Boost.Python provides the [@../../v2/handle.html handle] class
template to automate the process.
[h2 Reference-counting handles]
There are two ways in which a function in the Python/C API can return a
[^PyObject*]: as a ['borrowed reference] or as a ['new reference]. Which of
these a function uses, is listed in that function's documentation. The two
require slightely different approaches to reference-counting but both can
be 'handled' by Boost.Python.
For a function returning a ['borrowed reference] we'll have to tell the
[^handle] that the [^PyObject*] is borrowed with the aptly named
[@../../v2/handle.html#borrowed-spec borrowed] function. Two functions
returning borrowed references are PyImport_AddModule and PyModule_GetDict.
The former returns a reference to an already imported module, the latter
retrieves a module's namespace dictionary. Let's use them to retrieve the
namespace of the [^__main__] module:
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
Because the Python/C API doesn't know anything about [^handle]s, we used
the [@../../v2/handle.html#handle-spec-observers get] member function to
retrieve the [^PyObject*] from which the [^handle] was constructed.
For a function returning a ['new reference] we can just create a [^handle]
out of the raw [^PyObject*] without wrapping it in a call to borrowed. One
such function that returns a new reference is PyRun_String which we'll
discuss in the next section.
[blurb __detail__ [*Handle is a class ['template], so why haven't we been using any template parameters?][br]
[br]
[^handle] has a single template parameter specifying the type of the managed object. This type is [^PyObject] 99% of the time, so the parameter was defaulted to [^PyObject] for convenience. Therefore we can use the shorthand [^handle<>] instead of the longer, but equivalent, [^handle<PyObject>].
]
[h2 Running Python code]
To run Python code from C++ there is a family of functions in the API
starting with the PyRun prefix. You can find the full list of these
functions [@http://www.python.org/doc/current/api/veryhigh.html here]. They
all work similarly so we will look at only one of them, namely:
PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
PyRun_String takes the code to execute as a null-terminated (C-style)
string in its [^str] parameter. The function returns a new reference to a
Python object. Which object is returned depends on the [^start] paramater.
The [^start] parameter is the start symbol from the Python grammar to use
for interpreting the code. The possible values are:
[table Start symbols
[Py_eval_input] [for interpreting isolated expressions]
[Py_file_input] [for interpreting sequences of statements]
[Py_single_input] [for interpreting a single statement]
]
When using Py_eval_input, the input string must contain a single expression
and its result is returned. When using Py_file_input, the string can
contain an abitrary number of statements and None is returned.
Py_single_input works in the same way as Py_file_input but only accepts a
single statement.
Lastly, the [^globals] and [^locals] parameters are Python dictionaries
containing the globals and locals of the context in which to run the code.
For most intents and purposes you can use the namespace dictionary of the
[^__main__] module for both parameters.
We have already seen how to get the [^__main__] module's namespace so let's
run some Python code in it:
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
handle<>( PyRun_String("hello = file('hello.txt', 'w')\n"
"hello.write('Hello world!')\n"
"hello.close()", Py_file_input,
main_namespace.get(), main_namespace.get()) );
This should create a file called 'hello.txt' in the current directory
containing a phrase that is well-known in programming circles.
__note__ [*Note] that we wrap the return value of PyRun_String in a
(nameless) [^handle] even though we are not interested in it. If we didn't
do this, the the returned object would be kept alive unnecessarily. Unless
you want to be a Dr. Frankenstein, always wrap [^PyObject*]s in [^handle]s.
[h2 Beyond handles]
It's nice that [^handle] manages the reference counting details for us, but
other than that it doesn't do much. Often we'd like to have a more useful
class to manipulate Python objects. But we have already seen such a class
in the [@object_interface.html previous section]: the aptly named [^object]
class and it's derivatives. What we haven't seen, is that they can be
constructed from a [^handle]. The following examples should illustrate this
fact:
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
dict main_namespace(handle<>(borrowed( PyModule_GetDict(main_module.get()) )));
handle<>( PyRun_String("result = 5 ** 2", Py_file_input,
main_namespace.ptr(), main_namespace.ptr()) );
int five_squared = extract<int>( main_namespace["result"] );
Here we create a dictionary object for the [^__main__] module's namespace.
Then we assign 5 squared to the result variable and read this variable from
the dictionary. Another way to achieve the same result is to let
PyRun_String return the result directly with Py_eval_input:
object result(handle<>( PyRun_String("5 ** 2", Py_eval_input,
main_namespace.ptr(), main_namespace.ptr()) ));
int five_squared = extract<int>(result);
__note__ [*Note] that [^object]'s member function to return the wrapped
[^PyObject*] is called [^ptr] instead of [^get]. This makes sense if you
take into account the different functions that [^object] and [^handle]
perform.
[h2 Exception handling]
If an exception occurs in the execution of some Python code, the PyRun_String function returns a null pointer. Constructing a [^handle] out of this null pointer throws [@../../v2/errors.html#error_already_set-spec error_already_set], so basically, the Python exception is automatically translated into a C++ exception when using [^handle]:
try
{
object result(handle<>( PyRun_String("5/0", Py_eval_input,
main_namespace.ptr(), main_namespace.ptr()) ));
// execution will never get here:
int five_divided_by_zero = extract<int>(result);
}
catch(error_already_set)
{
// handle the exception in some way
}
The [^error_already_set] exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the [@http://www.python.org/doc/api/exceptionHandling.html exception handling functions] of the Python/C API in your catch-statement. This can be as simple as calling [@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to print the exception's traceback to the console, or comparing the type of the exception with those of the [@http://www.python.org/doc/api/standardExceptions.html standard exceptions]:
catch(error_already_set)
{
if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
{
// handle ZeroDivisionError specially
}
else
{
// print all other errors to stderr
PyErr_Print();
}
}
(To retrieve even more information from the exception you can use some of the other exception handling functions listed [@http://www.python.org/doc/api/exceptionHandling.html here].)
If you'd rather not have [^handle] throw a C++ exception when it is constructed, you can use the [@../../v2/handle.html#allow_null-spec allow_null] function in the same way you'd use borrowed:
handle<> result(allow_null( PyRun_String("5/0", Py_eval_input,
main_namespace.ptr(), main_namespace.ptr()) ));
if (!result)
// Python exception occurred
else
// everything went okay, it's safe to use the result
[page Iterators]
In C++, and STL in particular, we see iterators everywhere. Python also has
@@ -1681,321 +1424,3 @@ Users may provide custom translation. Here's an example:
PodBayDoorException>(translator);
...
[page General Techniques]
Here are presented some useful techniques that you can use while wrapping code with Boost.Python.
[page:1 Creating Packages]
A Python package is a collection of modules that provide to the user a certain
functionality. If you're not familiar on how to create packages, a good
introduction to them is provided in the
[@http://www.python.org/doc/current/tut/node8.html Python Tutorial].
But we are wrapping C++ code, using Boost.Python. How can we provide a nice
package interface to our users? To better explain some concepts, let's work
with an example.
We have a C++ library that works with sounds: reading and writing various
formats, applying filters to the sound data, etc. It is named (conveniently)
[^sounds]. Our library already has a neat C++ namespace hierarchy, like so:
sounds::core
sounds::io
sounds::filters
We would like to present this same hierarchy to the Python user, allowing him
to write code like this:
import sounds.filters
sounds.filters.echo(...) # echo is a C++ function
The first step is to write the wrapping code. We have to export each module
separately with Boost.Python, like this:
/* file core.cpp */
BOOST_PYTHON_MODULE(core)
{
/* export everything in the sounds::core namespace */
...
}
/* file io.cpp */
BOOST_PYTHON_MODULE(io)
{
/* export everything in the sounds::io namespace */
...
}
/* file filters.cpp */
BOOST_PYTHON_MODULE(filters)
{
/* export everything in the sounds::filters namespace */
...
}
Compiling these files will generate the following Python extensions:
[^core.pyd], [^io.pyd] and [^filters.pyd].
[blurb __note__ The extension [^.pyd] is used for python extension modules, which
are just shared libraries. Using the default for your system, like [^.so] for
Unix and [^.dll] for Windows, works just as well.]
Now, we create this directory structure for our Python package:
[pre
sounds/
__init__.py
core.pyd
filters.pyd
io.pyd
]
The file [^__init__.py] is what tells Python that the directory [^sounds/] is
actually a Python package. It can be a empty file, but can also perform some
magic, that will be shown later.
Now our package is ready. All the user has to do is put [^sounds] into his
[@http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000 PYTHONPATH] and fire up the interpreter:
>>> import sounds.io
>>> import sounds.filters
>>> sound = sounds.io.open('file.mp3')
>>> new_sound = sounds.filters.echo(sound, 1.0)
Nice heh?
This is the simplest way to create hierarchies of packages, but it is not very
flexible. What if we want to add a ['pure] Python function to the filters
package, for instance, one that applies 3 filters in a sound object at once?
Sure, you can do this in C++ and export it, but why not do so in Python? You
don't have to recompile the extension modules, plus it will be easier to write
it.
If we want this flexibility, we will have to complicate our package hierarchy a
little. First, we will have to change the name of the extension modules:
/* file core.cpp */
BOOST_PYTHON_MODULE(_core)
{
...
/* export everything in the sounds::core namespace */
}
Note that we added an underscore to the module name. The filename will have to
be changed to [^_core.pyd] as well, and we do the same to the other extension modules.
Now, we change our package hierarchy like so:
[pre
sounds/
__init__.py
core/
__init__.py
_core.pyd
filters/
__init__.py
_filters.pyd
io/
__init__.py
_io.pyd
]
Note that we created a directory for each extension module, and added a
__init__.py to each one. But if we leave it that way, the user will have to
access the functions in the core module with this syntax:
>>> import sounds.core._core
>>> sounds.core._core.foo(...)
which is not what we want. But here enters the [^__init__.py] magic: everything
that is brought to the [^__init__.py] namespace can be accessed directly by the
user. So, all we have to do is bring the entire namespace from [^_core.pyd]
to [^core/__init__.py]. So add this line of code to [^sounds/core/__init__.py]:
from _core import *
We do the same for the other packages. Now the user accesses the functions and
classes in the extension modules like before:
>>> import sounds.filters
>>> sounds.filters.echo(...)
with the additional benefit that we can easily add pure Python functions to
any module, in a way that the user can't tell the difference between a C++
function and a Python function. Let's add a ['pure] Python function,
[^echo_noise], to the [^filters] package. This function applies both the
[^echo] and [^noise] filters in sequence in the given [^sound] object. We
create a file named [^sounds/filters/echo_noise.py] and code our function:
import _filters
def echo_noise(sound):
s = _filters.echo(sound)
s = _filters.noise(sound)
return s
Next, we add this line to [^sounds/filters/__init__.py]:
from echo_noise import echo_noise
And that's it. The user now accesses this function like any other function
from the [^filters] package:
>>> import sounds.filters
>>> sounds.filters.echo_noise(...)
[page:1 Extending Wrapped Objects in Python]
Thanks to Python's flexibility, you can easily add new methods to a class,
even after it was already created:
>>> class C(object): pass
>>>
>>> # a regular function
>>> def C_str(self): return 'A C instance!'
>>>
>>> # now we turn it in a member function
>>> C.__str__ = C_str
>>>
>>> c = C()
>>> print c
A C instance!
>>> C_str(c)
A C instance!
Yes, Python rox. :-)
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class [^point] in C++:
class point {...};
BOOST_PYTHON_MODULE(_geom)
{
class_<point>("point")...;
}
If we are using the technique from the previous session, [@creating_packages.html
Creating Packages], we can code directly into [^geom/__init__.py]:
from _geom import *
# a regular function
def point_str(self):
return str((self.x, self.y))
# now we turn it into a member function
point.__str__ = point_str
[*All] point instances created from C++ will also have this member function!
This technique has several advantages:
* Cut down compile times to zero for these additional functions
* Reduce the memory footprint to virtually zero
* Minimize the need to recompile
* Rapid prototyping (you can move the code to C++ if required without changing the interface)
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.
# The one Boost.Python uses for all wrapped classes.
# You can use here any class exported by Boost instead of "point"
BoostPythonMetaclass = point.__class__
class injector(object):
class __metaclass__(BoostPythonMetaclass):
def __init__(self, name, bases, dict):
for b in bases:
if type(b) not in (self, type):
for k,v in dict.items():
setattr(b,k,v)
return type.__init__(self, name, bases, dict)
# inject some methods in the point foo
class more_point(injector, point):
def __repr__(self):
return 'Point(x=%s, y=%s)' % (self.x, self.y)
def foo(self):
print 'foo!'
Now let's see how it got:
>>> print point()
Point(x=10, y=10)
>>> point().foo()
foo!
Another useful idea is to replace constructors with factory functions:
_point = point
def point(x=0, y=0):
return _point(x, y)
In this simple case there is not much gained, but for constructurs with
many overloads and/or arguments this is often a great simplification, again
with virtually zero memory footprint and zero compile-time overhead for
the keyword support.
[page:1 Reducing Compiling Time]
If you have ever exported a lot of classes, you know that it takes quite a good
time to compile the Boost.Python wrappers. Plus the memory consumption can
easily become too high. If this is causing you problems, you can split the
class_ definitions in multiple files:
/* file point.cpp */
#include <point.h>
#include <boost/python.hpp>
void export_point()
{
class_<point>("point")...;
}
/* file triangle.cpp */
#include <triangle.h>
#include <boost/python.hpp>
void export_triangle()
{
class_<triangle>("triangle")...;
}
Now you create a file [^main.cpp], which contains the [^BOOST_PYTHON_MODULE]
macro, and call the various export functions inside it.
void export_point();
void export_triangle();
BOOST_PYTHON_MODULE(_geom)
{
export_point();
export_triangle();
}
Compiling and linking together all this files produces the same result as the
usual approach:
#include <boost/python.hpp>
#include <point.h>
#include <triangle.h>
BOOST_PYTHON_MODULE(_geom)
{
class_<point>("point")...;
class_<triangle>("triangle")...;
}
but the memory is kept under control.
This method is recommended too if you are developing the C++ library and
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.
[blurb __note__ If you're exporting your classes with [@../../../pyste/index.html Pyste],
take a look at the [^--multiple] option, that generates the wrappers in
various files as demonstrated here.]
[blurb __note__ This method is useful too if you are getting the error message
['"fatal error C1204:Compiler limit:internal structure overflow"] when compiling
a large source file, as explained in the [@../../v2/faq.html#c1204 FAQ].]

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>main_namespace </span><span class=identifier>dict</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

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
"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">
@@ -35,31 +35,7 @@
<dt><a href="#keyword-expression"><i>keyword-expressions</i></a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#arg-spec">class <code>arg</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#arg-synopsis">class <code>arg</code>
synopsis</a></dt>
<dt><a href="#arg-ctor">class <code>arg</code>
constructor</a></dt>
<dt><a href="#arg-operator">class <code>arg</code> template
<code>operator =</code></a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#keyword-expression-operators"><i>Keyword-expression</i>
operator <code>,</code></a></dt>
<dt><a href="#functions">Functions (deprecated)</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
@@ -81,95 +57,27 @@
<p>A <b>keyword-expression</b> results in an object which holds a
sequence of <a href="definitions.html#ntbs">ntbs</a>es, and whose type
encodes the number of keywords specified. The <b>keyword-expression</b>
may contain default values for some or all of the keywords it holds</p>
encodes the number of keywords specified.</p>
<h2><a name="classes"></a>Classes</h2>
<h2><a name="functions"></a>Functions</h2>
<h3><a name="arg-spec"></a><code>class arg;</code></h3>
<p>The objects of class arg are keyword-expressions holding one keyword (
size one )</p>
<h4><a name="arg-synopsis"></a>Class <code>arg</code> synopsis</h4>
<h3><a name="args-spec"></a><code>args(</code>...<code>)</code></h3>
<pre>
namespace boost { namespace python
{
struct arg
{
template &lt;class T&gt;
arg &amp;perator = (T const &amp;value);
explicit arg (char const *name){elements[0].name = name;}
};
}}
</pre>
<h4><a name="arg-ctor"></a>Class <code>arg</code> constructor</h4>
<pre>
arg(char const* name);
<i>unspecified1</i> args(char const*);
<i>unspecified2</i> args(char const*, char const*);
.
.
.
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The argument must be a <a href=
<dt><b>Requires:</b> Every argument must be a <a href=
"definitions.html#ntbs">ntbs</a>.</dt>
<dt><b>Effects:</b> Constructs an <code>arg</code> object holding a
keyword with name <code>name</code>.</dt>
</dl>
<h4><a name="arg-operator"></a>Class <code>arg</code> operator =</h4>
<pre>
template &lt;class T&gt; arg &amp;operator = (T const &amp;value);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The argument must convertible to python.</dt>
<dt><b>Effects:</b> Assigns default value for the keyword.</dt>
<dt><b>Returns:</b> Reference to <code>this</code>.</dt>
</dl>
<h2><a name="keyword-expression-operators"><i>Keyword-expression</i>
operator <code>,</code></a></h2>
<pre>
<i>keyword-expression</i> operator , (<i>keyword-expression</i>, const arg &amp;kw) const
<i>keyword-expression</i> operator , (<i>keyword-expression</i>, const char *name) const;
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The argument <code>name</code> must be a <a href=
"definitions.html#ntbs">ntbs</a>.</dt>
<dt><b>Effects:</b> Extends the <i>keyword-expression</i> argument with
one more keyword.</dt>
<dt><b>Returns:</b> The extended <i>keyword-expression</i>.</dt>
</dl>
<h2><font color="#7F7F7F"><a name="functions"></a>Functions
(deprecated)</font></h2>
<h3><a name="args-spec"></a><code><font color=
"#7F7F7F">args</font>(</code>...<code>)</code></h3>
<pre>
<font color="#7F7F7F"> <i>unspecified1</i> args(char const*);
<i>unspecified2</i> args(char const*, char const*);
.
.
.
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
</font>
</pre>
<dl class="function-semantics">
<dt><font color="#7F7F7F"><b>Requires:</b> Every argument must be a <a
href="definitions.html#ntbs">ntbs</a>.</font></dt>
<dt><font color="#7F7F7F"><b>Returns:</b> an object representing a <a
href="#keyword-expression"><i>keyword-expression</i></a> encapsulating
the arguments passed.</font></dt>
<dt><b>Returns:</b> an object representing a <a href=
"#keyword-expression"><i>keyword-expression</i></a> encapsulating the
arguments passed.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
@@ -177,21 +85,19 @@ template &lt;class T&gt; arg &amp;operator = (T const &amp;value);
#include &lt;boost/python/def.hpp&gt;
using namespace boost::python;
int f(double x, double y, double z=0.0, double w=1.0);
int f(int x, int y, int z);
BOOST_PYTHON_MODULE(xxx)
{
def("f", f
, ( arg("x"), "y", arg("z")=0.0, arg("w")=1.0 )
);
def("f", f, args("x", "y", "z"));
}
</pre>
<p>Revised 01 August, 2003</p>
<p>Revised 05 November, 2001</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003. All
Rights Reserved.</i></p>
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
"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">
@@ -212,7 +212,7 @@
namespace boost { namespace python
{
template &lt;class T
<font color="#007F00"> , class Bases = bases&lt;&gt;
<font color="#007F00"> , class Bases = bases&lt;&gt;
, class HeldType = T
, class NonCopyable = <i>unspecified</i>
&gt;
@@ -261,23 +261,12 @@ namespace boost { namespace python
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D T::*pm);
// exposing static data members
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D const&amp; d);
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D&amp; d);
// property creation
template &lt;class Get&gt;
void add_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_property(char const* name, Get const&amp; fget, Set const&amp; fset);
template &lt;class Get&gt;
void add_static_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_static_property(char const* name, Get const&amp; fget, Set const&amp; fset);
// pickle support
template &lt;typename PickleSuite&gt;
self&amp; def_pickle(PickleSuite const&amp;);
@@ -590,40 +579,8 @@ void add_property(char const* name, Get const&amp; fget, Set const&amp; fset);
</dl>
<br>
<pre>
template &lt;class Get&gt;
void add_static_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_static_property(char const* name, Get const&amp; fget, Set const&amp; fset);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.</dt>
<dt><b>Effects:</b> Creates a Boost.Python.StaticProperty object,
passing <code><a href=
"object.html#object-spec-ctors">object</a>(fget)</code> (and <code><a
href="object.html#object-spec-ctors">object</a>(fset)</code> in the
second form) to its constructor, then adds that property to the Python
class under construction with the given attribute <code>name</code>.
StaticProperty is a special subclass of Python's <a href=
"http://www.python.org/2.2.2/descrintro.html#property"><code>property</code></a>
class which can be called without an initial <code>self</code>
argument.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose functions that can
be invoked from Python with static attribute access syntax.</dt>
</dl>
<br>
<pre>
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D T::*pm);
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D const&amp; d);
</pre>
<dl class="function-semantics">
@@ -639,26 +596,17 @@ class_&amp; def_readonly(char const* name, D const&amp; d);
this-&gt;add_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm));
</pre>
and
<pre>
this-&gt;add_static_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm));
</pre>
respectively.<br>
<br>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data
member or free variable such that it can be inspected from Python with
a natural syntax.</dt>
member such that it can be inspected from Python with a natural
syntax.</dt>
</dl>
<pre>
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D T::*pm);
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D&amp; d);
</pre>
<dl class="function-semantics">
@@ -670,21 +618,13 @@ this-&gt;add_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
"data_members.html#make_setter-spec">make_setter</a>(pm));
</pre>
and
<pre>
this-&gt;add_static_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
"data_members.html#make_setter-spec">make_setter</a>(pm));
</pre>
respectively.<br>
<br>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data or
free variable member such that it can be inspected and set from Python
with a natural syntax.</dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data
member such that it can be inspected and set from Python with a natural
syntax.</dt>
</dl>
<pre>
template &lt;typename PickleSuite&gt;
@@ -774,7 +714,8 @@ class_&lt;Derived, bases&lt;Base&gt; &gt;("Derived");
</pre>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
5 August, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href=

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
"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">
@@ -92,39 +92,6 @@ template &lt;class C, class D, class Policies&gt;
callable object.</dt>
</dl>
<pre>
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_getter(D const&amp; d);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_getter(D const&amp; d, Policies const&amp; policies);
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_getter(D const* p);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_getter(D const* p, Policies const&amp; policies);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>Effects:</b> Creates a Python callable object which accepts no
arguments and returns <code>d</code> or <code>*p</code>, converted
<code>to_python</code> on demand. If <code>policies</code> is supplied,
it will be applied to the function as described <a href=
"CallPolicies.html">here</a>. Otherwise, the library attempts to
determine whether <code>D</code> is a user-defined class type, and if
so uses <code><a href=
"reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a></code></dt>
<dt>for <code>Policies</code>.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<pre>
<a name="make_setter-spec">template &lt;class C, class D&gt;</a>
<a href="object.html#object-spec">object</a> make_setter(D C::*pm);
@@ -149,34 +116,6 @@ template &lt;class C, class D, class Policies&gt;
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<pre>
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_setter(D&amp; d);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_setter(D&amp; d, Policies const&amp; policies);
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_setter(D* p);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_setter(D* p, Policies const&amp; policies);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>Effects:</b> Creates a Python callable object which accepts one
argument, which is converted from Python to <code>D const&amp;</code>
and written into <code>d</code> or <code>*p</code>, respectively. If
<code>policies</code> is supplied, it will be applied to the function
as described <a href="CallPolicies.html">here</a>.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
@@ -216,7 +155,8 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
5 August, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -1,135 +0,0 @@
<!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

@@ -57,11 +57,6 @@
<dt><a href="#ownership">How can I wrap a function which needs to take
ownership of a raw pointer?</a></dt>
<dt><a href="#slow_compilation">Compilation takes too much time and eats too much memory!
What can I do to make it faster?</a></dt>
<dt><a href="#packages">How do I create sub-packages using Boost.Python?</a></dt>
</dl>
<hr>
@@ -548,20 +543,6 @@ void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
"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.
<h2><a name="slow_compilation">Compilation takes too much time and eats too
much memory! What can I do to make it faster?</a></h2>
<p>
Please refer to the <a href="../tutorial/doc/reducing_compiling_time.html">Techniques</a>
section in the tutorial.
</p>
<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.
</p>
<hr>
<p>Revised

View File

@@ -10,7 +10,7 @@
</head>
<body>
Loading index page; if nothing happens, please go to <a href=
Automatic redirection failed, please go to <a href=
"../index.html">../index.html</a>.
</body>
</html>

View File

@@ -1,636 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st February 2003), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>
Indexing Support
</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3>
<a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border=
"0"></a>
</h3>
</td>
<td valign="top">
<h1 align="center">
<a href="../index.html">Boost.Python</a>
</h1>
<h2> Headers &lt;boost/python/indexing/indexing_suite.hpp&gt;<br>
&lt;boost/python/indexing/vector_indexing_suite.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>
Contents
</h2>
<dl class="page-index">
<dt>
<a href="#introduction">Introduction</a>
</dt>
<dt>
<a href="#interface">Interface</a>
</dt>
<dd>
<dl class="page-index">
<dt>
<a href="#indexing_suite">indexing_suite</a>
</dt>
<dt>
<a href="#indexing_suite_subclasses">indexing_suite
sub-classes</a>
</dt>
<dd>
<dl class="page-index">
<dt>
<a href="#vector_indexing_suite">vector_indexing_suite</a>
</dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<dl>
<dt>
<a href="#indexing_suite_class">indexing_suite class</a>
</dt>
<dt>
<a href="#vector_indexing_suite_class">vector_indexing_suite
class</a>
</dt>
</dl>
<hr>
<h2>
<a name="introduction" id="introduction"></a>Introduction
</h2>
<p>
Indexing is a Boost Python facility for easy exportation of indexable
C++ containers to Python. Indexable containers are containers that
allow random access through the operator[] (e.g. std::vector).
</p>
<p>
While Boost Python has all the facilities needed to expose indexable
C++ containers such as the ubiquitous std::vector to Python, the
procedure is not as straightforward as we'd like it to be. Python
containers do not map easily to C++ containers. Emulating Python
containers in C++ (see Python Reference Manual, <a href=
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
container types</a>) using Boost Python is non trivial. There are a lot
of issues to consider before we can map a C++ container to Python.
These involve implementing wrapper functions for the methods
<strong>__len__</strong>, <strong>__getitem__</strong>,
<strong>__setitem__</strong>, <strong>__delitem__,</strong>
<strong>__iter__</strong> and <strong>__contains</strong>.
</p>
<p>
The goals:
</p>
<ul>
<li>
<div>
Make indexable C++ containers behave exactly as one would expect a
Python container to behave.
</div>
</li>
<li>
Provide default reference semantics for container element indexing
(<tt>__getitem__</tt>) such that <tt>c[i]</tt> can be mutable.
Require:
<div>
<pre>
val = c[i]
c[i].m()
val == c[i]
</pre>
</div>where <tt>m</tt> is a non-const (mutating) member function
(method).
</li>
<li>
Return safe references from <tt>__getitem__</tt> such that subsequent
adds and deletes to and from the container will not result in
dangling references (will not crash Python).
</li>
<li>
Support slice indexes.
</li>
<li>
Accept Python container arguments (e.g. lists, tuples) wherever
appropriate.
</li>
<li>
Allow for extensibility through re-definable policy classes.
</li>
<li>
Provide predefined support for the most common STL and STL like
indexable containers.
</li>
</ul>
<hr>
<h2> <a name="interface"></a>The Boost.Python Indexing Interface</h2>
<h3> <a name="indexing_suite"></a>indexing_suite [ Header &lt;boost/python/indexing/indexing_suite.hpp&gt;
]</h3>
<p>
The <tt>indexing_suite</tt> class is the base protocol class for the
management of C++ containers intended to be integrated to Python. The
objective is make a C++ container look and feel and behave exactly as
we'd expect a Python container. The class automatically wraps these
special Python methods (taken from the Python reference: <a href=
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
container types</a>):
</p>
<dl>
<dd>
<dl>
<dt>
<b><a name="l2h-126"><tt class=
"method">__len__</tt></a></b>(<var>self</var>)
</dt>
<dd>
Called to implement the built-in function <tt class=
"function">len()</tt><a name="l2h-134">&nbsp;</a> Should return
the length of the object, an integer <code>&gt;=</code> 0. Also,
an object that doesn't define a <tt class=
"method">__nonzero__()</tt> method and whose <tt class=
"method">__len__()</tt> method returns zero is considered to be
false in a Boolean context. <a name="l2h-128">&nbsp;</a>
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-129"><tt class=
"method">__getitem__</tt></a></b>(<var>self, key</var>)
</dt>
<dd>
Called to implement evaluation of
<code><var>self</var>[<var>key</var>]</code>. For sequence types,
the accepted keys should be integers and slice
objects.<a name="l2h-135">&nbsp;</a> Note that the special
interpretation of negative indexes (if the class wishes to
emulate a sequence type) is up to the <tt class=
"method">__getitem__()</tt> method. If <var>key</var> is of
an inappropriate type, <tt class="exception">TypeError</tt>
may be raised; if of a value outside the set of indexes for
the sequence (after any special interpretation of negative
values), <tt class="exception">IndexError</tt> should be
raised. <span class="note"><b class="label">Note:</b>
<tt class="keyword">for</tt> loops expect that an <tt class=
"exception">IndexError</tt> will be raised for illegal
indexes to allow proper detection of the end of the
sequence.</span>
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-130"><tt class=
"method">__setitem__</tt></a></b>(<var>self, key, value</var>)
</dt>
<dd>
Called to implement assignment to
<code><var>self</var>[<var>key</var>]</code>. Same note as for
<tt class="method">__getitem__()</tt>. This should only be
implemented for mappings if the objects support changes to the
values for keys, or if new keys can be added, or for sequences if
elements can be replaced. The same exceptions should be raised
for improper <var>key</var> values as for the <tt class=
"method">__getitem__()</tt> method.
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-131"><tt class=
"method">__delitem__</tt></a></b>(<var>self, key</var>)
</dt>
<dd>
Called to implement deletion of
<code><var>self</var>[<var>key</var>]</code>. Same note as for
<tt class="method">__getitem__()</tt>. This should only be
implemented for mappings if the objects support removal of keys,
or for sequences if elements can be removed from the sequence.
The same exceptions should be raised for improper <var>key</var>
values as for the <tt class="method">__getitem__()</tt> method.
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-132"><tt class=
"method">__iter__</tt></a></b>(<var>self</var>)
</dt>
<dd>
This method is called when an iterator is required for a
container. This method should return a new iterator object that
can iterate over all the objects in the container. For mappings,
it should iterate over the keys of the container, and should also
be made available as the method <tt class=
"method">iterkeys()</tt>.
<p>
Iterator objects also need to implement this method; they are
required to return themselves. For more information on iterator
objects, see ``<a class="ulink" href=
"http://www.python.org/doc/current/lib/typeiter.html">Iterator
Types</a>'' in the <em class="citetitle"><a href=
"http://www.python.org/doc/current/lib/lib.html" title=
"Python Library Reference">Python Library Reference</a></em>.
</p>
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-133"><tt class=
"method">__contains__</tt></a></b>(<var>self, item</var>)
</dt>
<dd>
Called to implement membership test operators. Should return true
if <var>item</var> is in <var>self</var>, false otherwise. For
mapping objects, this should consider the keys of the mapping
rather than the values or the key-item pairs.
</dd>
</dl>
</dd>
</dl>
<h3> <a name="indexing_suite_subclasses"></a>indexing_suite sub-classes</h3>
<p>
The <tt>indexing_suite</tt> is not meant to be used as is. A couple of
policy functions must be supplied by subclasses of
<tt>indexing_suite</tt>. However, a set of <tt>indexing_suite</tt>
subclasses for the standard indexable STL containers will be provided,
In most cases, we can simply use the available predefined suites. In
some cases, we can refine the predefined suites to suit our needs.
</p>
<h3> <a name="vector_indexing_suite"></a>vector_indexing_suite [ Header &lt;boost/python/indexing/vector_indexing_suite.hpp&gt;
] </h3>
<p>
The <tt>vector_indexing_suite</tt> class is a predefined
<tt>indexing_suite</tt> derived class designed to wrap
<tt>std::vector</tt> (and <tt>std::vector</tt> like [i.e. a class with
std::vector interface]) classes (currently, this is the only predefined
suite available). It provides all the policies required by the
<tt>indexing_suite</tt>.
</p>
<p>
Example usage:
</p>
<pre>
class X {...};
...
class_&lt;std::vector&lt;X&gt; &gt;("XVec")
.def(vector_indexing_suite&lt;std::vector&lt;X&gt; &gt;())
;
</pre>
<p>
<tt>XVec</tt> is now a full-fledged Python container (see the
<a href="../../test/vector_indexing_suite.cpp">example in full</a>,
along with its <a href="../../test/vector_indexing_suite.py">python
test</a>).
</p>
<hr>
<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>
<table width="100%" border="1">
<tr>
<td>
<strong>Template Parameter</strong><br>
</td>
<td>
<strong>Requirements</strong>
</td>
<td>
<strong>Semantics</strong>
</td>
<td>
<strong>Default</strong>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Container</tt></font>
</td>
<td>
A class type
</td>
<td>
The container type to be wrapped to Python.
</td>
<td>&nbsp;
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>DerivedPolicies</tt></font>
</td>
<td>
A subclass of indexing_suite
</td>
<td>
Derived classes provide the policy hooks. See <a href=
"#DerivedPolicies">DerivedPolicies</a> below.
</td>
<td>&nbsp;
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>NoProxy</tt></font>
</td>
<td>
A boolean
</td>
<td>
By default indexed elements have Python reference semantics and are
returned by proxy. This can be disabled by supplying
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
</td>
<td>
false
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Element</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's element type.
</td>
<td>
<tt>Container::value_type</tt>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Key</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's key type.
</td>
<td>
<tt>Container::value_type</tt>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Index</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's index type.
</td>
<td>
<tt>Container::size_type</tt>
</td>
</tr>
</table>
<pre>
template &lt;<br> class Container
, class DerivedPolicies
, bool NoProxy = false
, class Element = typename Container::value_type
, class Key = typename Container::value_type
, class Index = typename Container::size_type
&gt;<br> class indexing_suite
: unspecified
{
public:
indexing_suite(); // default constructor
}
</pre>
<h2>
<tt><a name="DerivedPolicies"></a>DerivedPolicies</tt>
</h2>
<dl>
<dd>
Derived classes provide the hooks needed by
the<tt>indexing_suite:</tt>
</dd>
</dl>
<pre>
static element_type&amp;
get_item(Container&amp; container, index_type i);
static object
get_slice(Container&amp; container, index_type from, index_type to);
static void
set_item(Container&amp; container, index_type i, element_type const&amp; v);
static void
set_slice(
Container&amp; container, index_type from,
index_type to, element_type const&amp; v
);
template &lt;class Iter&gt;
static void<br> set_slice(Container&amp; container, index_type from,
index_type to, Iter first, Iter last
);
static void
delete_item(Container&amp; container, index_type i);
static void
delete_slice(Container&amp; container, index_type from, index_type to);
static size_t
size(Container&amp; container);
template &lt;class T&gt;
static bool
contains(Container&amp; container, T const&amp; val);
static index_type
convert_index(Container&amp; container, PyObject* i);
static index_type
adjust_index(index_type current, index_type from,
index_type to, size_type len
);
</pre>
<blockquote>
<p>
Most of these policies are self explanatory. <tt>However,
<strong>convert_index</strong></tt> and
<tt><strong>adjust_index</strong></tt> deserve some explanation.
</p>
<p>
<strong><tt>convert_index</tt></strong> converts a Python index into
a C++ index that the container can handle. For instance, negative
indexes in Python, by convention, start counting from the right(e.g.
<tt>C[-1]</tt> indexes the rightmost element in <tt>C</tt>).
<strong><tt>convert_index</tt></strong> should handle the necessary
conversion for the C++ container (e.g. convert <tt>-1</tt> to
<tt>C.size()-1</tt>). <tt><strong>convert_index</strong></tt> should
also be able to convert the type of the index (A dynamic Python type)
to the actual type that the C++ container expects.
</p>
<p>
When a container expands or contracts, held indexes to its elements
must be adjusted to follow the movement of data. For instance, if we
erase 3 elements, starting from index 0 from a 5 element vector, what
used to be at index 4 will now be at index 1:
</p>
<pre>
[a][b][c][d][e] ---&gt; [d][e]
^ ^
4 1
</pre>
<p>
<strong><tt>adjust_index</tt></strong> takes care of the adjustment.
Given a current index, the function should return the adjusted index
when data in the container at index <tt>from</tt>..<tt>to</tt> is
replaced by <tt>len</tt> elements.
</p>
</blockquote>
<div>
<hr>
<h2>
<a name="vector_indexing_suite_class"></a>vector_indexing_suite class
</h2>
<h3>
Class template <tt><br>
vector_indexing_suite&lt;<br>
class <font color="#007F00">Container</font><br>
, bool <font color="#007F00">NoProxy</font><br>
, class <font color="#007F00">DerivedPolicies</font>&gt;</tt>
</h3>
<table width="100%" border="1">
<tr>
<td>
<strong>Template Parameter</strong><br>
</td>
<td>
<strong>Requirements</strong>
</td>
<td>
<strong>Semantics</strong>
</td>
<td>
<strong>Default</strong>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Container</tt></font>
</td>
<td>
A class type
</td>
<td>
The container type to be wrapped to Python.
</td>
<td>&nbsp;
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>NoProxy</tt></font>
</td>
<td>
A boolean
</td>
<td>
By default indexed elements have Python reference semantics and
are returned by proxy. This can be disabled by supplying
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
</td>
<td>
false
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>DerivedPolicies</tt></font>
</td>
<td>
A subclass of indexing_suite
</td>
<td>
The <tt>vector_indexing_suite</tt> may still be derived to
further tweak any of the predefined policies. Static polymorphism
through CRTP (James Coplien. "Curiously Recurring Template
Pattern". C++ Report, Feb. 1995) enables the base
<tt>indexing_suite</tt> class to call policy function of the most
derived class
</td>
<td>&nbsp;
</td>
</tr>
</table>
<pre>
template &lt;<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite<br> : public indexing_suite&lt;Container, DerivedPolicies, NoProxy&gt;<br> {<br> public:<br><br> typedef typename Container::value_type element_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> static element_type&amp;<br> get_item(Container&amp; container, index_type i);
static object
get_slice(Container&amp; container, index_type from, index_type to);
static void<br> set_item(Container&amp; container, index_type i, element_type const&amp; v);
static void
set_slice(Container&amp; container, index_type from,
index_type to, element_type const&amp; v);
template &lt;class Iter&gt;<br> static void<br> set_slice(Container&amp; container, index_type from,<br> index_type to, Iter first, Iter last);
static void
delete_item(Container&amp; container, index_type i);
static void
delete_slice(Container&amp; container, index_type from, index_type to);<br>
static size_t
size(Container&amp; container);
static bool
contains(Container&amp; container, key_type const&amp; key);
static index_type
convert_index(Container&amp; container, PyObject* i);
static index_type
adjust_index(index_type current, index_type from,
index_type to, size_type len);
};
</pre>
<hr>
&copy; Copyright Joel de Guzman 2003. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided "as is" without
express or implied warranty, and with no claim as to its suitability
for any purpose.
</div>
</body>
</html>

View File

@@ -66,13 +66,9 @@ template &lt;class F, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies)
template &lt;class F, class Policies, class KeywordsOrSignature&gt;
template &lt;class F, class Policies, class Keywords&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, KeywordsOrSignature const&amp; ks)
template &lt;class F, class Policies, class Keywords, class Signature&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; kw, Signature const&amp; sig)
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; keywords)
</pre>
<dl class="function-semantics">
@@ -86,41 +82,19 @@ template &lt;class F, class Policies, class Keywords, class Signature&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>. <ul>
<li> 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>. If <code>policies</code> are supplied, it
will be applied to the function as described <a href=
"CallPolicies.html">here</a>.
<li>If <code>keywords</code> are
"CallPolicies.html">here</a>. If <code>keywords</code> are
supplied, the keywords will be applied in order to the final
arguments of the resulting function.
<li>If <code>Signature</code>
is supplied, it should be an instance of an <a
href="../../mpl/doc/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>
arguments of the resulting function.</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;

View File

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

View File

@@ -194,10 +194,9 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 1, 3)
BOOST_PYTHON_MODULE(args_ext)
{
def(&quot;f&quot;, f,
f_overloads(
args(&quot;x&quot;, &quot;y&quot;, &quot;z&quot;), &quot;This is f's docstring&quot;
));
def(&quot;f&quot;, f, args(&quot;x&quot;, &quot;y&quot;, &quot;z&quot;)
, &quot;This is f's docstring&quot;
);
class_&lt;Y&gt;(&quot;Y&quot;)
@@ -205,17 +204,16 @@ BOOST_PYTHON_MODULE(args_ext)
class_&lt;X&gt;(&quot;X&quot;, &quot;This is X's docstring&quot;)
.def(&quot;f1&quot;, &amp;X::f,
X_f_overloads(
args(&quot;x&quot;, &quot;y&quot;, &quot;z&quot;), &quot;f's docstring&quot;
)[return_internal_reference&lt;&gt;()]
)
X_f_overloads(args(&quot;x&quot;, &quot;y&quot;, &quot;z&quot;),
&quot;f's docstring&quot;
)[return_internal_reference&lt;&gt;()])
;
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
15 April, 2003
15 December, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,116 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/raw_function.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../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/raw_function.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#raw_function-spec">raw_function</a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code><a href="#raw_function-spec">raw_function</a>(...)</code>
is used to convert a function taking a <a
href="tuple.html#tuple-spec">tuple</a> and a <a
href="dict.html#dict-spec">dict</a> into a Python callable object
which accepts a variable number of arguments and arbitrary keyword
arguments.
<h2><a name="functions"></a>Functions</h2>
<a name="raw_function-spec"></a>raw_function
<pre>
template &lt;class F&gt;
object raw_function(F f, std::size_t min_args = 0);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>f(tuple(), dict())</code> is
well-formed.</dt>
<dt><b>Returns:</b> a <a href=
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">callable</a> object which requires at least <code>min_args</code> arguments. When called, the actual non-keyword arguments will be passed in a <a
href="tuple.html#tuple-spec">tuple</a> as the first argument to <code>f</code>, and the keyword arguments will be passed in a <a
href="dict.html#dict-spec">dict</a> as the second argument to <code>f</code>.
</dd>
</dl>
<h2><a name="examples"></a>Example</h2>
C++:
<pre>
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/tuple.hpp&gt;
#include &lt;boost/python/dict.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/raw_function.hpp&gt;
using namespace boost::python;
tuple raw(tuple args, dict kw)
{
return make_tuple(args, kw);
}
BOOST_PYTHON_MODULE(raw_test)
{
def("raw", raw_function(raw));
}
</pre>
Python:
<pre>
&gt;&gt;&gt; from raw_test import *
&gt;&gt;&gt; raw(3, 4, foo = 'bar', baz = 42)
((3, 4), {'foo': 'bar', 'baz': 42})
</pre>
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
7 March, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
</body>
</html>

View File

@@ -13,7 +13,7 @@
p.c3 {font-style: italic}
h2.c2 {text-align: center}
h1.c1 {text-align: center}
</style>
</style>
</head>
<body>
@@ -96,158 +96,193 @@
<h2><a name="high_level">High Level Components</a></h2>
<dl>
<dt><a href="class.html">class.hpp/class_fwd.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="class.html#classes">Classes</a></dt>
<dd>
<dl>
<dt><a href="class.html">class.hpp/class_fwd.hpp</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>
<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>
</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>
<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>
</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>
<dt><a href="enum.html">enum.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="enum.html#enum_-spec">enum_</a></dt>
<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>
</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>
<dt><a href="errors.html">errors.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
<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=
</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=
<dt><a href=
"errors.html#expect_non_null-spec">expect_non_null</a></dt>
<dt><a href=
<dt><a href=
"errors.html#throw_error_already_set-spec">throw_error_already_set</a></dt>
</dl>
</dd>
</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">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=
<dd>
<dl class="index">
<dt><a href=
"exception_translator.html#register_exception_translator-spec">register_exception_translator</a></dt>
</dl>
</dd>
</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>
<dt><a href="init.html">init.hpp</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>
<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>
</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>
<dt><a href="iterator.html">iterator.hpp</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>
<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="iterator.html#functions">Functions</a></dt>
<dd>
<dt><a href="module.html">module.hpp</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=
<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>
</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>
@@ -336,7 +371,7 @@
</dl>
</dd>
<dt><a href="tuple.html">tuple.hpp</a></dt>
<dt><a href="str.html">tuple.hpp</a></dt>
<dd>
<dl class="index">
@@ -535,24 +570,6 @@
</dl>
</dd>
<dt><a href="return_arg.html">return_arg.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href="return_arg.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"return_arg.html#return_arg-spec">return_arg</a></dt>
<dt><a href=
"return_arg.html#return_self-spec">return_self</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href=
"return_internal_reference.html">return_internal_reference.hpp</a></dt>
@@ -733,22 +750,21 @@
</dl>
</dd>
<dt><a href=
"return_opaque_pointer.html">return_opaque_pointer.hpp</a></dt>
<dt><a href="return_opaque_pointer.html">return_opaque_pointer.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"return_opaque_pointer.html#classes">Classes</a></dt>
<dt><a href="return_opaque_pointer.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"return_opaque_pointer.html#return_opaque_pointer-spec">return_opaque_pointer</a></dt>
<dt><a href="return_opaque_pointer.html#return_opaque_pointer-spec">
return_opaque_pointer</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
</dd>
</dl>
@@ -806,28 +822,24 @@
</dl>
</dd>
<dt><a href=
"opaque_pointer_converter.html">opaque_pointer_converter.hpp</a></dt>
<dt><a href="opaque_pointer_converter.html">opaque_pointer_converter.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"opaque_pointer_converter.html#classes">Classes</a></dt>
<dt><a href="opaque_pointer_converter.html#classes">Classes</a></dt>
<dd>
<dl class="index">
<dt><a href=
"opaque_pointer_converter.html#opaque_pointer_converter-spec">opaque_pointer_converter</a></dt>
<dt><a href="opaque_pointer_converter.html#opaque_pointer_converter-spec">
opaque_pointer_converter</a></dt>
</dl>
</dd>
<dt><a href="opaque_pointer_converter.html#macros">Macros</a></dt>
<dd>
<dl class="index">
<dt><a href=
"opaque_pointer_converter.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</a></dt>
<dt><a href="opaque_pointer_converter.html#BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID-spec">
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID</a></dt>
</dl>
</dd>
</dl>
@@ -847,23 +859,6 @@
</dd>
</dl>
</dd>
<dt><a href=
"register_ptr_to_python.html">register_ptr_to_python.hpp</a></dt>
<dd>
<dl class="index">
<dt><a href=
"register_ptr_to_python.html#functions">Functions</a></dt>
<dd>
<dl class="index">
<dt><a href=
"register_ptr_to_python.html#register_ptr_to_python-spec">register_ptr_to_python</a></dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<h2><a name="utility">Utility and Infrastructure</a></h2>
@@ -965,17 +960,18 @@
<h2><a name="topics">Topics</a></h2>
<dl>
<dt><a href="callbacks.html">Calling Python Functions and Methods</a></dt>
<dt><a href="pickle.html">Pickle Support</a><br>
<a href="containers.html">Indexing Support</a></dt>
</dl>
<dl>
<dt><a href="callbacks.html">Calling Python Functions and
Methods</a></dt>
<dt><a href="pickle.html">Pickle Support</a></dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
19 July, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
7 March, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p class="c3">&copy; Copyright <a href=

View File

@@ -1,160 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;register_ptr_to_python.hpp&gt;</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../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;register_ptr_to_python.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#functions">Functions</a></dt>
<dl class="page-index">
<dt><a href="#register_ptr_to_python-spec">register_ptr_to_python</a></dt>
</dl>
<dt><a href="#examples">Example(s)</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p>
<code>&lt;boost/python/register_ptr_to_python.hpp&gt;</code>
supplies <code>register_ptr_to_python</code>, a function template
which registers a conversion for smart pointers to Python. The
resulting Python object holds a copy of the converted smart pointer,
but behaves as though it were a wrapped copy of the pointee. If
the pointee type has virtual functions and the class representing
its dynamic (most-derived) type has been wrapped, the Python object
will be an instance of the wrapper for the most-derived type. More than
one smart pointer type for a pointee's class can be registered.
</p>
<p>
Note that in order to convert a Python <code>X</code> object to a
<code>smart_ptr&lt;X&gt;&amp;</code> (non-const reference), the embedded C++
object must be held by <code>smart_ptr&lt;X&gt;</code>, and that when wrapped
objects are created by calling the constructor from Python, how they are held
is determined by the <code>HeldType</code> parameter to
<code>class_&lt;...&gt;</code> instances.
</p>
<h2><a name="functions"></a>Functions</h2>
<pre>
<a name="register_ptr_to_python-spec">template &lt;class P&gt;
void register_ptr_to_python()
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>P</code> is the type of the smart pointer,
for example <code>smart_ptr&lt;X&gt;</code>.
</dt>
<dt><b>Effects:</b> Allows conversions to-python of <code>smart_ptr&lt;X&gt;</code>
instances.
</dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
<h3>C++ Wrapper Code</h3>
Here is an example of a module that contains a class <code>A</code> with
virtual functions and some functions that work with
<code>boost::shared_ptr&lt;A&gt;</code>.
<pre>
struct A
{
virtual int f() { return 0; }
};
shared_ptr&lt;A&gt; New() { return shared_ptr&lt;A&gt;( new A() ); }
int Ok( const shared_ptr&lt;A&gt;&amp; a ) { return a-&gt;f(); }
int Fail( shared_ptr&lt;A&gt;&amp; a ) { return a-&gt;f(); }
struct A_Wrapper: A
{
A_Wrapper(PyObject* self_): self(self_) {}
int f() { return call_method&lt;int&gt;(self, "f"); }
int default_f() { return A::f(); }
PyObject* self;
};
BOOST_PYTHON_MODULE(register_ptr)
{
class_&lt;A, A_Wrapper&gt;("A")
.def("f", &amp;A::f, &amp;A_Wrapper::default_f)
;
def("New", &amp;New);
def("Ok", &amp;Call);
def("Fail", &amp;Fail);
register_ptr_to_python&lt; shared_ptr&lt;A&gt; &gt;();
}
</pre>
<h3>Python Code</h3>
<pre>
&gt;&gt;&gt; from register_ptr import *
&gt;&gt;&gt; a = A()
&gt;&gt;&gt; Ok(a) # ok, passed as shared_ptr&lt;A&gt;
0
&gt;&gt;&gt; Fail(a) # passed as shared_ptr&lt;A&gt;&amp;, and was created in Python!
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in ?
TypeError: bad argument type for built-in operation
&gt;&gt;&gt;
&gt;&gt;&gt; na = New() # now "na" is actually a shared_ptr&lt;A&gt;
&gt;&gt;&gt; Ok(a)
0
&gt;&gt;&gt; Fail(a)
0
&gt;&gt;&gt;
</pre>
If <code>shared_ptr&lt;A&gt;</code> is registered as follows:
<pre>
class_&lt;A, A_Wrapper, shared_ptr&lt;A&gt; &gt;("A")
.def("f", &amp;A::f, &amp;A_Wrapper::default_f)
;
</pre>
There will be an error when trying to convert <code>shared_ptr&lt;A&gt;</code> to
<code>shared_ptr&lt;A_Wrapper&gt;</code>:
<pre>
&gt;&gt;&gt; a = New()
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in ?
TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr&lt;struct A&gt;
&gt;&gt;&gt;
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
24 Jun, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
2002. All Rights Reserved.</i></p>
</body>
</html>

View File

@@ -1,219 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/return_arg.hpp&gt;</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../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/return_arg.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#return_arg-spec">Class Template
<code>return_arg</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#return_arg-spec-synopsis">Class Template
<code>return_arg</code> synopsis</a></dt>
<dt><a href="#return_arg-spec-statics">Class
<code>return_arg</code> static functions</a></dt>
</dl>
</dd>
<dt><a href="#return_self-spec">Class Template
<code>return_self</code></a></dt>
</dl>
</dd>
<dt><a href="#examples">Example</a></dt>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<code>return_arg</code> and <code>return_self</code> instantiations are
models of <a href="CallPolicies.html">CallPolicies</a> which return the
specified argument parameter (usually <code>*this</code>) of a wrapped
(member) function.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="return_arg-spec"></a>Class template
<code>return_arg</code></h3>
<table border="1" summary="return_arg template parameters">
<caption>
<b><code>return_arg</code> template parameters</b>
</caption>
<tr>
<th>Parameter</th>
<th>Requirements</th>
<th>Description</th>
<th>Default</th>
</tr>
<tr>
<td><code>arg_pos</code></td>
<td>A positive compile-time constant of type
<code>std::size_t</code>.</td>
<td>the position of the argument to be returned.</td>
<td>1</td>
</tr>
<tr>
<td><code>Base</code></td>
<td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
<td>Used for policy composition. Any <code>result_converter</code> it
supplies will be overridden by <code>return_arg</code>, but its
<code>precall</code> and <code>postcall</code> policies are composed
as described here <a href=
"CallPolicies.html#composition">CallPolicies</a>.</td>
<td><code><a href=
"default_call_policies.html#default_call_policies-spec">default_call_policies</a></code></td>
</tr>
</table>
<h4><a name="return_arg-spec-synopsis"></a>Class template
<code>return_arg</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;size_t arg_pos=1, class Base = default_call_policies&gt;
struct return_arg : Base
{
static PyObject* postcall(PyObject*, PyObject* result);
struct result_converter{ template &lt;class T&gt; struct apply; };
};
}}
</pre>
<h4><a name="return_arg-spec-statics"></a>Class <code>return_arg</code>
static functions</h4>
<pre>
PyObject* postcall(PyObject* args, PyObject* result);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code><a href=
"http://www.python.org/doc/2.2/api/tupleObjects.html#l2h-476">PyTuple_Check</a>(args)
!= 0</code> and <code>PyTuple_Size(args) != 0</code></dt>
<dt><b>Returns:</b> <code>PyTuple_GetItem(args,arg_pos-1)</code></dt>
</dl>
<h3><a name="return_self-spec"></a>Class template
<code>return_self</code></h3>
<h4>Class template <code>return_self</code> synopsis:</h4>
<pre>
namespace boost { namespace python
{
template &lt;class Base = default_call_policies&gt;
struct return_self
: return_arg&lt;1,Base&gt;
{};
}}
</pre>
<h2><a name="examples"></a>Example</h2>
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/return_arg.hpp&gt;
struct Widget
{
Widget() :sensitive_(true){}
bool get_sensitive() const { return sensitive_; }
void set_sensitive(bool s) { this-&gt;sensitive_ = s; }
private:
bool sensitive_;
};
struct Label : Widget
{
Label() {}
std::string get_label() const { return label_; }
void set_label(const std::string &amp;l){ label_ = l; }
private:
std::string label_;
};
using namespace boost::python;
BOOST_PYTHON_MODULE(return_self_ext)
{
class_&lt;widget&gt;("Widget")
.def("sensitive", &amp;Widget::get_sensitive)
.def("sensitive", &amp;Widget::set_sensitive, return_self&lt;&gt;())
;
class_&lt;Label, bases&lt;Widget&gt; &gt;("Label")
.def("label", &amp;Label::get_label)
.def("label", &amp;Label::set_label, return_self&lt;&gt;())
;
}
</pre>
<h3>Python code</h3>
<pre>
&gt;&gt;&gt; from return_self_ext import *
&gt;&gt;&gt; l1 = Label().label("foo").sensitive(false)
&gt;&gt;&gt; l2 = Label().sensitive(false).label("foo")
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
19 July, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> and Nikolay
Mladenov 2003. All Rights Reserved.</i></p>
</body>
</html>

View File

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

View File

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

View File

@@ -2,9 +2,11 @@
use-project /boost/python : ../build ;
project
: requirements <library>/boost/python//boost_python
: requirements <library>@/boost/python/boost_python
;
python-extension getting_started1 : getting_started1.cpp : <link>shared ;
python-extension getting_started2 : getting_started2.cpp : <link>shared ;
python-extension getting_started1 : getting_started1.cpp : <shared>true ;
python-extension getting_started2 : getting_started2.cpp : <shared>true ;
exe embedding_test : embedding_test.cpp : <define>BOOST_PYTHON_DYNAMIC_LIB <shared>true ;

View File

@@ -1,7 +0,0 @@
# 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) ;

View File

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

View File

@@ -1,18 +0,0 @@
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

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

67
include/boost/python.hpp Normal file
View File

@@ -0,0 +1,67 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// See http://www.boost.org/libs/python for documentation.
#ifndef PYTHON_DWA2002810_HPP
# define PYTHON_DWA2002810_HPP
# include <boost/python/args.hpp>
# include <boost/python/args_fwd.hpp>
# include <boost/python/back_reference.hpp>
# include <boost/python/bases.hpp>
# include <boost/python/borrowed.hpp>
# include <boost/python/call.hpp>
# include <boost/python/call_method.hpp>
# include <boost/python/class.hpp>
# include <boost/python/copy_const_reference.hpp>
# include <boost/python/copy_non_const_reference.hpp>
# include <boost/python/data_members.hpp>
# include <boost/python/def.hpp>
# include <boost/python/default_call_policies.hpp>
# include <boost/python/dict.hpp>
# include <boost/python/enum.hpp>
# include <boost/python/errors.hpp>
# include <boost/python/exception_translator.hpp>
# include <boost/python/extract.hpp>
# include <boost/python/handle.hpp>
# include <boost/python/has_back_reference.hpp>
# include <boost/python/implicit.hpp>
# include <boost/python/init.hpp>
# include <boost/python/instance_holder.hpp>
# include <boost/python/iterator.hpp>
# include <boost/python/list.hpp>
# include <boost/python/long.hpp>
# include <boost/python/lvalue_from_pytype.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/manage_new_object.hpp>
# include <boost/python/module.hpp>
# include <boost/python/numeric.hpp>
# include <boost/python/object.hpp>
# include <boost/python/object_protocol.hpp>
# include <boost/python/object_protocol_core.hpp>
# include <boost/python/operators.hpp>
# include <boost/python/opaque_pointer_converter.hpp>
# include <boost/python/other.hpp>
# include <boost/python/overloads.hpp>
# include <boost/python/pointee.hpp>
# include <boost/python/ptr.hpp>
# include <boost/python/reference_existing_object.hpp>
# include <boost/python/return_internal_reference.hpp>
# include <boost/python/return_opaque_pointer.hpp>
# include <boost/python/return_value_policy.hpp>
# include <boost/python/scope.hpp>
# include <boost/python/self.hpp>
# include <boost/python/slice_nil.hpp>
# include <boost/python/str.hpp>
# include <boost/python/to_python_converter.hpp>
# include <boost/python/to_python_indirect.hpp>
# include <boost/python/to_python_value.hpp>
# include <boost/python/tuple.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/with_custodian_and_ward.hpp>
#endif // PYTHON_DWA2002810_HPP

View File

@@ -0,0 +1,84 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef ARG_FROM_PYTHON_DWA2002128_HPP
# define ARG_FROM_PYTHON_DWA2002128_HPP
# include <boost/python/converter/arg_from_python.hpp>
# include <boost/python/detail/indirect_traits.hpp>
namespace boost { namespace python {
template <class T>
struct arg_from_python
: converter::select_arg_from_python<T>::type
{
typedef typename converter::select_arg_from_python<T>::type base;
arg_from_python(PyObject*);
};
// specialization for PyObject*
template <>
struct arg_from_python<PyObject*>
{
typedef PyObject* result_type;
arg_from_python(PyObject*) {}
bool convertible() const { return true; }
PyObject* operator()(PyObject* source) const { return source; }
};
template <>
struct arg_from_python<PyObject* const&>
{
typedef PyObject* const& result_type;
arg_from_python(PyObject*) {}
bool convertible() const { return true; }
PyObject*const& operator()(PyObject*const& source) const { return source; }
};
namespace detail
{
//
// Meta-iterators for use with caller<>
//
// temporary hack
template <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
//
template <class T>
inline arg_from_python<T>::arg_from_python(PyObject* source)
: base(source)
{
}
}} // namespace boost::python
#endif // ARG_FROM_PYTHON_DWA2002128_HPP

View File

@@ -0,0 +1,112 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef KEYWORDS_DWA2002323_HPP
# define KEYWORDS_DWA2002323_HPP
# include <boost/python/args_fwd.hpp>
# include <boost/config.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/detail/type_list.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/remove_reference.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/preprocessor/enum_params.hpp>
# include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/facilities/intercept.hpp>
# include <boost/preprocessor/iteration/local.hpp>
# include <boost/python/detail/mpl_lambda.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/type.hpp>
# include <cstddef>
namespace boost { namespace python {
namespace detail
{
template <std::size_t nkeywords>
struct keywords
{
BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
keyword_range range() const
{
return keyword_range(elements, elements + nkeywords);
}
keyword elements[nkeywords];
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
struct is_keywords
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
template<std::size_t nkeywords>
struct is_keywords<keywords<nkeywords> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct is_reference_to_keywords
{
BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
typedef typename remove_reference<T>::type deref;
typedef typename remove_cv<deref>::type key_t;
BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
typedef mpl::bool_<value> type;
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
};
# else
typedef char (&yes_keywords_t)[1];
typedef char (&no_keywords_t)[2];
no_keywords_t is_keywords_test(...);
template<std::size_t nkeywords>
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords>&));
template<std::size_t nkeywords>
yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords> const&));
template<typename T>
class is_reference_to_keywords
{
public:
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(detail::is_keywords_test( (void (*)(T))0 ))
== sizeof(detail::yes_keywords_t)));
typedef mpl::bool_<value> type;
BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
};
# endif
}
# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
# define BOOST_PP_LOCAL_MACRO(n) \
inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
{ \
detail::keywords<n> result; \
BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
return result; \
}
# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY)
# include BOOST_PP_LOCAL_ITERATE()
}} // namespace boost::python
# endif // KEYWORDS_DWA2002323_HPP

View File

@@ -0,0 +1,47 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef ARGS_FWD_DWA2002927_HPP
# define ARGS_FWD_DWA2002927_HPP
# include <boost/python/handle.hpp>
# include <boost/config.hpp>
# include <cstddef>
# include <utility>
namespace boost { namespace python {
namespace detail
{
struct keyword
{
char const* name;
handle<> default_value;
};
template <std::size_t nkeywords = 0> struct keywords;
typedef std::pair<keyword const*, keyword const*> keyword_range;
template <>
struct keywords<0>
{
BOOST_STATIC_CONSTANT(std::size_t, size = 0);
static keyword_range range() { return keyword_range(); }
};
namespace error
{
template <int keywords, int function_args>
struct more_keywords_than_function_arguments
{
typedef char too_many_keywords[keywords > function_args ? -1 : 1];
};
}
}
}} // namespace boost::python
#endif // ARGS_FWD_DWA2002927_HPP

View File

@@ -0,0 +1,101 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BACK_REFERENCE_DWA2002510_HPP
# define BACK_REFERENCE_DWA2002510_HPP
# include <boost/python/object_fwd.hpp>
# include <boost/python/detail/dependent.hpp>
# include <boost/python/detail/raw_pyobject.hpp>
namespace boost { namespace python {
template <class T>
struct back_reference
{
private: // types
typedef typename detail::dependent<object,T>::type source_t;
public:
typedef T type;
back_reference(PyObject*, T);
source_t const& source() const;
T get() const;
private:
source_t m_source;
T m_value;
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
class is_back_reference
{
public:
BOOST_STATIC_CONSTANT(bool, value = false);
};
template<typename T>
class is_back_reference<back_reference<T> >
{
public:
BOOST_STATIC_CONSTANT(bool, value = true);
};
# else // no partial specialization
}} // namespace boost::python
#include <boost/type.hpp>
namespace boost { namespace python {
namespace detail
{
typedef char (&yes_back_reference_t)[1];
typedef char (&no_back_reference_t)[2];
no_back_reference_t is_back_reference_test(...);
template<typename T>
yes_back_reference_t is_back_reference_test(boost::type< back_reference<T> >);
}
template<typename T>
class is_back_reference
{
public:
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(detail::is_back_reference_test(boost::type<T>()))
== sizeof(detail::yes_back_reference_t)));
};
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//
// implementations
//
template <class T>
back_reference<T>::back_reference(PyObject* p, T x)
: m_source(detail::borrowed_reference(p))
, m_value(x)
{
}
template <class T>
typename back_reference<T>::source_t const& back_reference<T>::source() const
{
return m_source;
}
template <class T>
T back_reference<T>::get() const
{
return m_value;
}
}} // namespace boost::python
#endif // BACK_REFERENCE_DWA2002510_HPP

View File

@@ -0,0 +1,36 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BASE_TYPE_TRAITS_DWA2002614_HPP
# define BASE_TYPE_TRAITS_DWA2002614_HPP
namespace boost { namespace python {
namespace detail
{
struct unspecialized {};
}
// Derive from unspecialized so we can detect whether traits are
// specialized
template <class T> struct base_type_traits
: detail::unspecialized
{};
template <>
struct base_type_traits<PyObject>
{
typedef PyObject type;
};
template <>
struct base_type_traits<PyTypeObject>
{
typedef PyObject type;
};
}} // namespace boost::python
#endif // BASE_TYPE_TRAITS_DWA2002614_HPP

View File

@@ -0,0 +1,67 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BASES_DWA2002321_HPP
# define BASES_DWA2002321_HPP
# include <boost/type_traits/object_traits.hpp>
# include <boost/python/detail/type_list.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/preprocessor/enum_params_with_a_default.hpp>
# include <boost/preprocessor/enum_params.hpp>
namespace boost { namespace python {
# define BOOST_PYTHON_BASE_PARAMS BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, Base)
// A type list for specifying bases
template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename Base, mpl::void_) >
struct bases : detail::type_list< BOOST_PYTHON_BASE_PARAMS >::type
{};
namespace detail
{
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T> struct specifies_bases
: mpl::false_
{
};
template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class Base) >
struct specifies_bases< bases< BOOST_PYTHON_BASE_PARAMS > >
: mpl::true_
{
};
# else
template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class Base) >
static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&);
static char (& is_bases_helper(...) )[256];
template <class T>
struct specifies_bases
{
private:
static typename add_reference<T>::type make();
BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference<T>::value);
public:
BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1));
typedef mpl::bool_<value> type;
};
# endif
template <class T, class Prev = bases<> >
struct select_bases
: mpl::if_<
specifies_bases<T>
, T
, Prev
>
{
};
}
# undef BOOST_PYTHON_BASE_PARAMS
}} // namespace boost::python
#endif // BASES_DWA2002321_HPP

View File

@@ -0,0 +1,20 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BORROWED_DWA2002614_HPP
# define BORROWED_DWA2002614_HPP
# include <boost/python/detail/borrowed_ptr.hpp>
namespace boost { namespace python {
template <class T>
inline python::detail::borrowed<T>* borrowed(T* p)
{
return (detail::borrowed<T>*)p;
}
}} // namespace boost::python
#endif // BORROWED_DWA2002614_HPP

View File

@@ -0,0 +1,66 @@
#if !defined(BOOST_PP_IS_ITERATING)
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# ifndef CALL_DWA2002411_HPP
# define CALL_DWA2002411_HPP
# include <boost/type.hpp>
# include <boost/python/converter/arg_to_python.hpp>
# include <boost/python/converter/return_from_python.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/detail/void_return.hpp>
# include <boost/preprocessor/comma_if.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/debug/line.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
namespace boost { namespace python {
# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \
, converter::arg_to_python<A##n>(a##n).get()
# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/call.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET
}} // namespace boost::python
# endif // CALL_DWA2002411_HPP
#elif BOOST_PP_ITERATION_DEPTH() == 1
# line BOOST_PP_LINE(__LINE__, call.hpp)
# define N BOOST_PP_ITERATION()
template <
class R
BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)
>
typename detail::returnable<R>::type
call(PyObject* callable
BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)
, boost::type<R>* = 0
)
{
converter::return_from_python<R> converter;
return converter(
PyEval_CallFunction(
callable
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
));
}
# undef N
#endif

View File

@@ -0,0 +1,66 @@
#if !defined(BOOST_PP_IS_ITERATING)
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# ifndef CALL_METHOD_DWA2002411_HPP
# define CALL_METHOD_DWA2002411_HPP
# include <boost/type.hpp>
# include <boost/python/converter/arg_to_python.hpp>
# include <boost/python/converter/return_from_python.hpp>
# include <boost/python/detail/preprocessor.hpp>
# include <boost/python/detail/void_return.hpp>
# include <boost/preprocessor/comma_if.hpp>
# include <boost/preprocessor/iterate.hpp>
# include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/debug/line.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
namespace boost { namespace python {
# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \
, converter::arg_to_python<A##n>(a##n).get()
# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/call_method.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET
}} // namespace boost::python
# endif // CALL_METHOD_DWA2002411_HPP
#elif BOOST_PP_ITERATION_DEPTH() == 1
# line BOOST_PP_LINE(__LINE__, call_method.hpp)
# define N BOOST_PP_ITERATION()
template <
class R
BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)
>
typename detail::returnable<R>::type
call_method(PyObject* self, char const* name
BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)
, boost::type<R>* = 0
)
{
converter::return_from_python<R> converter;
return converter(
PyEval_CallMethod(
self
, const_cast<char*>(name)
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
));
}
# undef N
#endif // BOOST_PP_IS_ITERATING

106
include/boost/python/cast.hpp Executable file
View File

@@ -0,0 +1,106 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CAST_DWA200269_HPP
# define CAST_DWA200269_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/type_traits/same_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type.hpp>
# include <boost/python/base_type_traits.hpp>
# include <boost/python/detail/convertible.hpp>
namespace boost { namespace python {
namespace detail
{
template <class Source, class Target> inline Target* upcast_impl(Source*, Target*);
template <class Source, class Target>
inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*)
{
return p;
}
template <class Source, class Target>
inline Target* upcast(Source* p, no_convertible, no_convertible, Target*)
{
typedef typename base_type_traits<Source>::type base;
return detail::upcast_impl((base*)p, (Target*)0);
}
template <bool is_same = true>
struct upcaster
{
template <class T>
static inline T* execute(T* x, T*) { return x; }
};
template <>
struct upcaster<false>
{
template <class Source, class Target>
static inline Target* execute(Source* x, Target*)
{
return detail::upcast(
x, detail::convertible<Target*>::check(x)
, detail::convertible<Source*>::check((Target*)0)
, (Target*)0);
}
};
template <class Target, class Source>
inline Target* downcast(Source* p, yes_convertible)
{
return static_cast<Target*>(p);
}
template <class Target, class Source>
inline Target* downcast(Source* p, no_convertible, boost::type<Target>* = 0)
{
typedef typename base_type_traits<Source>::type base;
return (Target*)detail::downcast<base>(p, convertible<Source*>::check((base*)0));
}
template <class T>
inline void assert_castable(boost::type<T>* = 0)
{
typedef char must_be_a_complete_type[sizeof(T)];
}
template <class Source, class Target>
inline Target* upcast_impl(Source* x, Target*)
{
typedef typename add_cv<Source>::type src_t;
typedef typename add_cv<Target>::type target_t;
static bool const same = is_same<src_t,target_t>::value;
return detail::upcaster<same>::execute(x, (Target*)0);
}
}
template <class Target, class Source>
inline Target* upcast(Source* x, Target* = 0)
{
detail::assert_castable<Source>();
detail::assert_castable<Target>();
return detail::upcast_impl(x, (Target*)0);
}
template <class Target, class Source>
inline Target* downcast(Source* x, Target* = 0)
{
detail::assert_castable<Source>();
detail::assert_castable<Target>();
return detail::downcast<Target>(x, detail::convertible<Source*>::check((Target*)0));
}
}} // namespace boost::python
#endif // CAST_DWA200269_HPP

View File

@@ -0,0 +1,548 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_DWA200216_HPP
# define CLASS_DWA200216_HPP
# include <boost/python/class_fwd.hpp>
# include <boost/python/object/class.hpp>
# include <boost/python/bases.hpp>
# include <boost/python/object.hpp>
# include <boost/python/type_id.hpp>
# include <boost/python/data_members.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/signature.hpp>
# include <boost/python/init.hpp>
# include <boost/python/args_fwd.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_member_function_pointer.hpp>
# include <boost/type_traits/is_polymorphic.hpp>
# include <boost/mpl/size.hpp>
# include <boost/mpl/for_each.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/mpl/not.hpp>
# include <boost/mpl/or.hpp>
# include <boost/python/object/select_holder.hpp>
# include <boost/python/object/class_wrapper.hpp>
# include <boost/python/object/make_instance.hpp>
# include <boost/python/object/pickle_support.hpp>
# include <boost/python/object/add_to_namespace.hpp>
# include <boost/python/object/class_converters.hpp>
# include <boost/python/detail/string_literal.hpp>
# 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>
# include <boost/utility.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python {
enum no_init_t { no_init };
namespace detail
{
// This function object is used with mpl::for_each to write the id
// of the type a pointer to which is passed as its 2nd compile-time
// argument. into the iterator pointed to by its runtime argument
struct write_type_id
{
write_type_id(type_info**p) : p(p) {}
// Here's the runtime behavior
template <class T>
void operator()(T*) const
{
*(*p)++ = type_id<T>();
}
type_info** p;
};
template <class T, class Prev = detail::not_specified>
struct select_held_type;
template <class T1, class T2, class T3>
struct has_noncopyable;
template <detail::operator_id, class L, class R>
struct operator_;
// Register to_python converters for a class T. The first argument
// will be mpl::true_ unless noncopyable was specified as a
// class_<...> template parameter. The 2nd argument is a pointer to
// the type of holder that must be created. The 3rd argument is a
// reference to the Python type object to be created.
template <class T, class SelectHolder>
inline void register_class_to_python(mpl::true_, SelectHolder, T* = 0)
{
typedef typename SelectHolder::type holder;
force_instantiate(objects::class_cref_wrapper<T, objects::make_instance<T,holder> >());
SelectHolder::register_();
}
template <class T, class SelectHolder>
inline void register_class_to_python(mpl::false_, SelectHolder, T* = 0)
{
SelectHolder::register_();
}
namespace error
{
//
// A meta-assertion mechanism which prints nice error messages and
// backtraces on lots of compilers. Usage:
//
// assertion<C>::failed
//
// where C is an MPL metafunction class
//
template <class C> struct assertion_failed { };
template <class C> struct assertion_ok { typedef C failed; };
template <class C>
struct assertion
: mpl::if_<C, assertion_ok<C>, assertion_failed<C> >::type
{};
//
// Checks for validity of arguments used to define virtual
// functions with default implementations.
//
template <class Default>
void not_a_derived_class_member(Default) {}
template <class T, class Fn>
struct virtual_function_default
{
template <class Default>
static void
must_be_derived_class_member(Default const&)
{
typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
typedef typename assertion<is_polymorphic<T> >::failed test1;
# endif
typedef typename assertion<is_member_function_pointer<Fn> >::failed test2;
not_a_derived_class_member<Default>(Fn());
}
};
}
}
// This is the primary mechanism through which users will expose
// C++ classes to Python.
template <
class T // class being wrapped
, class X1 // = detail::not_specified
, class X2 // = detail::not_specified
, class X3 // = detail::not_specified
>
class class_ : public objects::class_base
{
public: // types
typedef objects::class_base base;
typedef T wrapped_type;
typedef class_<T,X1,X2,X3> self;
BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable<X1,X2,X3>::value));
typedef typename detail::select_held_type<
X1, typename detail::select_held_type<
X2, typename detail::select_held_type<
X3
>::type>::type>::type held_type;
typedef objects::select_holder<T,held_type> holder_selector;
private: // types
typedef typename detail::select_bases<X1
, typename detail::select_bases<X2
, typename boost::python::detail::select_bases<X3>::type
>::type
>::type bases;
// A helper class which will contain an array of id objects to be
// passed to the base class constructor
struct id_vector
{
id_vector()
{
// Stick the derived class id into the first element of the array
ids[0] = type_id<T>();
// Write the rest of the elements into succeeding positions.
type_info* p = ids + 1;
mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer<mpl::_>*)0);
}
BOOST_STATIC_CONSTANT(
std::size_t, size = mpl::size<bases>::value + 1);
type_info ids[size];
};
friend struct id_vector;
public: // constructors
// Construct with the class name, with or without docstring, and default __init__() function
class_(char const* name, char const* doc = 0);
// Construct with class name, no docstring, and an uncallable __init__ function
class_(char const* name, no_init_t);
// Construct with class name, docstring, and an uncallable __init__ function
class_(char const* name, char const* doc, no_init_t);
// Construct with class name and init<> function
template <class DerivedT>
inline class_(char const* name, init_base<DerivedT> const& i)
: base(name, id_vector::size, id_vector().ids)
{
this->register_();
define_init(*this, i.derived());
this->set_instance_size(holder_selector::additional_size());
}
// Construct with class name, docstring and init<> function
template <class DerivedT>
inline class_(char const* name, char const* doc, init_base<DerivedT> const& i)
: base(name, id_vector::size, id_vector().ids, doc)
{
this->register_();
define_init(*this, i.derived());
this->set_instance_size(holder_selector::additional_size());
}
public: // member functions
// Define additional constructors
template <class DerivedT>
self& def(init_base<DerivedT> const& i)
{
define_init(*this, i.derived());
return *this;
}
// Wrap a member function or a non-member function which can take
// a T, T cv&, or T cv* as its first parameter, or a callable
// python object.
template <class F>
self& def(char const* name, F f)
{
this->def_impl(name, f, detail::def_helper<char const*>(0), &f);
return *this;
}
template <class A1, class A2>
self& def(char const* name, A1 a1, A2 const& a2)
{
this->def_maybe_overloads(name, a1, a2, &a2);
return *this;
}
template <class Fn, class A1, class A2>
self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2)
{
// The arguments are definitely:
// def(name, function, policy, doc_string)
// def(name, function, doc_string, policy)
this->def_impl(
name, fn
, detail::def_helper<A1,A2>(a1,a2)
, &fn);
return *this;
}
template <class Fn, class A1, class A2, class A3>
self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3)
{
this->def_impl(
name, fn
, detail::def_helper<A1,A2,A3>(a1,a2,a3)
, &fn);
return *this;
}
template <detail::operator_id id, class L, class R>
self& def(detail::operator_<id,L,R> const& op)
{
typedef detail::operator_<id,L,R> op_t;
return this->def(op.name(), &op_t::template apply<T>::execute);
}
//
// Data member access
//
template <class D, class B>
self& def_readonly(char const* name, D B::*pm_)
{
D T::*pm = pm_;
this->add_property(name, make_getter(pm));
return *this;
}
template <class D, class B>
self& def_readwrite(char const* name, D B::*pm_)
{
D T::*pm = pm_;
return this->add_property(name, make_getter(pm), make_setter(pm));
}
// Property creation
template <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)
)
);
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)
)
);
return *this;
}
template <class U>
self& setattr(char const* name, U const& x)
{
this->base::setattr(name, object(x));
return *this;
}
// Pickle support
template <typename PickleSuiteType>
self& def_pickle(PickleSuiteType const& x)
{
error_messages::must_be_derived_from_pickle_suite(x);
detail::pickle_suite_finalize<PickleSuiteType>::register_(
*this,
&PickleSuiteType::getinitargs,
&PickleSuiteType::getstate,
&PickleSuiteType::setstate,
PickleSuiteType::getstate_manages_dict());
return *this;
}
self& staticmethod(char const* name)
{
this->make_method_static(name);
return *this;
}
private: // helper functions
inline void register_() const;
//
// These two overloads discriminate between def() as applied to
// things which are already wrapped into callable python::object
// instances and everything else.
//
template <class F, class A1>
inline void def_impl(
char const* name
, F f
, detail::def_helper<A1> const& helper
, object const*)
{
// It's too late to specify anything other than docstrings, if
// the callable object is already wrapped.
BOOST_STATIC_ASSERT(
(is_same<char const*,A1>::value
|| detail::is_string_literal<A1>::value));
objects::add_to_namespace(*this, name, f, helper.doc());
}
template <class Fn, class Helper>
inline void def_impl(
char const* name
, Fn fn
, Helper const& helper
, ...)
{
objects::add_to_namespace(
*this, name,
make_function(
// This bit of nastiness casts F to a member function of T if possible.
detail::member_function_cast<T,Fn>::stage1(fn).stage2((T*)0).stage3(fn)
, helper.policies(), helper.keywords())
, 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.
//
template <class Fn, class Helper>
inline void def_default(
char const* name
, Fn fn
, Helper const& helper
, mpl::bool_<true>)
{
detail::error::virtual_function_default<T,Fn>::must_be_derived_class_member(
helper.default_implementation());
objects::add_to_namespace(
*this, name,
make_function(
helper.default_implementation(), helper.policies(), helper.keywords())
);
}
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
// regular functions and def() as applied to the result of
// BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
// discriminate.
//
template <class OverloadsT, class SigT>
void def_maybe_overloads(
char const* name
, SigT sig
, OverloadsT const& overloads
, detail::overloads_base const*)
{
// convert sig to a type_list (see detail::get_signature in signature.hpp)
// before calling detail::define_with_defaults.
detail::define_with_defaults(
name, overloads, *this, detail::get_signature(sig));
}
template <class Fn, class A1>
void def_maybe_overloads(
char const* name
, Fn fn
, A1 const& a1
, ...)
{
this->def_impl(
name, fn
, detail::def_helper<A1>(a1)
, &fn);
}
};
//
// implementations
//
// register converters
template <class T, class X1, class X2, class X3>
inline void class_<T,X1,X2,X3>::register_() const
{
objects::register_class_from_python<T,bases>();
detail::register_class_to_python<T>(
mpl::bool_<is_copyable>()
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
, holder_selector::execute((held_type*)0)
# elif BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
, holder_selector::type()
# else
, typename holder_selector::type()
# endif
);
}
template <class T, class X1, class X2, class X3>
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc)
: base(name, id_vector::size, id_vector().ids, doc)
{
this->register_();
this->set_instance_size(holder_selector::additional_size());
# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
holder_selector::execute((held_type*)0).assert_default_constructible();
# else
holder_selector::type::assert_default_constructible();
# endif
this->def(init<>());
}
template <class T, class X1, class X2, class X3>
inline class_<T,X1,X2,X3>::class_(char const* name, no_init_t)
: base(name, id_vector::size, id_vector().ids)
{
this->register_();
this->def_no_init();
}
template <class T, class X1, class X2, class X3>
inline class_<T,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
: base(name, id_vector::size, id_vector().ids, doc)
{
this->register_();
this->def_no_init();
}
namespace detail
{
template <class T1, class T2, class T3>
struct has_noncopyable
: mpl::or_<
is_same<T1,noncopyable>
, is_same<T2,noncopyable>
, is_same<T3,noncopyable>
>
{};
template <class T, class Prev>
struct select_held_type
: mpl::if_<
mpl::or_<
specifies_bases<T>
, is_same<T,noncopyable>
>
, Prev
, T
>
{
};
}
}} // namespace boost::python
#endif // CLASS_DWA200216_HPP

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CLASS_FWD_DWA200222_HPP
# define CLASS_FWD_DWA200222_HPP
# include <boost/python/detail/not_specified.hpp>
namespace boost { namespace python {
template <
class T // class being wrapped
// arbitrarily-ordered optional arguments. Full qualification needed for MSVC6
, class X1 = ::boost::python::detail::not_specified
, class X2 = ::boost::python::detail::not_specified
, class X3 = ::boost::python::detail::not_specified
>
class class_;
}} // namespace boost::python
#endif // CLASS_FWD_DWA200222_HPP

View File

@@ -0,0 +1,341 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef ARG_FROM_PYTHON_DWA2002127_HPP
# define ARG_FROM_PYTHON_DWA2002127_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/registered_pointee.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/python/back_reference.hpp>
# include <boost/python/detail/referent_storage.hpp>
# include <boost/python/converter/obj_mgr_arg_from_python.hpp>
namespace boost { namespace python
{
template <class T> struct arg_from_python;
}}
// This header defines Python->C++ function argument converters,
// parametrized on the argument type.
namespace boost { namespace python { namespace converter {
//
// lvalue converters
//
// These require that an lvalue of the type U is stored somewhere in
// the Python object being converted.
// Used when T == U*const&
template <class T>
struct pointer_cref_arg_from_python
{
typedef T result_type;
pointer_cref_arg_from_python(PyObject*);
T operator()(PyObject*) const;
bool convertible() const;
private: // storage for a U*
// needed because not all compilers will let us declare U* as the
// return type of operator() -- we return U*const& instead
typename python::detail::referent_storage<T>::type m_result;
};
// Base class for pointer and reference converters
struct arg_lvalue_from_python_base
{
public: // member functions
arg_lvalue_from_python_base(void* result);
bool convertible() const;
protected: // member functions
void*const& result() const;
private: // data members
void* m_result;
};
// Used when T == U*
template <class T>
struct pointer_arg_from_python : arg_lvalue_from_python_base
{
typedef T result_type;
pointer_arg_from_python(PyObject*);
T operator()(PyObject*) const;
};
// Used when T == U& and (T != V const& or T == W volatile&)
template <class T>
struct reference_arg_from_python : arg_lvalue_from_python_base
{
typedef T result_type;
reference_arg_from_python(PyObject*);
T operator()(PyObject*) const;
};
// ===================
//
// rvalue converters
//
// These require only that an object of type T can be created from
// the given Python object, but not that the T object exist
// somewhere in storage.
//
// Used when T is a plain value (non-pointer, non-reference) type or
// a (non-volatile) const reference to a plain value type.
template <class T>
struct arg_rvalue_from_python
{
typedef typename boost::add_reference<
T
// We can't add_const here, or it would be impossible to pass
// auto_ptr<U> args from Python to C++
>::type result_type;
arg_rvalue_from_python(PyObject*);
bool convertible() const;
# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
typename arg_rvalue_from_python<T>::
# endif
result_type operator()(PyObject*);
private:
rvalue_from_python_data<result_type> m_data;
};
// ==================
// Converts to a (PyObject*,T) bundle, for when you need a reference
// back to the Python object
template <class T>
struct back_reference_arg_from_python
: boost::python::arg_from_python<typename T::type>
{
typedef T result_type;
back_reference_arg_from_python(PyObject*);
T operator()(PyObject*);
private:
typedef boost::python::arg_from_python<typename T::type> base;
};
// ==================
// This metafunction selects the appropriate arg_from_python converter
// type for an argument of type T.
template <class T>
struct select_arg_from_python
{
BOOST_STATIC_CONSTANT(
bool, obj_mgr = is_object_manager<T>::value);
BOOST_STATIC_CONSTANT(
bool, obj_mgr_ref = is_reference_to_object_manager<T>::value);
BOOST_STATIC_CONSTANT(
bool, ptr = is_pointer<T>::value);
BOOST_STATIC_CONSTANT(
bool, ptr_cref
= boost::python::detail::is_reference_to_pointer<T>::value
&& boost::python::detail::is_reference_to_const<T>::value
&& !boost::python::detail::is_reference_to_volatile<T>::value);
BOOST_STATIC_CONSTANT(
bool, ref =
boost::python::detail::is_reference_to_non_const<T>::value
|| boost::python::detail::is_reference_to_volatile<T>::value);
BOOST_STATIC_CONSTANT(
bool, back_ref =
boost::python::is_back_reference<T>::value);
typedef typename mpl::if_c<
obj_mgr
, object_manager_value_arg_from_python<T>
, typename mpl::if_c<
obj_mgr_ref
, object_manager_ref_arg_from_python<T>
, typename mpl::if_c<
ptr
, pointer_arg_from_python<T>
, typename mpl::if_c<
ptr_cref
, pointer_cref_arg_from_python<T>
, typename mpl::if_c<
ref
, reference_arg_from_python<T>
, typename mpl::if_c<
back_ref
, back_reference_arg_from_python<T>
, arg_rvalue_from_python<T>
>::type
>::type
>::type
>::type
>::type
>::type type;
};
// ==================
//
// implementations
//
// arg_lvalue_from_python_base
//
inline arg_lvalue_from_python_base::arg_lvalue_from_python_base(void* result)
: m_result(result)
{
}
inline bool arg_lvalue_from_python_base::convertible() const
{
return m_result != 0;
}
inline void*const& arg_lvalue_from_python_base::result() const
{
return m_result;
}
// pointer_cref_arg_from_python
//
namespace detail
{
// null_ptr_reference -- a function returning a reference to a null
// pointer of type U. Needed so that extractors for T*const& can
// convert Python's None.
template <class T>
struct null_ptr_owner
{
static T value;
};
template <class T> T null_ptr_owner<T>::value = 0;
template <class U>
inline U& null_ptr_reference(U&(*)())
{
return null_ptr_owner<U>::value;
}
}
template <class T>
inline pointer_cref_arg_from_python<T>::pointer_cref_arg_from_python(PyObject* p)
{
// T == U*const&: store a U* in the m_result storage. Nonzero
// indicates success. If find returns nonzero, it's a pointer to
// a U object.
python::detail::write_void_ptr_reference(
m_result.bytes
, p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters)
, (T(*)())0);
}
template <class T>
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
{
return (p == Py_None) // None ==> 0
? detail::null_ptr_reference((T(*)())0)
// Otherwise, return a U*const& to the m_result storage.
: python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0);
}
// pointer_arg_from_python
//
template <class T>
inline pointer_arg_from_python<T>::pointer_arg_from_python(PyObject* p)
: arg_lvalue_from_python_base(
p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee<T>::converters))
{
}
template <class T>
inline T pointer_arg_from_python<T>::operator()(PyObject* p) const
{
return (p == Py_None) ? 0 : T(result());
}
// reference_arg_from_python
//
template <class T>
inline reference_arg_from_python<T>::reference_arg_from_python(PyObject* p)
: arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered<T>::converters))
{
}
template <class T>
inline T reference_arg_from_python<T>::operator()(PyObject*) const
{
return python::detail::void_ptr_to_reference(result(), (T(*)())0);
}
// arg_rvalue_from_python
//
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))
{
}
template <class T>
inline bool arg_rvalue_from_python<T>::convertible() const
{
return m_data.stage1.convertible != 0;
}
template <class T>
inline typename arg_rvalue_from_python<T>::result_type
arg_rvalue_from_python<T>::operator()(PyObject* p)
{
if (m_data.stage1.construct != 0)
m_data.stage1.construct(p, &m_data.stage1);
return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0);
}
// back_reference_arg_from_python
//
template <class T>
back_reference_arg_from_python<T>::back_reference_arg_from_python(PyObject* x)
: base(x)
{
}
template <class T>
inline T
back_reference_arg_from_python<T>::operator()(PyObject* x)
{
return T(x, base::operator()(x));
}
}}} // namespace boost::python::converter
#endif // ARG_FROM_PYTHON_DWA2002127_HPP

View File

@@ -0,0 +1,262 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef ARG_TO_PYTHON_DWA200265_HPP
# define ARG_TO_PYTHON_DWA200265_HPP
# include <boost/python/ptr.hpp>
# include <boost/python/tag.hpp>
# include <boost/python/to_python_indirect.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/registered_pointee.hpp>
# include <boost/python/converter/arg_to_python_base.hpp>
# include <boost/python/converter/shared_ptr_to_python.hpp>
// Bring in specializations
# include <boost/python/converter/builtin_converters.hpp>
# include <boost/python/object/function_handle.hpp>
# include <boost/python/base_type_traits.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/python/detail/convertible.hpp>
# include <boost/python/detail/string_literal.hpp>
# include <boost/python/detail/value_is_shared_ptr.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/type_traits/composite_traits.hpp>
# include <boost/type_traits/function_traits.hpp>
# include <boost/mpl/or.hpp>
namespace boost { namespace python { namespace converter {
template <class T> struct is_object_manager;
namespace detail
{
template <class T>
struct function_arg_to_python : handle<>
{
function_arg_to_python(T const& x);
};
template <class T>
struct reference_arg_to_python : handle<>
{
reference_arg_to_python(T& x);
private:
static PyObject* get_object(T& x);
};
template <class T>
struct shared_ptr_arg_to_python : handle<>
{
shared_ptr_arg_to_python(T const& x);
private:
static PyObject* get_object(T& x);
};
template <class T>
struct value_arg_to_python : arg_to_python_base
{
// Throw an exception if the conversion can't succeed
value_arg_to_python(T const&);
};
template <class Ptr>
struct pointer_deep_arg_to_python : arg_to_python_base
{
// Throw an exception if the conversion can't succeed
pointer_deep_arg_to_python(Ptr);
};
template <class Ptr>
struct pointer_shallow_arg_to_python : handle<>
{
// Throw an exception if the conversion can't succeed
pointer_shallow_arg_to_python(Ptr);
private:
static PyObject* get_object(Ptr p);
};
// Convert types that manage a Python object to_python
template <class T>
struct object_manager_arg_to_python
{
object_manager_arg_to_python(T const& x) : m_src(x) {}
PyObject* get() const
{
return python::upcast<PyObject>(get_managed_object(m_src, tag));
}
private:
T const& m_src;
};
template <class T>
struct select_arg_to_python
{
typedef typename unwrap_reference<T>::type unwrapped_referent;
typedef typename unwrap_pointer<T>::type unwrapped_ptr;
typedef typename mpl::if_<
// Special handling for char const[N]; interpret them as char
// const* for the sake of conversion
python::detail::is_string_literal<T const>
, arg_to_python<char const*>
, typename mpl::if_<
python::detail::value_is_shared_ptr<T>
, shared_ptr_arg_to_python<T>
, typename mpl::if_<
mpl::or_<
is_function<T>
, python::detail::is_pointer_to_function<T>
, is_member_function_pointer<T>
>
, function_arg_to_python<T>
, typename mpl::if_<
is_object_manager<T>
, object_manager_arg_to_python<T>
, typename mpl::if_<
is_pointer<T>
, pointer_deep_arg_to_python<T>
, typename mpl::if_<
is_pointer_wrapper<T>
, pointer_shallow_arg_to_python<unwrapped_ptr>
, typename mpl::if_<
is_reference_wrapper<T>
, reference_arg_to_python<unwrapped_referent>
, value_arg_to_python<T>
>::type
>::type
>::type
>::type
>::type
>::type
>::type
type;
};
}
template <class T>
struct arg_to_python
: detail::select_arg_to_python<T>::type
{
typedef typename detail::select_arg_to_python<T>::type base;
public: // member functions
// Throw an exception if the conversion can't succeed
arg_to_python(T const& x);
};
//
// implementations
//
namespace detail
{
// reject_raw_object_ptr -- cause a compile-time error if the user
// should pass a raw Python object pointer
using python::detail::yes_convertible;
using python::detail::no_convertible;
using python::detail::unspecialized;
template <class T> struct cannot_convert_raw_PyObject;
template <class T, class Convertibility>
struct reject_raw_object_helper
{
static void error(Convertibility)
{
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
}
static void error(...) {}
};
template <class T>
inline void reject_raw_object_ptr(T*)
{
reject_raw_object_helper<T,yes_convertible>::error(
python::detail::convertible<PyObject const volatile*>::check((T*)0));
typedef typename remove_cv<T>::type value_type;
reject_raw_object_helper<T,no_convertible>::error(
python::detail::convertible<unspecialized*>::check(
(base_type_traits<value_type>*)0
));
}
// ---------
template <class T>
inline function_arg_to_python<T>::function_arg_to_python(T const& x)
: handle<>(python::objects::make_function_handle(x))
{
}
template <class T>
inline value_arg_to_python<T>::value_arg_to_python(T const& x)
: arg_to_python_base(&x, registered<T>::converters)
{
}
template <class Ptr>
inline pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr x)
: arg_to_python_base(x, registered_pointee<Ptr>::converters)
{
detail::reject_raw_object_ptr((Ptr)0);
}
template <class T>
inline PyObject* reference_arg_to_python<T>::get_object(T& x)
{
to_python_indirect<T&,python::detail::make_reference_holder> convert;
return convert(x);
}
template <class T>
inline reference_arg_to_python<T>::reference_arg_to_python(T& x)
: handle<>(reference_arg_to_python<T>::get_object(x))
{
}
template <class T>
inline shared_ptr_arg_to_python<T>::shared_ptr_arg_to_python(T const& x)
: handle<>(shared_ptr_to_python(x))
{
}
template <class Ptr>
inline pointer_shallow_arg_to_python<Ptr>::pointer_shallow_arg_to_python(Ptr x)
: handle<>(pointer_shallow_arg_to_python<Ptr>::get_object(x))
{
detail::reject_raw_object_ptr((Ptr)0);
}
template <class Ptr>
inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)
{
to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
return convert(x);
}
}
template <class T>
inline arg_to_python<T>::arg_to_python(T const& x)
: base(x)
{}
}}} // namespace boost::python::converter
#endif // ARG_TO_PYTHON_DWA200265_HPP

View File

@@ -0,0 +1,34 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef ARG_TO_PYTHON_BASE_DWA200237_HPP
# define ARG_TO_PYTHON_BASE_DWA200237_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/handle.hpp>
namespace boost { namespace python { namespace converter {
struct registration;
namespace detail
{
struct BOOST_PYTHON_DECL arg_to_python_base
# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179
: handle<>
# endif
{
arg_to_python_base(void const volatile* source, registration const&);
# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102179
PyObject* get() const { return m_ptr.get(); }
PyObject* release() { return m_ptr.release(); }
private:
handle<> m_ptr;
# endif
};
}
}}} // namespace boost::python::converter
#endif // ARG_TO_PYTHON_BASE_DWA200237_HPP

View File

@@ -0,0 +1,50 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
# define AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
# include <boost/python/converter/to_python_function_type.hpp>
namespace boost { namespace python { namespace converter {
// Given a typesafe to_python conversion function, produces a
// to_python_function_t which can be registered in the usual way.
template <class T, class ToPython>
struct as_to_python_function
{
// Assertion functions used to prevent wrapping of converters
// which take non-const reference parameters. The T* argument in
// the first overload ensures it isn't used in case T is a
// reference.
template <class U>
static int convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0);
template <class U>
static int convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...);
static PyObject* convert(void const* x)
{
BOOST_STATIC_ASSERT(
sizeof(
convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L))
== sizeof(int));
// Yes, the const_cast below opens a hole in const-correctness,
// but it's needed to convert auto_ptr<U> to python.
//
// How big a hole is it? It allows ToPython::convert() to be
// a function which modifies its argument. The upshot is that
// client converters applied to const objects may invoke
// undefined behavior. The damage, however, is limited by the
// use of the assertion function. Thus, the only way this can
// modify its argument is if T is an auto_ptr-like type. There
// is still a const-correctness hole w.r.t. auto_ptr<U> const,
// but c'est la vie.
return ToPython::convert(*const_cast<T*>(static_cast<T const*>(x)));
}
};
}}} // namespace boost::python::converter
#endif // AS_TO_PYTHON_FUNCTION_DWA2002121_HPP

View File

@@ -0,0 +1,132 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP
# define BUILTIN_CONVERTERS_DWA2002124_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/python/handle.hpp>
# include <string>
# include <complex>
# include <boost/limits.hpp>
// Since all we can use to decide how to convert an object to_python
// is its C++ type, there can be only one such converter for each
// type. Therefore, for built-in conversions we can bypass registry
// lookups using explicit specializations of arg_to_python and
// result_to_python.
namespace boost { namespace python {
namespace converter
{
template <class T> struct arg_to_python;
BOOST_PYTHON_DECL PyObject* do_return_to_python(char);
BOOST_PYTHON_DECL PyObject* do_return_to_python(char const*);
BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject*);
BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject*);
}
// Provide specializations of to_python_value
template <class T> struct to_python_value;
namespace detail
{
// Since there's no registry lookup, always report the existence of
// a converter.
struct builtin_to_python
{
// This information helps make_getter() decide whether to try to
// return an internal reference or not. I don't like it much,
// but it will have to serve for now.
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
};
}
// Use expr to create the PyObject corresponding to x
# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \
template <> struct to_python_value<T&> \
: detail::builtin_to_python \
{ \
inline PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
}; \
template <> struct to_python_value<T const&> \
: detail::builtin_to_python \
{ \
inline PyObject* operator()(T const& x) const \
{ \
return (expr); \
} \
};
# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \
namespace converter \
{ \
template <> struct arg_to_python< T > \
: handle<> \
{ \
arg_to_python(T const& x) \
: python::handle<>(expr) {} \
}; \
}
// Specialize argument and return value converters for T using expr
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \
BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
// Specialize converters for signed and unsigned T to Python Int
# define BOOST_PYTHON_TO_INT(T) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \
BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
unsigned T \
, static_cast<unsigned long>(x) > static_cast<unsigned long>( \
std::numeric_limits<long>::max()) \
? PyLong_FromUnsignedLong(x) \
: PyInt_FromLong(x))
// Bool is not signed.
BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x))
// note: handles signed char and unsigned char, but not char (see below)
BOOST_PYTHON_TO_INT(char)
BOOST_PYTHON_TO_INT(short)
BOOST_PYTHON_TO_INT(int)
BOOST_PYTHON_TO_INT(long)
// using Python's macro instead of Boost's - we don't seem to get the
// config right all the time.
# ifdef HAVE_LONG_LONG
BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, PyLong_FromLongLong(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong(x))
# endif
# undef BOOST_TO_PYTHON_INT
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromStringAndSize(x.c_str(),x.size()))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x))
BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x))
BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex<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()))
namespace converter
{
void initialize_builtin_converters();
}
}} // namespace boost::python::converter
#endif // BUILTIN_CONVERTERS_DWA2002124_HPP

View File

@@ -0,0 +1,18 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CONSTRUCTOR_FUNCTION_DWA200278_HPP
# define CONSTRUCTOR_FUNCTION_DWA200278_HPP
namespace boost { namespace python { namespace converter {
// Declares the type of functions used to construct C++ objects for
// rvalue from_python conversions.
struct rvalue_from_python_stage1_data;
typedef void (*constructor_function)(PyObject* source, rvalue_from_python_stage1_data*);
}}} // namespace boost::python::converter
#endif // CONSTRUCTOR_FUNCTION_DWA200278_HPP

View File

@@ -0,0 +1,15 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CONVERTIBLE_FUNCTION_DWA200278_HPP
# define CONVERTIBLE_FUNCTION_DWA200278_HPP
namespace boost { namespace python { namespace converter {
typedef void* (*convertible_function)(PyObject*);
}}} // namespace boost::python::converter
#endif // CONVERTIBLE_FUNCTION_DWA200278_HPP

View File

@@ -0,0 +1,43 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FIND_FROM_PYTHON_DWA2002223_HPP
# define FIND_FROM_PYTHON_DWA2002223_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
namespace boost { namespace python { namespace converter {
struct registration;
BOOST_PYTHON_DECL void* get_lvalue_from_python(
PyObject* source, registration const&);
BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python(
PyObject* source, registration const&);
BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
PyObject* source, registration const&);
BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
PyObject* source, rvalue_from_python_stage1_data&, registration const&);
BOOST_PYTHON_DECL void* rvalue_result_from_python(
PyObject*, rvalue_from_python_stage1_data&);
BOOST_PYTHON_DECL void* reference_result_from_python(PyObject*, registration const&);
BOOST_PYTHON_DECL void* pointer_result_from_python(PyObject*, registration const&);
BOOST_PYTHON_DECL void void_result_from_python(PyObject*);
BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject*, registration const&);
BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject*, registration const&);
}}} // namespace boost::python::converter
#endif // FIND_FROM_PYTHON_DWA2002223_HPP

View File

@@ -0,0 +1,43 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef IMPLICIT_DWA2002326_HPP
# define IMPLICIT_DWA2002326_HPP
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/registrations.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/extract.hpp>
namespace boost { namespace python { namespace converter {
template <class Source, class Target>
struct implicit
{
static void* convertible(PyObject* obj)
{
// Find a converter which can produce a Source instance from
// obj. The user has told us that Source can be converted to
// Target, and instantiating construct() below, ensures that
// at compile-time.
return implicit_rvalue_convertible_from_python(obj, registered<Source>::converters)
? obj : 0;
}
static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
{
void* storage = ((rvalue_from_python_storage<Target>*)data)->storage.bytes;
new (storage) Target(extract<Source>(obj)());
// record successful construction
data->convertible = storage;
}
};
}}} // namespace boost::python::converter
#endif // IMPLICIT_DWA2002326_HPP

View File

@@ -0,0 +1,122 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/detail/referent_storage.hpp>
# include <boost/python/detail/destroy.hpp>
# include <boost/python/detail/construct.hpp>
# include <boost/python/converter/object_manager.hpp>
# include <boost/python/detail/raw_pyobject.hpp>
# include <boost/python/tag.hpp>
//
// arg_from_python converters for Python type wrappers, to be used as
// base classes for specializations.
//
namespace boost { namespace python { namespace converter {
template <class T>
struct object_manager_value_arg_from_python
{
typedef T result_type;
object_manager_value_arg_from_python(PyObject*);
bool convertible() const;
T operator()(PyObject*) const;
private:
PyObject* m_source;
};
// Used for converting reference-to-object-manager arguments from
// python. The process used here is a little bit odd. Upon
// construction, we build the object manager object in the m_result
// object, *forcing* it to accept the source Python object by casting
// its pointer to detail::borrowed_reference. This is supposed to
// bypass any type checking of the source object. The convertible
// check then extracts the owned object and checks it. If the check
// fails, nothing else in the program ever gets to touch this strange
// "forced" object.
template <class Ref>
struct object_manager_ref_arg_from_python
{
typedef Ref result_type;
object_manager_ref_arg_from_python(PyObject*);
bool convertible() const;
Ref operator()(PyObject*) const;
~object_manager_ref_arg_from_python();
private:
typename python::detail::referent_storage<Ref>::type m_result;
};
//
// implementations
//
template <class T>
inline object_manager_value_arg_from_python<T>::object_manager_value_arg_from_python(PyObject* x)
: m_source(x)
{
}
template <class T>
inline bool object_manager_value_arg_from_python<T>::convertible() const
{
return object_manager_traits<T>::check(m_source);
}
template <class T>
inline T object_manager_value_arg_from_python<T>::operator()(PyObject* x) const
{
return T(python::detail::borrowed_reference(x));
}
template <class Ref>
inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_python(PyObject* x)
{
# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
// needed for warning suppression
python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x);
python::detail::construct_referent<Ref>(&m_result.bytes, x_);
# else
python::detail::construct_referent<Ref>(&m_result.bytes, (python::detail::borrowed_reference)x);
# endif
}
template <class Ref>
inline object_manager_ref_arg_from_python<Ref>::~object_manager_ref_arg_from_python()
{
python::detail::destroy_referent<Ref>(this->m_result.bytes);
}
namespace detail
{
template <class T>
inline bool object_manager_ref_check(T const& x)
{
return object_manager_traits<T>::check(get_managed_object(x, tag));
}
}
template <class Ref>
inline bool object_manager_ref_arg_from_python<Ref>::convertible() const
{
return detail::object_manager_ref_check(
python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0));
}
template <class Ref>
inline Ref object_manager_ref_arg_from_python<Ref>::operator()(PyObject*) const
{
return python::detail::void_ptr_to_reference(
this->m_result.bytes, (Ref(*)())0);
}
}}} // namespace boost::python::converter
#endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP

View File

@@ -0,0 +1,231 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef OBJECT_MANAGER_DWA2002614_HPP
# define OBJECT_MANAGER_DWA2002614_HPP
# include <boost/python/handle.hpp>
# include <boost/python/cast.hpp>
# include <boost/python/converter/pyobject_traits.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/bool.hpp>
// Facilities for dealing with types which always manage Python
// objects. Some examples are object, list, str, et. al. Different
// to_python/from_python conversion rules apply here because in
// contrast to other types which are typically embedded inside a
// Python object, these are wrapped around a Python object. For most
// object managers T, a C++ non-const T reference argument does not
// imply the existence of a T lvalue embedded in the corresponding
// Python argument, since mutating member functions on T actually only
// modify the held Python object.
//
// handle<T> is an object manager, though strictly speaking it should
// not be. In other words, even though mutating member functions of
// hanlde<T> actually modify the handle<T> and not the T object,
// handle<T>& arguments of wrapped functions will bind to "rvalues"
// wrapping the actual Python argument, just as with other object
// manager classes. Making an exception for handle<T> is simply not
// worth the trouble.
//
// borrowed<T> cv* is an object manager so that we can use the general
// to_python mechanisms to convert raw Python object pointers to
// python, without the usual semantic problems of using raw pointers.
// Object Manager Concept requirements:
//
// T is an Object Manager
// p is a PyObject*
// x is a T
//
// * object_manager_traits<T>::is_specialized == true
//
// * T(detail::borrowed_reference(p))
// Manages p without checking its type
//
// * get_managed_object(x, boost::python::tag)
// Convertible to PyObject*
//
// Additional requirements if T can be converted from_python:
//
// * T(object_manager_traits<T>::adopt(p))
// steals a reference to p, or throws a TypeError exception if
// p doesn't have an appropriate type. May assume p is non-null
//
// * X::check(p)
// convertible to bool. True iff T(X::construct(p)) will not
// throw.
// Forward declarations
//
namespace boost { namespace python
{
namespace api
{
class object;
}
}}
namespace boost { namespace python { namespace converter {
// Specializations for handle<T>
template <class T>
struct handle_object_manager_traits
: pyobject_traits<typename T::element_type>
{
private:
typedef pyobject_traits<typename T::element_type> base;
public:
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
// Initialize with a null_ok pointer for efficiency, bypassing the
// null check since the source is always non-null.
static null_ok<typename T::element_type>* adopt(PyObject* p)
{
return python::allow_null(base::checked_downcast(p));
}
};
template <class T>
struct default_object_manager_traits
{
BOOST_STATIC_CONSTANT(
bool, is_specialized = python::detail::is_borrowed_ptr<T>::value
);
};
template <class T>
struct object_manager_traits
: mpl::if_c<
is_handle<T>::value
, handle_object_manager_traits<T>
, default_object_manager_traits<T>
>::type
{
};
//
// Traits for detecting whether a type is an object manager or a
// (cv-qualified) reference to an object manager.
//
template <class T>
struct is_object_manager
: mpl::bool_<object_manager_traits<T>::is_specialized>
{
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct is_reference_to_object_manager
: mpl::false_
{
};
template <class T>
struct is_reference_to_object_manager<T&>
: is_object_manager<T>
{
};
template <class T>
struct is_reference_to_object_manager<T const&>
: is_object_manager<T>
{
};
template <class T>
struct is_reference_to_object_manager<T volatile&>
: is_object_manager<T>
{
};
template <class T>
struct is_reference_to_object_manager<T const volatile&>
: is_object_manager<T>
{
};
# else
namespace detail
{
typedef char (&yes_reference_to_object_manager)[1];
typedef char (&no_reference_to_object_manager)[2];
// A number of nastinesses go on here in order to work around MSVC6
// bugs.
template <class T>
struct is_object_manager_help
{
typedef typename mpl::if_<
is_object_manager<T>
, yes_reference_to_object_manager
, no_reference_to_object_manager
>::type type;
// If we just use the type instead of the result of calling this
// function, VC6 will ICE.
static type call();
};
// A set of overloads for each cv-qualification. The same argument
// is passed twice: the first one is used to unwind the cv*, and the
// second one is used to avoid relying on partial ordering for
// overload resolution.
template <class U>
typename is_object_manager_help<U>
is_object_manager_helper(U*, void*);
template <class U>
typename is_object_manager_help<U>
is_object_manager_helper(U const*, void const*);
template <class U>
typename is_object_manager_help<U>
is_object_manager_helper(U volatile*, void volatile*);
template <class U>
typename is_object_manager_help<U>
is_object_manager_helper(U const volatile*, void const volatile*);
template <class T>
struct is_reference_to_object_manager_nonref
: mpl::false_
{
};
template <class T>
struct is_reference_to_object_manager_ref
{
static T sample_object;
BOOST_STATIC_CONSTANT(
bool, value
= (sizeof(is_object_manager_helper(&sample_object, &sample_object).call())
== sizeof(detail::yes_reference_to_object_manager)
)
);
typedef mpl::bool_<value> type;
};
}
template <class T>
struct is_reference_to_object_manager
: mpl::if_<
is_reference<T>
, detail::is_reference_to_object_manager_ref<T>
, detail::is_reference_to_object_manager_nonref<T>
>::type
{
};
# endif
}}} // namespace boost::python::converter
#endif // OBJECT_MANAGER_DWA2002614_HPP

View File

@@ -0,0 +1,69 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef POINTER_TYPE_ID_DWA2002222_HPP
# define POINTER_TYPE_ID_DWA2002222_HPP
# include <boost/python/type_id.hpp>
# include <boost/type_traits/composite_traits.hpp>
namespace boost { namespace python { namespace converter {
namespace detail
{
template <bool is_ref = false>
struct pointer_typeid_select
{
template <class T>
static inline type_info execute(T*(*)() = 0)
{
return type_id<T>();
}
};
template <>
struct pointer_typeid_select<true>
{
template <class T>
static inline type_info execute(T* const volatile&(*)() = 0)
{
return type_id<T>();
}
template <class T>
static inline type_info execute(T*volatile&(*)() = 0)
{
return type_id<T>();
}
template <class T>
static inline type_info execute(T*const&(*)() = 0)
{
return type_id<T>();
}
template <class T>
static inline type_info execute(T*&(*)() = 0)
{
return type_id<T>();
}
};
}
// Usage: pointer_type_id<T>()
//
// Returns a type_info associated with the type pointed
// to by T, which may be a pointer or a reference to a pointer.
template <class T>
type_info pointer_type_id(T(*)() = 0)
{
return detail::pointer_typeid_select<
is_reference<T>::value
>::execute((T(*)())0);
}
}}} // namespace boost::python::converter
#endif // POINTER_TYPE_ID_DWA2002222_HPP

View File

@@ -0,0 +1,42 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef PYOBJECT_TRAITS_DWA2002720_HPP
# define PYOBJECT_TRAITS_DWA2002720_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/pyobject_type.hpp>
namespace boost { namespace python { namespace converter {
template <class> struct pyobject_traits;
template <>
struct pyobject_traits<PyObject>
{
// All objects are convertible to PyObject
static bool check(PyObject*) { return true; }
static PyObject* checked_downcast(PyObject* x) { return x; }
};
//
// Specializations
//
# define BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(T) \
template <> struct pyobject_traits<Py##T##Object> \
: pyobject_type<Py##T##Object, &Py##T##_Type> {}
// This is not an exhaustive list; should be expanded.
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple);
}}} // namespace boost::python::converter
#endif // PYOBJECT_TRAITS_DWA2002720_HPP

View File

@@ -0,0 +1,37 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef PYOBJECT_TYPE_DWA2002720_HPP
# define PYOBJECT_TYPE_DWA2002720_HPP
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/cast.hpp>
namespace boost { namespace python { namespace converter {
BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*);
// Used as a base class for specializations which need to provide
// Python type checking capability.
template <class Object, PyTypeObject* pytype>
struct pyobject_type
{
static bool check(PyObject* x)
{
return ::PyObject_IsInstance(x, (PyObject*)pytype);
}
static Object* checked_downcast(PyObject* x)
{
return python::downcast<Object>(
(checked_downcast_impl)(x, pytype)
);
}
};
}}} // namespace boost::python::converter
#endif // PYOBJECT_TYPE_DWA2002720_HPP

View File

@@ -0,0 +1,99 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all 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/wrap_python.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

@@ -0,0 +1,43 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
# define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP
# include <boost/python/detail/raw_pyobject.hpp>
# include <boost/python/cast.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/pyobject_type.hpp>
# include <boost/python/errors.hpp>
namespace boost { namespace python { namespace converter {
// Provide a forward declaration as a convenience for clients, who all
// need it.
template <class T> struct object_manager_traits;
// Derive specializations of object_manager_traits from this class
// when T is an object manager for a particular Python type hierarchy.
//
template <PyTypeObject* pytype, class T>
struct pytype_object_manager_traits
: pyobject_type<T, pytype> // provides check()
{
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
static inline python::detail::new_reference adopt(PyObject*);
};
//
// implementations
//
template <PyTypeObject* pytype, class T>
inline python::detail::new_reference pytype_object_manager_traits<pytype,T>::adopt(PyObject* x)
{
return python::detail::new_reference(python::pytype_check(pytype, x));
}
}}} // namespace boost::python::converter
#endif // PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP

View File

@@ -0,0 +1,54 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REGISTERED_DWA2002710_HPP
# define REGISTERED_DWA2002710_HPP
# include <boost/python/type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/python/converter/registrations.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
namespace boost { namespace python { namespace converter {
struct registration;
namespace detail
{
template <class T>
struct registered_base
{
static registration const& converters;
};
}
template <class T>
struct registered
: detail::registered_base<
typename add_reference<
typename add_cv<T>::type
>::type
>
{
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// collapses a few more types to the same static instance
template <class T>
struct registered<T&> : registered<T> {};
# endif
//
// implementations
//
namespace detail
{
template <class T>
registration const& registered_base<T>::converters
= registry::lookup(type_id<T>());
}
}}} // namespace boost::python::converter
#endif // REGISTERED_DWA2002710_HPP

View File

@@ -0,0 +1,63 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REGISTERED_POINTEE_DWA2002710_HPP
# define REGISTERED_POINTEE_DWA2002710_HPP
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/pointer_type_id.hpp>
# include <boost/python/converter/registry.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
namespace boost { namespace python { namespace converter {
struct registration;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct registered_pointee
: registered<
typename remove_pointer<
typename remove_cv<
typename remove_reference<T>::type
>::type
>::type
>
{
};
# else
namespace detail
{
template <class T>
struct registered_pointee_base
{
static registration const& converters;
};
}
template <class T>
struct registered_pointee
: detail::registered_pointee_base<
typename add_reference<
typename add_cv<T>::type
>::type
>
{
};
//
// implementations
//
namespace detail
{
template <class T>
registration const& registered_pointee_base<T>::converters
= registry::lookup(pointer_type_id<T>());
}
# endif
}}} // namespace boost::python::converter
#endif // REGISTERED_POINTEE_DWA2002710_HPP

View File

@@ -0,0 +1,85 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REGISTRATIONS_DWA2002223_HPP
# define REGISTRATIONS_DWA2002223_HPP
# include <boost/python/type_id.hpp>
# include <boost/python/converter/convertible_function.hpp>
# include <boost/python/converter/constructor_function.hpp>
# include <boost/python/converter/to_python_function_type.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python { namespace converter {
struct lvalue_from_python_chain
{
convertible_function convert;
lvalue_from_python_chain* next;
};
struct rvalue_from_python_chain
{
convertible_function convertible;
constructor_function construct;
rvalue_from_python_chain* next;
};
struct BOOST_PYTHON_DECL registration
{
public: // member functions
explicit registration(type_info);
// Convert the appropriately-typed data to Python
PyObject* to_python(void const volatile*) const;
// Return the class object, or raise an appropriate Python
// exception if no class has been registered.
PyTypeObject* get_class_object() const;
public: // data members. So sue me.
const python::type_info target_type;
// The chain of eligible from_python converters when an lvalue is required
lvalue_from_python_chain* lvalue_chain;
// The chain of eligible from_python converters when an rvalue is acceptable
rvalue_from_python_chain* rvalue_chain;
// The class object associated with this type
PyTypeObject* m_class_object;
// The unique to_python converter for the associated C++ type.
to_python_function_t m_to_python;
# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
private:
void operator=(registration); // This is not defined, and just keeps MWCW happy.
# endif
};
//
// implementations
//
inline registration::registration(type_info target_type)
: target_type(target_type)
, lvalue_chain(0)
, rvalue_chain(0)
, m_class_object(0)
, m_to_python(0)
{}
inline bool operator<(registration const& lhs, registration const& rhs)
{
return lhs.target_type < rhs.target_type;
}
}}} // namespace boost::python::converter
#endif // REGISTRATIONS_DWA2002223_HPP

View File

@@ -0,0 +1,52 @@
// Copyright David Abrahams 2001. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef REGISTRY_DWA20011127_HPP
# define REGISTRY_DWA20011127_HPP
# include <boost/python/type_id.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/python/converter/to_python_function_type.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/constructor_function.hpp>
# include <boost/python/converter/convertible_function.hpp>
namespace boost { namespace python { namespace converter {
struct registration;
// This namespace acts as a sort of singleton
namespace registry
{
// Get the registration corresponding to the type, creating it if neccessary
BOOST_PYTHON_DECL registration const& lookup(type_info);
// Return a pointer to the corresponding registration, if one exists
BOOST_PYTHON_DECL registration const* query(type_info);
BOOST_PYTHON_DECL void insert(to_python_function_t, type_info);
// Insert an lvalue from_python converter
BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info);
// Insert an rvalue from_python converter
BOOST_PYTHON_DECL void insert(
convertible_function
, constructor_function
, type_info
);
// Insert an rvalue from_python converter at the tail of the
// chain. Used for implicit conversions
BOOST_PYTHON_DECL void push_back(
convertible_function
, constructor_function
, type_info
);
}
}}} // namespace boost::python::converter
#endif // REGISTRY_DWA20011127_HPP

View File

@@ -0,0 +1,161 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef RETURN_FROM_PYTHON_DWA200265_HPP
# define RETURN_FROM_PYTHON_DWA200265_HPP
# include <boost/python/converter/from_python.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
# include <boost/python/converter/registered.hpp>
# include <boost/python/converter/registered_pointee.hpp>
# include <boost/python/detail/void_ptr.hpp>
# include <boost/python/detail/void_return.hpp>
# include <boost/python/errors.hpp>
# include <boost/type_traits/has_trivial_copy.hpp>
# include <boost/mpl/and.hpp>
# include <boost/mpl/bool.hpp>
namespace boost { namespace python { namespace converter {
template <class T> struct is_object_manager;
namespace detail
{
template <class T>
struct return_pointer_from_python
{
typedef T result_type;
T operator()(PyObject*) const;
};
template <class T>
struct return_reference_from_python
{
typedef T result_type;
T operator()(PyObject*) const;
};
template <class T>
struct return_rvalue_from_python
{
typedef T result_type;
return_rvalue_from_python();
result_type operator()(PyObject*);
private:
rvalue_from_python_data<T> m_data;
};
template <class T>
struct return_object_manager_from_python
{
typedef T result_type;
result_type operator()(PyObject*) const;
};
template <class T>
struct select_return_from_python
{
BOOST_STATIC_CONSTANT(
bool, obj_mgr = is_object_manager<T>::value);
BOOST_STATIC_CONSTANT(
bool, ptr = is_pointer<T>::value);
BOOST_STATIC_CONSTANT(
bool, ref = is_reference<T>::value);
typedef typename mpl::if_c<
obj_mgr
, return_object_manager_from_python<T>
, typename mpl::if_c<
ptr
, return_pointer_from_python<T>
, typename mpl::if_c<
ref
, return_reference_from_python<T>
, return_rvalue_from_python<T>
>::type
>::type
>::type type;
};
}
template <class T>
struct return_from_python
: detail::select_return_from_python<T>::type
{
};
// Specialization as a convenience for call and call_method
template <>
struct return_from_python<void>
{
typedef python::detail::returnable<void>::type result_type;
result_type operator()(PyObject* x) const
{
(void_result_from_python)(x);
# ifdef BOOST_NO_VOID_RETURNS
return result_type();
# endif
}
};
//
// Implementations
//
namespace detail
{
template <class T>
inline return_rvalue_from_python<T>::return_rvalue_from_python()
: m_data(
const_cast<registration*>(&registered<T>::converters)
)
{
}
template <class T>
inline typename return_rvalue_from_python<T>::result_type
return_rvalue_from_python<T>::operator()(PyObject* obj)
{
// Take possession of the source object here. If the result is in
// fact going to be a copy of an lvalue embedded in the object,
// and we take possession inside rvalue_result_from_python, it
// will be destroyed too early.
handle<> holder(obj);
return *(T*)
(rvalue_result_from_python)(obj, m_data.stage1);
}
template <class T>
inline T return_reference_from_python<T>::operator()(PyObject* obj) const
{
return python::detail::void_ptr_to_reference(
(reference_result_from_python)(obj, registered<T>::converters)
, (T(*)())0);
}
template <class T>
inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
{
return T(
(pointer_result_from_python)(obj, registered_pointee<T>::converters)
);
}
template <class T>
inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const
{
return T(
object_manager_traits<T>::adopt(expect_non_null(obj))
);
}
}
}}} // namespace boost::python::converter
#endif // RETURN_FROM_PYTHON_DWA200265_HPP

View File

@@ -0,0 +1,141 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP
# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP
# include <boost/python/converter/constructor_function.hpp>
# include <boost/python/detail/referent_storage.hpp>
# include <boost/python/detail/destroy.hpp>
# include <boost/static_assert.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/type_traits/add_cv.hpp>
# include <cstddef>
// Data management for potential rvalue conversions from Python to C++
// types. When a client requests a conversion to T* or T&, we
// generally require that an object of type T exists in the source
// Python object, and the code here does not apply**. This implements
// conversions which may create new temporaries of type T. The classic
// example is a conversion which converts a Python tuple to a
// std::vector. Since no std::vector lvalue exists in the Python
// object -- it must be created "on-the-fly" by the converter, and
// which must manage the lifetime of the created object.
//
// Note that the client is not precluded from using a registered
// lvalue conversion to T in this case. In other words, we will
// happily accept a Python object which /does/ contain a std::vector
// lvalue, provided an appropriate converter is registered. So, while
// this is an rvalue conversion from the client's point-of-view, the
// converter registry may serve up lvalue or rvalue conversions for
// the target type.
//
// ** C++ argument from_python conversions to T const& are an
// exception to the rule for references: since in C++, const
// references can bind to temporary rvalues, we allow rvalue
// converters to be chosen when the target type is T const& for some
// T.
namespace boost { namespace python { namespace converter {
// Conversions begin by filling in and returning a copy of this
// structure. The process looks up a converter in the rvalue converter
// registry for the target type. It calls the convertible() function
// of each registered converter, passing the source PyObject* as an
// argument, until a non-null result is returned. This result goes in
// the convertible field, and the converter's construct() function is
// stored in the construct field.
//
// If no appropriate converter is found, conversion fails and the
// convertible field is null. When used in argument conversion for
// wrapped C++ functions, it causes overload resolution to reject the
// current function but not to fail completely. If an exception is
// thrown, overload resolution stops and the exception propagates back
// through the caller.
//
// If an lvalue converter is matched, its convertible() function is
// expected to return a pointer to the stored T object; its
// construct() function will be NULL. The convertible() function of
// rvalue converters may return any non-singular pointer; the actual
// target object will only be available once the converter's
// construct() function is called.
struct rvalue_from_python_stage1_data
{
void* convertible;
constructor_function construct;
};
// Augments rvalue_from_python_stage1_data by adding storage for
// constructing an object of remove_reference<T>::type. The
// construct() function of rvalue converters (stored in m_construct
// above) will cast the rvalue_from_python_stage1_data to an
// appropriate instantiation of this template in order to access that
// storage.
template <class T>
struct rvalue_from_python_storage
{
rvalue_from_python_stage1_data stage1;
// Storage for the result, in case an rvalue must be constructed
typename python::detail::referent_storage<
typename add_reference<T>::type
>::type storage;
};
// Augments rvalue_from_python_storage<T> with a destructor. If
// stage1.convertible == storage.bytes, it indicates that an object of
// remove_reference<T>::type has been constructed in storage and
// should will be destroyed in ~rvalue_from_python_data(). It is
// crucial that successful rvalue conversions establish this equality
// and that unsuccessful ones do not.
template <class T>
struct rvalue_from_python_data : rvalue_from_python_storage<T>
{
# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \
&& (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \
&& (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \
&& !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */
// This must always be a POD struct with m_data its first member.
BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0);
# endif
// The usual constructor
rvalue_from_python_data(rvalue_from_python_stage1_data const&);
// This constructor just sets m_convertible -- used by
// implicitly_convertible<> to perform the final step of the
// conversion, where the construct() function is already known.
rvalue_from_python_data(void* convertible);
// Destroys any object constructed in the storage.
~rvalue_from_python_data();
private:
typedef typename add_reference<typename add_cv<T>::type>::type ref_type;
};
//
// Implementataions
//
template <class T>
inline rvalue_from_python_data<T>::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1)
{
this->stage1 = stage1;
}
template <class T>
inline rvalue_from_python_data<T>::rvalue_from_python_data(void* convertible)
{
this->stage1.convertible = convertible;
}
template <class T>
inline rvalue_from_python_data<T>::~rvalue_from_python_data()
{
if (this->stage1.convertible == this->storage.bytes)
python::detail::destroy_referent<ref_type>(this->storage.bytes);
}
}}} // namespace boost::python::converter
#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef SHARED_PTR_DELETER_DWA2002121_HPP
# define SHARED_PTR_DELETER_DWA2002121_HPP
namespace boost { namespace python { namespace converter {
struct BOOST_PYTHON_DECL shared_ptr_deleter
{
shared_ptr_deleter(handle<> owner);
~shared_ptr_deleter();
void operator()(void const*);
handle<> owner;
};
}}} // namespace boost::python::converter
#endif // SHARED_PTR_DELETER_DWA2002121_HPP

View File

@@ -0,0 +1,53 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
# define SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
# include <boost/python/handle.hpp>
# include <boost/python/converter/shared_ptr_deleter.hpp>
namespace boost { namespace python { namespace converter {
template <class T>
struct shared_ptr_from_python
{
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)
;
}
static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
{
void* const storage = ((converter::rvalue_from_python_storage<shared_ptr<T> >*)data)->storage.bytes;
// Deal with the "None" case.
if (data->convertible == source)
new (storage) shared_ptr<T>();
else
new (storage) shared_ptr<T>(
static_cast<T*>(data->convertible),
shared_ptr_deleter(handle<>(borrowed(source)))
);
data->convertible = storage;
}
};
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

@@ -0,0 +1,26 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef SHARED_PTR_TO_PYTHON_DWA2003224_HPP
# define SHARED_PTR_TO_PYTHON_DWA2003224_HPP
# include <boost/python/refcount.hpp>
# include <boost/python/converter/shared_ptr_deleter.hpp>
# include <boost/shared_ptr.hpp>
namespace boost { namespace python { namespace converter {
template <class T>
PyObject* shared_ptr_to_python(shared_ptr<T> const& x)
{
if (shared_ptr_deleter* d = boost::get_deleter<shared_ptr_deleter>(x))
return incref(d->owner.get());
else
return converter::registered<shared_ptr<T> const&>::converters.to_python(&x);
}
}}} // namespace boost::python::converter
#endif // SHARED_PTR_TO_PYTHON_DWA2003224_HPP

View File

@@ -0,0 +1,20 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/static_assert.hpp>
namespace boost { namespace python { namespace converter {
// The type of stored function pointers which actually do conversion
// by-value. The void* points to the object to be converted, and
// type-safety is preserved through runtime registration.
typedef PyObject* (*to_python_function_t)(void const*);
}}} // namespace boost::python::converter
#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP

View File

@@ -0,0 +1,42 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef COPY_CONST_REFERENCE_DWA2002131_HPP
# define COPY_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/to_python_value.hpp>
namespace boost { namespace python {
namespace detail
{
template <class R>
struct copy_const_reference_expects_a_const_reference_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
template <class T> struct to_python_value;
struct copy_const_reference
{
template <class T>
struct apply
{
typedef typename mpl::if_c<
detail::is_reference_to_const<T>::value
, to_python_value<T>
, detail::copy_const_reference_expects_a_const_reference_return_type<T>
>::type type;
};
};
}} // namespace boost::python
#endif // COPY_CONST_REFERENCE_DWA2002131_HPP

View File

@@ -0,0 +1,42 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef COPY_NON_CONST_REFERENCE_DWA2002131_HPP
# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/to_python_value.hpp>
namespace boost { namespace python {
namespace detail
{
template <class R>
struct copy_non_const_reference_expects_a_non_const_reference_return_type
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
template <class T> struct to_python_value;
struct copy_non_const_reference
{
template <class T>
struct apply
{
typedef typename mpl::if_c<
boost::python::detail::is_reference_to_non_const<T>::value
, to_python_value<T>
, detail::copy_non_const_reference_expects_a_non_const_reference_return_type<T>
>::type type;
};
};
}} // namespace boost::python
#endif // COPY_NON_CONST_REFERENCE_DWA2002131_HPP

View File

@@ -0,0 +1,144 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DATA_MEMBERS_DWA2002328_HPP
# define DATA_MEMBERS_DWA2002328_HPP
# include <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/converter/builtin_converters.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/python/detail/config.hpp>
# include <boost/python/detail/wrap_python.hpp>
# include <boost/type_traits/transform_traits.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/mpl/if.hpp>
# include <boost/bind.hpp>
namespace boost { namespace python {
namespace detail
{
template <class Data, class Class, class Policies>
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));
if (!c1.convertible()) return 0;
if (!policies.precall(args_)) return 0;
(c0(PyTuple_GET_ITEM(args_, 0))).*pm = c1(PyTuple_GET_ITEM(args_, 1));
return policies.postcall(args_, detail::none());
}
};
// If it's a regular class type (not an object manager or other
// type for which we have to_python specializations, use
// return_internal_reference so that we can do things like
// x.y.z = 1
// and get the right result.
template <class T>
struct default_getter_policy
{
typedef typename add_reference<
typename add_const<T>::type
>::type t_cref;
BOOST_STATIC_CONSTANT(
bool, by_ref = to_python_value<t_cref>::uses_registry
&& is_reference_to_class<t_cref>::value);
typedef typename mpl::if_c<
by_ref
, return_internal_reference<>
, return_value_policy<return_by_value>
>::type type;
};
}
template <class C, class D>
object make_getter(D C::*pm)
{
typedef typename detail::default_getter_policy<D>::type policy;
return objects::function_object(
::boost::bind(
&detail::member<D,C,policy>::get, pm, _1, _2
, policy())
, 1);
}
template <class C, class D, class Policies>
object make_getter(D C::*pm, Policies const& policies)
{
return objects::function_object(
::boost::bind(
&detail::member<D,C,Policies>::get, pm, _1, _2
, policies)
, 1);
}
template <class C, class D>
object make_setter(D C::*pm)
{
return objects::function_object(
::boost::bind(
&detail::member<D,C,default_call_policies>::set, pm, _1, _2
, default_call_policies())
, 2);
}
template <class C, class D, class Policies>
object make_setter(D C::*pm, Policies const& policies)
{
return objects::function_object(
::boost::bind(
&detail::member<D,C,Policies>::set, pm, _1, _2
, policies)
, 2);
}
}} // namespace boost::python
#endif // DATA_MEMBERS_DWA2002328_HPP

View File

@@ -0,0 +1,113 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DEF_DWA200292_HPP
# define DEF_DWA200292_HPP
# include <boost/python/object_fwd.hpp>
# include <boost/python/make_function.hpp>
# include <boost/python/detail/def_helper.hpp>
# include <boost/python/detail/overloads_fwd.hpp>
# include <boost/python/scope.hpp>
# include <boost/python/signature.hpp>
# include <boost/python/detail/scope.hpp>
namespace boost { namespace python {
namespace detail
{
namespace error
{
// Compile-time error messages
template <bool> struct multiple_functions_passed_to_def;
template <> struct multiple_functions_passed_to_def<false> { typedef char type; };
}
//
// def_from_helper --
//
// Use a def_helper to define a regular wrapped function in the current scope.
template <class F, class Helper>
void def_from_helper(
char const* name, F const& fn, Helper const& helper)
{
// Must not try to use default implementations except with method definitions.
typedef typename error::multiple_functions_passed_to_def<
Helper::has_default_implementation
>::type assertion;
detail::scope_setattr_doc(
name, boost::python::make_function(
fn
, helper.policies()
, helper.keywords())
, helper.doc()
);
}
//
// These two overloads discriminate between def() as applied to
// regular functions and def() as applied to the result of
// BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
// discriminate.
//
template <class Fn, class A1>
void
def_maybe_overloads(
char const* name
, Fn fn
, A1 const& a1
, ...)
{
detail::def_from_helper(name, fn, def_helper<A1>(a1));
}
template <class StubsT, class SigT>
void def_maybe_overloads(
char const* name
, SigT sig
, StubsT const& stubs
, detail::overloads_base const*)
{
scope current;
detail::define_with_defaults(
name, stubs, current, detail::get_signature(sig));
}
template <class T>
object make_function1(T fn, ...) { return make_function(fn); }
inline
object make_function1(object const& x, object const*) { return x; }
}
template <class Fn>
void def(char const* name, Fn fn)
{
detail::scope_setattr_doc(name, detail::make_function1(fn, &fn), 0);
}
template <class Arg1T, class Arg2T>
void def(char const* name, Arg1T arg1, Arg2T const& arg2)
{
detail::def_maybe_overloads(name, arg1, arg2, &arg2);
}
template <class F, class A1, class A2>
void def(char const* name, F f, A1 const& a1, A2 const& a2)
{
detail::def_from_helper(name, f, detail::def_helper<A1,A2>(a1,a2));
}
template <class F, class A1, class A2, class A3>
void def(char const* name, F f, A1 const& a1, A2 const& a2, A3 const& a3)
{
detail::def_from_helper(name, f, detail::def_helper<A1,A2,A3>(a1,a2,a3));
}
}} // namespace boost::python
#endif // DEF_DWA200292_HPP

View File

@@ -0,0 +1,78 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP
# define DEFAULT_CALL_POLICIES_DWA2002131_HPP
# include <boost/python/detail/wrap_python.hpp>
# include <boost/mpl/if.hpp>
# include <boost/python/to_python_value.hpp>
# include <boost/type_traits/transform_traits.hpp>
namespace boost { namespace python {
template <class T> struct to_python_value;
namespace detail
{
// for "readable" error messages
template <class T> struct specify_a_return_value_policy_to_wrap_functions_returning
# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__)
{}
# endif
;
}
struct default_result_converter;
struct default_call_policies
{
// Nothing to do
static bool precall(PyObject*)
{
return true;
}
// Pass the result through
static PyObject* postcall(PyObject*, PyObject* result)
{
return result;
}
typedef default_result_converter result_converter;
};
struct default_result_converter
{
template <class R>
struct apply
{
BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference<R>::value || is_pointer<R>::value);
typedef typename mpl::if_c<
is_illegal
, detail::specify_a_return_value_policy_to_wrap_functions_returning<R>
, boost::python::to_python_value<
typename add_reference<typename add_const<R>::type>::type
>
>::type type;
};
};
// Exceptions for c strings an PyObject*s
template <>
struct default_result_converter::apply<char const*>
{
typedef boost::python::to_python_value<char const*const&> type;
};
template <>
struct default_result_converter::apply<PyObject*>
{
typedef boost::python::to_python_value<PyObject*const&> type;
};
}} // namespace boost::python
#endif // DEFAULT_CALL_POLICIES_DWA2002131_HPP

View File

@@ -0,0 +1,27 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef AIX_INIT_MODULE_DWA2002529_HPP
# define AIX_INIT_MODULE_DWA2002529_HPP
# ifdef _AIX
# include <boost/python/detail/wrap_python.hpp>
# include <cstdio>
# ifdef __KCC
# include <iostream> // this works around a problem in KCC 4.0f
# endif
namespace boost { namespace python { namespace detail {
extern "C"
{
typedef PyObject* (*so_load_function)(char*,char*,FILE*);
}
void aix_init_module(so_load_function, char const* name, void (*init_module)());
}}} // namespace boost::python::detail
# endif
#endif // AIX_INIT_MODULE_DWA2002529_HPP

View File

@@ -0,0 +1,19 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_PYTHON_API_PLACE_HOLDER_HPP
#define BOOST_PYTHON_API_PLACE_HOLDER_HPP
namespace boost { namespace python {
inline long len(object const& obj)
{
long result = PyObject_Length(obj.ptr());
if (PyErr_Occurred()) throw_error_already_set();
return result;
}
}} // namespace boost::python
#endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP

View File

@@ -0,0 +1,112 @@
#ifndef BORROWED_PTR_DWA20020601_HPP
# define BORROWED_PTR_DWA20020601_HPP
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# include <boost/config.hpp>
# include <boost/type.hpp>
# include <boost/mpl/if.hpp>
# include <boost/type_traits/object_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
# include <boost/python/tag.hpp>
namespace boost { namespace python { namespace detail {
template<class T> class borrowed
{
typedef T type;
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
struct is_borrowed_ptr
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
# if !defined(__MWERKS__) || __MWERKS__ > 0x3000
template<typename T>
struct is_borrowed_ptr<borrowed<T>*>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
struct is_borrowed_ptr<borrowed<T> const*>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
struct is_borrowed_ptr<borrowed<T> volatile*>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
struct is_borrowed_ptr<borrowed<T> const volatile*>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
# else
template<typename T>
struct is_borrowed
{
BOOST_STATIC_CONSTANT(bool, value = false);
};
template<typename T>
struct is_borrowed<borrowed<T> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
struct is_borrowed_ptr<T*>
: is_borrowed<typename remove_cv<T>::type>
{
};
# endif
# else // no partial specialization
typedef char (&yes_borrowed_ptr_t)[1];
typedef char (&no_borrowed_ptr_t)[2];
no_borrowed_ptr_t is_borrowed_ptr_test(...);
template <class T>
typename mpl::if_c<
is_pointer<T>::value
, T
, int
>::type
is_borrowed_ptr_test1(boost::type<T>);
template<typename T>
yes_borrowed_ptr_t is_borrowed_ptr_test(borrowed<T> const volatile*);
template<typename T>
class is_borrowed_ptr
{
public:
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(detail::is_borrowed_ptr_test(is_borrowed_ptr_test1(boost::type<T>())))
== sizeof(detail::yes_borrowed_ptr_t)));
};
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
template <class T>
inline T* get_managed_object(detail::borrowed<T> const volatile* p, tag_t)
{
return (T*)p;
}
}} // namespace boost::python::detail
#endif // #ifndef BORROWED_PTR_DWA20020601_HPP

View File

@@ -0,0 +1,175 @@
#if !defined(BOOST_PP_IS_ITERATING)
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# ifndef CALLER_DWA20021121_HPP
# define CALLER_DWA20021121_HPP
# include <boost/compressed_pair.hpp>
# include <boost/mpl/apply.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/size.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/python/detail/preprocessor.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/python/detail/invoke.hpp>
namespace boost { namespace python { namespace detail {
// This "result converter" is really just used as
// a dispatch tag to invoke(...), selecting the appropriate
// implementation
typedef int void_result_to_python;
// A metafunction taking an iterator FunctionIter to a metafunction
// class and an iterator ArgIter to an argument, which applies the
// result of dereferencing FunctionIter to the result of dereferencing
// ArgIter
template <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_<
is_same<Result,void>
, void_result_to_python
, typename mpl::apply1<typename Policies::result_converter,Result>::type*
>
{
};
template <unsigned> struct caller_arity;
# define BOOST_PYTHON_NEXT(init,name,n) \
typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n;
# define BOOST_PYTHON_ARG_CONVERTER(n) \
BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \
BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \
typedef typename apply_iter1<conv_iter##n,arg_iter##n>::type c_t##n; \
c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \
if (!c##n.convertible()) \
return 0;
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>))
# include BOOST_PP_ITERATE()
# undef BOOST_PYTHON_ARG_CONVERTER
# undef BOOST_PYTHON_NEXT
// 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>
struct caller_base_select
{
enum { arity = mpl::size<Sig>::value - 1 };
typedef typename caller_arity<arity>::template impl<F,ConverterGenerators,CallPolicies,Sig> type;
};
// A function object type which wraps C++ objects as Python callable
// objects.
//
// Template Arguments:
//
// F -
// the C++ `function object' that will be called. Might
// actually be any data for which an appropriate invoke_tag() can
// be generated. invoke(...) takes care of the actual invocation syntax.
//
// ConverterGenerators -
// An MPL iterator type over a sequence of metafunction classes
// that can be applied to element 1...N of Sig to produce
// argument from_python converters for the arguments
//
// CallPolicies -
// The precall, postcall, and what kind of resultconverter to
// generate for mpl::front<Sig>::type
//
// Sig -
// The `intended signature' of the function. An MPL sequence
// beginning with a result type and continuing with a list of
// argument types.
template <class F, class ConverterGenerators, class CallPolicies, class Sig>
struct caller
: caller_base_select<F,ConverterGenerators,CallPolicies,Sig>::type
{
typedef typename caller_base_select<
F,ConverterGenerators,CallPolicies,Sig
>::type base;
typedef PyObject* result_type;
caller(F f, CallPolicies p) : base(f,p) {}
};
}}} // namespace boost::python::detail
# endif // CALLER_DWA20021121_HPP
#else
# define N BOOST_PP_ITERATION()
template <>
struct caller_arity<N>
{
template <class F, class ConverterGenerators, class Policies, class Sig>
struct impl
{
impl(F f, Policies p) : m_data(f,p) {}
PyObject* operator()(PyObject* args_, PyObject*) // eliminate
// this
// trailing
// keyword dict
{
typedef typename mpl::begin<Sig>::type first;
typedef typename first::type result_t;
typedef typename select_result_converter<Policies, result_t>::type result_converter;
# if N
# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
# define BOOST_PP_LOCAL_LIMITS (0, N-1)
# include BOOST_PP_LOCAL_ITERATE()
# endif
// all converters have been checked. Now we can do the
// precall part of the policy
if (!m_data.second().precall(args_))
return 0;
typedef typename detail::invoke_tag<F>::type tag;
PyObject* result = detail::invoke(
tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c));
return m_data.second().postcall(args_, result);
}
private:
compressed_pair<F,Policies> m_data;
};
};
#endif // BOOST_PP_IS_ITERATING

View File

@@ -0,0 +1,23 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CHAR_ARRAY_DWA2002129_HPP
# define CHAR_ARRAY_DWA2002129_HPP
namespace boost { namespace python { namespace detail {
// This little package is used to transmit the number of arguments
// from the helper functions below to the sizeof() expression below.
// Because we can never have an array of fewer than 1 element, we
// add 1 to n and then subtract 1 from the result of sizeof() below.
template <int n>
struct char_array
{
char elements[n+1];
};
}}} // namespace boost::python::detail
#endif // CHAR_ARRAY_DWA2002129_HPP

View File

@@ -0,0 +1,114 @@
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
// Revision History:
// 04 Mar 01 Some fixes so it will compile with Intel C++ (Dave Abrahams)
#ifndef CONFIG_DWA052200_H_
# define CONFIG_DWA052200_H_
#if defined(__ALPHA) && defined(__osf__) && defined(__DECCXX_VER)
# include <pyconfig.h>
#endif
# include <boost/config.hpp>
# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
// A gcc bug forces some symbols into the global namespace
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE
# define BOOST_PYTHON_CONVERSION
# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x
# else
# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python {
# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python
# define BOOST_PYTHON_CONVERSION boost::python
# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';'
# endif
# if defined(BOOST_MSVC)
# if _MSC_VER <= 1200
# define BOOST_MSVC6_OR_EARLIER 1
# endif
# pragma warning (disable : 4786) // disable truncated debug symbols
# pragma warning (disable : 4251) // disable exported dll function
# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or 'false'
# pragma warning (disable : 4275) // non dll-interface class
# elif defined(__ICL) && __ICL < 600 // Intel C++ 5
# pragma warning(disable: 985) // identifier was truncated in debug information
# endif
// The STLport puts all of the standard 'C' library names in std (as far as the
// user is concerned), but without it you need a fix if you're using MSVC or
// Intel C++
# if defined(BOOST_MSVC_STD_ITERATOR)
# define BOOST_CSTD_
# else
# define BOOST_CSTD_ std
# endif
/*****************************************************************************
*
* Set up dll import/export options:
*
****************************************************************************/
// backwards compatibility:
#ifdef BOOST_PYTHON_STATIC_LIB
# define BOOST_PYTHON_STATIC_LINK
# elif !defined(BOOST_PYTHON_DYNAMIC_LIB)
# define BOOST_PYTHON_DYNAMIC_LIB
#endif
#if defined(__MWERKS__) \
|| (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730)
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
#endif
#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32)
# if defined(BOOST_PYTHON_SOURCE)
# define BOOST_PYTHON_DECL __declspec(dllexport)
# define BOOST_PYTHON_BUILD_DLL
# else
# define BOOST_PYTHON_DECL __declspec(dllimport)
# endif
// MinGW, at least, has some problems exporting template instantiations
# if defined(__GNUC__) && __GNUC__ < 3 && !defined(__CYGWIN__)
# define BOOST_PYTHON_NO_TEMPLATE_EXPORT
# endif
#endif
#ifndef BOOST_PYTHON_DECL
# define BOOST_PYTHON_DECL
#endif
#ifndef BOOST_PYTHON_EXPORT
# define BOOST_PYTHON_EXPORT extern
#endif
#if !defined(BOOST_PYTHON_NO_TEMPLATE_EXPORT)
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL instantiation
#else
# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD
#endif
#if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031)
// Replace broken Tru64/cxx offsetof macro
# define BOOST_PYTHON_OFFSETOF(s_name, s_member) \
((size_t)__INTADDR__(&(((s_name *)0)->s_member)))
#else
# define BOOST_PYTHON_OFFSETOF offsetof
#endif
#endif // CONFIG_DWA052200_H_

View File

@@ -0,0 +1,43 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CONSTRUCT_REFERENCE_DWA2002716_HPP
# define CONSTRUCT_REFERENCE_DWA2002716_HPP
namespace boost { namespace python { namespace detail {
template <class T, class Arg>
void construct_pointee(void* storage, Arg& x
# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
, T const volatile*
# else
, T const*
# endif
)
{
new (storage) T(x);
}
template <class T, class Arg>
void construct_referent_impl(void* storage, Arg& x, T&(*)())
{
construct_pointee(storage, x, (T*)0);
}
template <class T, class Arg>
void construct_referent(void* storage, Arg const& x, T(*tag)() = 0)
{
construct_referent_impl(storage, x, tag);
}
template <class T, class Arg>
void construct_referent(void* storage, Arg& x, T(*tag)() = 0)
{
construct_referent_impl(storage, x, tag);
}
}}} // namespace boost::python::detail
#endif // CONSTRUCT_REFERENCE_DWA2002716_HPP

View File

@@ -0,0 +1,39 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CONVERTIBLE_DWA2002614_HPP
# define CONVERTIBLE_DWA2002614_HPP
# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241
# include <boost/mpl/if.hpp>
# include <boost/type_traits/conversion_traits.hpp>
# endif
// Supplies a runtime is_convertible check which can be used with tag
// dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible
namespace boost { namespace python { namespace detail {
typedef char* yes_convertible;
typedef int* no_convertible;
template <class Target>
struct convertible
{
# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 || __EDG_VERSION__ == 238
static inline no_convertible check(...) { return 0; }
static inline yes_convertible check(Target) { return 0; }
# else
template <class X>
static inline typename mpl::if_c<
is_convertible<X,Target>::value
, yes_convertible
, no_convertible
>::type check(X const&) { return 0; }
# endif
};
}}} // namespace boost::python::detail
#endif // CONVERTIBLE_DWA2002614_HPP

View File

@@ -0,0 +1,22 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
# define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
#include <boost/python/detail/is_auto_ptr.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace python { namespace detail {
template <class T>
struct copy_ctor_mutates_rhs
: is_auto_ptr<T>
{
};
}}} // namespace boost::python::detail
#endif // COPY_CTOR_MUTATES_RHS_DWA2003219_HPP

View File

@@ -0,0 +1,34 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef CV_CATEGORY_DWA200222_HPP
# define CV_CATEGORY_DWA200222_HPP
# include <boost/type_traits/cv_traits.hpp>
namespace boost { namespace python { namespace detail {
template <bool is_const_, bool is_volatile_>
struct cv_tag
{
BOOST_STATIC_CONSTANT(bool, is_const = is_const_);
BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_);
};
typedef cv_tag<false,false> cv_unqualified;
typedef cv_tag<true,false> const_;
typedef cv_tag<false,true> volatile_;
typedef cv_tag<true,true> const_volatile_;
template <class T>
struct cv_category
{
BOOST_STATIC_CONSTANT(bool, c = is_const<T>::value);
BOOST_STATIC_CONSTANT(bool, v = is_volatile<T>::value);
typedef cv_tag<c,v> type;
};
}}} // namespace boost::python::detail
#endif // CV_CATEGORY_DWA200222_HPP

View File

@@ -0,0 +1,18 @@
// Copyright Gottfried Ganßauge 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
# ifndef BOOST_PYTHON_DETAIL_DEALLOC_HPP_
# define BOOST_PYTHON_DETAIL_DEALLOC_HPP_
namespace boost { namespace python { namespace detail {
extern "C"
{
inline void dealloc(PyObject* self)
{
PyObject_Del(self);
}
}
}}} // namespace boost::python::detail
# endif // BOOST_PYTHON_DETAIL_DEALLOC_HPP_

View File

@@ -0,0 +1,77 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DECORATED_TYPE_ID_DWA2002517_HPP
# define DECORATED_TYPE_ID_DWA2002517_HPP
# include <boost/python/type_id.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/type_traits/cv_traits.hpp>
namespace boost { namespace python { namespace detail {
struct decorated_type_info : totally_ordered<decorated_type_info>
{
enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 };
decorated_type_info(type_info, decoration = decoration());
inline bool operator<(decorated_type_info const& rhs) const;
inline bool operator==(decorated_type_info const& rhs) const;
friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&);
operator type_info const&() const;
private: // type
typedef type_info base_id_t;
private: // data members
decoration m_decoration;
base_id_t m_base_type;
};
template <class T>
inline decorated_type_info decorated_type_id(boost::type<T>* = 0)
{
return decorated_type_info(
type_id<T>()
, decorated_type_info::decoration(
(is_const<T>::value || python::detail::is_reference_to_const<T>::value
? decorated_type_info::const_ : 0)
| (is_volatile<T>::value || python::detail::is_reference_to_volatile<T>::value
? decorated_type_info::volatile_ : 0)
| (is_reference<T>::value ? decorated_type_info::reference : 0)
)
);
}
inline decorated_type_info::decorated_type_info(type_info base_t, decoration decoration)
: m_decoration(decoration)
, m_base_type(base_t)
{
}
inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const
{
return m_decoration < rhs.m_decoration
|| m_decoration == rhs.m_decoration
&& m_base_type < rhs.m_base_type;
}
inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const
{
return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type;
}
inline decorated_type_info::operator type_info const&() const
{
return m_base_type;
}
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&);
}}} // namespace boost::python::detail
#endif // DECORATED_TYPE_ID_DWA2002517_HPP

View File

@@ -0,0 +1,22 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DECREF_GUARD_DWA20021220_HPP
# define DECREF_GUARD_DWA20021220_HPP
namespace boost { namespace python { namespace detail {
struct decref_guard
{
decref_guard(PyObject* o) : obj(o) {}
~decref_guard() { Py_XDECREF(obj); }
void cancel() { obj = 0; }
private:
PyObject* obj;
};
}}} // namespace boost::python::detail
#endif // DECREF_GUARD_DWA20021220_HPP

View File

@@ -0,0 +1,212 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DEF_HELPER_DWA200287_HPP
# define DEF_HELPER_DWA200287_HPP
# include <boost/python/args.hpp>
# include <boost/type_traits/ice.hpp>
# include <boost/type_traits/same_traits.hpp>
# include <boost/python/detail/indirect_traits.hpp>
# include <boost/mpl/not.hpp>
# include <boost/mpl/and.hpp>
# include <boost/mpl/or.hpp>
# include <boost/type_traits/add_reference.hpp>
# include <boost/mpl/lambda.hpp>
# include <boost/mpl/apply.hpp>
# include <boost/tuple/tuple.hpp>
# include <boost/python/detail/not_specified.hpp>
namespace boost { namespace python {
struct default_call_policies;
namespace detail
{
// tuple_extract<Tuple,Predicate>::extract(t) returns the first
// element of a Tuple whose type E satisfies the given Predicate
// applied to add_reference<E>. The Predicate must be an MPL
// metafunction class.
template <class Tuple, class Predicate>
struct tuple_extract;
// Implementation class for when the tuple's head type does not
// satisfy the Predicate
template <bool matched>
struct tuple_extract_impl
{
template <class Tuple, class Predicate>
struct apply
{
typedef typename Tuple::head_type result_type;
static typename Tuple::head_type extract(Tuple const& x)
{
return x.get_head();
}
};
};
// Implementation specialization for when the tuple's head type
// satisfies the predicate
template <>
struct tuple_extract_impl<false>
{
template <class Tuple, class Predicate>
struct apply
{
// recursive application of tuple_extract on the tail of the tuple
typedef tuple_extract<typename Tuple::tail_type, Predicate> next;
typedef typename next::result_type result_type;
static result_type extract(Tuple const& x)
{
return next::extract(x.get_tail());
}
};
};
// A metafunction which selects a version of tuple_extract_impl to
// use for the implementation of tuple_extract
template <class Tuple, class Predicate>
struct tuple_extract_base_select
{
typedef typename Tuple::head_type head_type;
typedef typename mpl::apply1<Predicate, typename add_reference<head_type>::type>::type match_t;
BOOST_STATIC_CONSTANT(bool, match = match_t::value);
typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type;
};
template <class Tuple, class Predicate>
struct tuple_extract
: tuple_extract_base_select<
Tuple
, typename mpl::lambda<Predicate>::type
>::type
{
};
//
// Specialized extractors for the docstring, keywords, CallPolicies,
// and default implementation of virtual functions
//
template <class Tuple>
struct doc_extract
: tuple_extract<
Tuple
, mpl::not_<
mpl::or_<
is_reference_to_class<mpl::_1>
, is_reference_to_member_function_pointer<mpl::_1 >
>
>
>
{
};
template <class Tuple>
struct keyword_extract
: tuple_extract<Tuple, is_reference_to_keywords<mpl::_1 > >
{
};
template <class Tuple>
struct policy_extract
: tuple_extract<
Tuple
, mpl::and_<
mpl::not_<is_same<not_specified const&,mpl::_1> >
, is_reference_to_class<mpl::_1 >
, mpl::not_<is_reference_to_keywords<mpl::_1 > >
>
>
{
};
template <class Tuple>
struct default_implementation_extract
: tuple_extract<
Tuple
, is_reference_to_member_function_pointer<mpl::_1 >
>
{
};
//
// A helper class for decoding the optional arguments to def()
// invocations, which can be supplied in any order and are
// discriminated by their type properties. The template parameters
// are expected to be the types of the actual (optional) arguments
// passed to def().
//
template <class T1, class T2 = not_specified, class T3 = not_specified, class T4 = not_specified>
struct def_helper
{
// A tuple type which begins with references to the supplied
// arguments and ends with actual representatives of the default
// types.
typedef boost::tuples::tuple<
T1 const&
, T2 const&
, T3 const&
, T4 const&
, default_call_policies
, keywords<0>
, char const*
, void(not_specified::*)() // A function pointer type which is never an
// appropriate default implementation
> all_t;
// Constructors; these initialize an member of the tuple type
// shown above.
def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {}
def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {}
def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {}
def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {}
private: // types
typedef typename default_implementation_extract<all_t>::result_type default_implementation_t;
public: // Constants which can be used for static assertions.
// Users must not supply a default implementation for non-class
// methods.
BOOST_STATIC_CONSTANT(
bool, has_default_implementation = (
!is_same<default_implementation_t, void(not_specified::*)()>::value));
public: // Extractor functions which pull the appropriate value out
// of the tuple
char const* doc() const
{
return doc_extract<all_t>::extract(m_all);
}
typename keyword_extract<all_t>::result_type keywords() const
{
return keyword_extract<all_t>::extract(m_all);
}
typename policy_extract<all_t>::result_type policies() const
{
return policy_extract<all_t>::extract(m_all);
}
default_implementation_t default_implementation() const
{
return default_implementation_extract<all_t>::extract(m_all);
}
private: // data members
all_t m_all;
not_specified m_nil; // for filling in not_specified slots
};
}
}} // namespace boost::python::detail
#endif // DEF_HELPER_DWA200287_HPP

View File

@@ -0,0 +1,280 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_PP_IS_ITERATING)
#ifndef DEFAULTS_DEF_JDG20020811_HPP
#define DEFAULTS_DEF_JDG20020811_HPP
#include <boost/python/detail/defaults_gen.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/size.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/iterate.hpp>
#include <boost/python/class_fwd.hpp>
#include <boost/python/scope.hpp>
#include <boost/preprocessor/debug/line.hpp>
#include <boost/python/detail/scope.hpp>
#include <boost/python/detail/make_keyword_range_fn.hpp>
#include <boost/python/object/add_to_namespace.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace python {
struct module;
namespace objects
{
struct class_base;
}
namespace detail
{
template <class T, class F> struct member_function_cast;
template <class Func, class CallPolicies, class NameSpaceT>
static void name_space_def(
NameSpaceT& name_space
, char const* name
, Func f
, keyword_range const& kw
, CallPolicies const& policies
, char const* doc
, objects::class_base*
)
{
typedef typename NameSpaceT::wrapped_type wrapped_type;
objects::add_to_namespace(
name_space, name,
detail::make_keyword_range_function(
// This bit of nastiness casts F to a member function of T if possible.
member_function_cast<wrapped_type,Func>::stage1(f).stage2((wrapped_type*)0).stage3(f)
, policies, kw)
, doc);
}
template <class Func, class CallPolicies>
static void name_space_def(
object& name_space
, char const* name
, Func f
, keyword_range const& kw
, CallPolicies const& policies
, char const* doc
, ...
)
{
scope within(name_space);
detail::scope_setattr_doc(
name
, detail::make_keyword_range_function(f, policies, kw)
, doc);
}
// For backward compatibility
template <class Func, class CallPolicies, class NameSpaceT>
static void name_space_def(
NameSpaceT& name_space
, char const* name
, Func f
, keyword_range const& kw // ignored
, CallPolicies const& policies
, char const* doc
, module*
)
{
name_space.def(name, f, policies, doc);
}
///////////////////////////////////////////////////////////////////////////////
//
// This Boost PP code generates expansions for
//
// template <typename OverloadsT, typename NameSpaceT>
// inline void
// define_stub_function(
// char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_<N>)
// {
// name_space.def(name, &OverloadsT::func_N);
// }
//
// where N runs from 0 to BOOST_PYTHON_MAX_ARITY
//
// The set of overloaded functions (define_stub_function) expects:
//
// 1. char const* name: function name that will be visible to python
// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp)
// 3. NameSpaceT& name_space: a python::class_ or python::module instance
// 4. int_t<N>: the Nth overloaded function (OverloadsT::func_N)
// (see defaults_gen.hpp)
// 5. char const* name: doc string
//
///////////////////////////////////////////////////////////////////////////////
template <int N>
struct define_stub_function {};
#define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/defaults_def.hpp>))
#include BOOST_PP_ITERATE()
///////////////////////////////////////////////////////////////////////////////
//
// 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);
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);
}
};
///////////////////////////////////////
template <>
struct define_with_defaults_helper<0> {
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
}
};
///////////////////////////////////////////////////////////////////////////////
//
// 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& sig)
{
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;
typedef typename mpl::if_c<
boost::is_same<void, return_type>::value
, void_return_type
, non_void_return_type
>::type stubs_type;
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)
// PP vertical iteration code
template <>
struct define_stub_function<BOOST_PP_ITERATION()> {
template <class StubsT, class CallPolicies, class NameSpaceT>
static void define(
char const* name
, StubsT const&
, keyword_range const& kw
, CallPolicies const& policies
, NameSpaceT& name_space
, char const* doc)
{
detail::name_space_def(
name_space
, name
, &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION())
, kw
, policies
, doc
, &name_space);
}
};
#endif // !defined(BOOST_PP_IS_ITERATING)

View File

@@ -0,0 +1,388 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its
// suitability for any purpose.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef DEFAULTS_GEN_JDG20020807_HPP
#define DEFAULTS_GEN_JDG20020807_HPP
#include <boost/python/detail/preprocessor.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>
#include <boost/preprocessor/enum.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/tuple.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/comma_if.hpp>
#include <boost/config.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/apply.hpp>
namespace boost { namespace python {
namespace detail
{
// overloads_base is used as a base class for all function
// stubs. This class holds the doc_string of the stubs.
struct overloads_base
{
overloads_base(char const* doc_)
: m_doc(doc_) {}
overloads_base(char const* doc_, detail::keyword_range const& kw)
: m_doc(doc_), m_keywords(kw) {}
char const* doc_string() const
{
return m_doc;
}
detail::keyword_range const& keywords() const
{
return m_keywords;
}
private:
char const* m_doc;
detail::keyword_range m_keywords;
};
// overloads_proxy is generated by the overloads_common operator[] (see
// below). This class holds a user defined call policies of the stubs.
template <class CallPoliciesT, class OverloadsT>
struct overloads_proxy
: public overloads_base
{
typedef typename OverloadsT::non_void_return_type non_void_return_type;
typedef typename OverloadsT::void_return_type void_return_type;
overloads_proxy(
CallPoliciesT const& policies_
, char const* doc
, keyword_range const& kw
)
: overloads_base(doc, kw)
, policies(policies_)
{}
CallPoliciesT
call_policies() const
{
return policies;
}
CallPoliciesT policies;
};
// overloads_common is our default function stubs base class. This
// class returns the default_call_policies in its call_policies()
// member function. It can generate a overloads_proxy however through
// its operator[]
template <class DerivedT>
struct overloads_common
: public overloads_base
{
overloads_common(char const* doc)
: overloads_base(doc) {}
overloads_common(char const* doc, keyword_range const& kw)
: overloads_base(doc, kw) {}
default_call_policies
call_policies() const
{
return default_call_policies();
}
template <class CallPoliciesT>
overloads_proxy<CallPoliciesT, DerivedT>
operator[](CallPoliciesT const& policies) const
{
return overloads_proxy<CallPoliciesT, DerivedT>(
policies, this->doc_string(), this->keywords());
}
};
}}} // namespace boost::python::detail
#define BOOST_PYTHON_TYPEDEF_GEN(z, index, data) \
typedef typename ::boost::mpl::next<BOOST_PP_CAT(iter, index)>::type \
BOOST_PP_CAT(iter, BOOST_PP_INC(index)); \
typedef typename ::boost::mpl::apply0<BOOST_PP_CAT(iter, index)>::type \
BOOST_PP_CAT(T, index);
#define BOOST_PYTHON_FUNC_WRAPPER_GEN(z, index, data) \
static RT BOOST_PP_CAT(func_, \
BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \
BOOST_PP_ENUM_BINARY_PARAMS_Z( \
1, index, T, arg)) \
{ \
BOOST_PP_TUPLE_ELEM(3, 2, data) \
BOOST_PP_TUPLE_ELEM(3, 0, data)( \
BOOST_PP_ENUM_PARAMS( \
index, \
arg)); \
}
#define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \
struct fstubs_name \
{ \
BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \
BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \
\
template <typename SigT> \
struct gen \
{ \
typedef typename ::boost::mpl::begin<SigT>::type rt_iter; \
typedef typename ::boost::mpl::apply0<rt_iter>::type RT; \
typedef typename ::boost::mpl::next<rt_iter>::type iter0; \
\
BOOST_PP_REPEAT_2ND( \
n_args, \
BOOST_PYTHON_TYPEDEF_GEN, \
0) \
\
BOOST_PP_REPEAT_FROM_TO_2( \
BOOST_PP_SUB_D(1, n_args, n_dflts), \
BOOST_PP_INC(n_args), \
BOOST_PYTHON_FUNC_WRAPPER_GEN, \
(fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \
}; \
}; \
///////////////////////////////////////////////////////////////////////////////
#define BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN(z, index, data) \
static RT BOOST_PP_CAT(func_, \
BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) ( \
ClassT obj BOOST_PP_COMMA_IF(index) \
BOOST_PP_ENUM_BINARY_PARAMS_Z(1, index, T, arg) \
) \
{ \
BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)( \
BOOST_PP_ENUM_PARAMS(index, arg) \
); \
}
#define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \
struct fstubs_name \
{ \
BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \
BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \
\
template <typename SigT> \
struct gen \
{ \
typedef typename ::boost::mpl::begin<SigT>::type rt_iter; \
typedef typename ::boost::mpl::apply0<rt_iter>::type RT; \
\
typedef typename ::boost::mpl::next<rt_iter>::type class_iter; \
typedef typename ::boost::mpl::apply0<class_iter>::type ClassT; \
typedef typename ::boost::mpl::next<class_iter>::type iter0; \
\
BOOST_PP_REPEAT_2ND( \
n_args, \
BOOST_PYTHON_TYPEDEF_GEN, \
0) \
\
BOOST_PP_REPEAT_FROM_TO_2( \
BOOST_PP_SUB_D(1, n_args, n_dflts), \
BOOST_PP_INC(n_args), \
BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN, \
(fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret)) \
}; \
};
#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
fstubs_name(char const* doc = 0) \
: ::boost::python::detail::overloads_common<fstubs_name>(doc) {} \
template <class Keywords> \
fstubs_name(char const* doc, Keywords const& keywords) \
: ::boost::python::detail::overloads_common<fstubs_name>( \
doc, keywords.range()) \
{ \
typedef typename ::boost::python::detail:: \
error::more_keywords_than_function_arguments< \
Keywords::size,n_args>::too_many_keywords assertion; \
} \
template <class Keywords> \
fstubs_name(Keywords const& keywords, char const* doc = 0) \
: ::boost::python::detail::overloads_common<fstubs_name>( \
doc, keywords.range()) \
{ \
typedef typename ::boost::python::detail:: \
error::more_keywords_than_function_arguments< \
Keywords::size,n_args>::too_many_keywords assertion; \
}
# if defined(BOOST_NO_VOID_RETURNS)
# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
struct fstubs_name \
: public ::boost::python::detail::overloads_common<fstubs_name> \
{ \
BOOST_PYTHON_GEN_FUNCTION( \
fname, non_void_return_type, n_args, n_dflts, return) \
BOOST_PYTHON_GEN_FUNCTION( \
fname, void_return_type, n_args, n_dflts, ;) \
\
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
};
# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
struct fstubs_name \
: public ::boost::python::detail::overloads_common<fstubs_name> \
{ \
BOOST_PYTHON_GEN_MEM_FUNCTION( \
fname, non_void_return_type, n_args, n_dflts, return) \
BOOST_PYTHON_GEN_MEM_FUNCTION( \
fname, void_return_type, n_args, n_dflts, ;) \
\
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
};
# else // !defined(BOOST_NO_VOID_RETURNS)
# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
struct fstubs_name \
: public ::boost::python::detail::overloads_common<fstubs_name> \
{ \
BOOST_PYTHON_GEN_FUNCTION( \
fname, non_void_return_type, n_args, n_dflts, return) \
\
typedef non_void_return_type void_return_type; \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
};
# define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \
struct fstubs_name \
: public ::boost::python::detail::overloads_common<fstubs_name> \
{ \
BOOST_PYTHON_GEN_MEM_FUNCTION( \
fname, non_void_return_type, n_args, n_dflts, return) \
\
typedef non_void_return_type void_return_type; \
BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \
};
# endif // !defined(BOOST_NO_VOID_RETURNS)
///////////////////////////////////////////////////////////////////////////////
//
// MAIN MACROS
//
// Given generator_name, fname, min_args and max_args, These macros
// generate function stubs that forward to a function or member function
// named fname. max_args is the arity of the function or member function
// fname. fname can have default arguments. min_args is the minimum
// arity that fname can accept.
//
// There are two versions:
//
// 1. BOOST_PYTHON_FUNCTION_OVERLOADS for free functions
// 2. BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for member functions.
//
// For instance, given a function:
//
// int
// foo(int a, char b = 1, unsigned c = 2, double d = 3)
// {
// return a + b + c + int(d);
// }
//
// The macro invocation:
//
// BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4)
//
// Generates this code:
//
// struct foo_stubsNonVoid
// {
// static const int n_funcs = 4;
// static const int max_args = n_funcs;
//
// template <typename SigT>
// struct gen
// {
// typedef typename ::boost::mpl::begin<SigT>::type rt_iter;
// typedef typename rt_iter::type RT;
// typedef typename rt_iter::next iter0;
// typedef typename iter0::type T0;
// typedef typename iter0::next iter1;
// typedef typename iter1::type T1;
// typedef typename iter1::next iter2;
// typedef typename iter2::type T2;
// typedef typename iter2::next iter3;
// typedef typename iter3::type T3;
// typedef typename iter3::next iter4;
//
// static RT func_0(T0 arg0)
// { return foo(arg0); }
//
// static RT func_1(T0 arg0, T1 arg1)
// { return foo(arg0, arg1); }
//
// static RT func_2(T0 arg0, T1 arg1, T2 arg2)
// { return foo(arg0, arg1, arg2); }
//
// static RT func_3(T0 arg0, T1 arg1, T2 arg2, T3 arg3)
// { return foo(arg0, arg1, arg2, arg3); }
// };
// };
//
// struct foo_overloads
// : public boost::python::detail::overloads_common<foo_overloads>
// {
// typedef foo_overloadsNonVoid non_void_return_type;
// typedef foo_overloadsNonVoid void_return_type;
//
// foo_overloads(char const* doc = 0)
// : boost::python::detail::overloads_common<foo_overloads>(doc) {}
// };
//
// The typedefs non_void_return_type and void_return_type are
// used to handle compilers that do not support void returns. The
// example above typedefs non_void_return_type and
// void_return_type to foo_overloadsNonVoid. On compilers that do
// not support void returns, there are two versions:
// foo_overloadsNonVoid and foo_overloadsVoid. The "Void"
// version is almost identical to the "NonVoid" version except
// for the return type (void) and the lack of the return keyword.
//
// See the overloads_common above for a description of the
// foo_overloads' base class.
//
///////////////////////////////////////////////////////////////////////////////
#define BOOST_PYTHON_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \
BOOST_PYTHON_GEN_FUNCTION_STUB( \
fname, \
generator_name, \
max_args, \
BOOST_PP_SUB_D(1, max_args, min_args))
#define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args) \
BOOST_PYTHON_GEN_MEM_FUNCTION_STUB( \
fname, \
generator_name, \
max_args, \
BOOST_PP_SUB_D(1, max_args, min_args))
// deprecated macro names (to be removed)
#define BOOST_PYTHON_FUNCTION_GENERATOR BOOST_PYTHON_FUNCTION_OVERLOADS
#define BOOST_PYTHON_MEM_FUN_GENERATOR BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
///////////////////////////////////////////////////////////////////////////////
#endif // DEFAULTS_GEN_JDG20020807_HPP

View File

@@ -0,0 +1,28 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef DEPENDENT_DWA200286_HPP
# define DEPENDENT_DWA200286_HPP
namespace boost { namespace python { namespace detail {
// A way to turn a concrete type T into a type dependent on U. This
// keeps conforming compilers (those implementing proper 2-phase
// name lookup for templates) from complaining about incomplete
// types in situations where it would otherwise be inconvenient or
// impossible to re-order code so that all types are defined in time.
// One such use is when we must return an incomplete T from a member
// function template (which must be defined in the class body to
// keep MSVC happy).
template <class T, class U>
struct dependent
{
typedef T type;
};
}}} // namespace boost::python::detail
#endif // DEPENDENT_DWA200286_HPP

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